Architecture#
This page is the map of EmbCC for people about to change it: the constraints the whole source tree obeys, the path of one source file from the command line to an object file and an executable, the directory, entry point and output of each stage, how the target is chosen, the build, and the tools around the compiler. Each stage has a page of its own, linked from here.
Constraints on the whole tree#
One process#
embcc runs every stage in one process: the preprocessor, the front
end, the optimizer, the code generator, the object writer and, when it
produces an executable, the linker. It never spawns a program. There is
no cc1, as or ld behind the driver; the assembler and the linker
are libraries (src/as, src/arch/x86_64/as.c, src/link) that the
driver calls. The reason is the system EmbCC is built to run on:
EmbLinkOS has no fork or exec, so a driver that started other
programs could not be hosted there.
The platform layer is the only view of the host#
Every interaction with the host goes through src/platform/platform.h:
reading and writing a file (plat_read_file, plat_write_file),
asking whether a file exists, reading an environment variable
(plat_getenv), asking whether standard error is a terminal, finding
the running binary (plat_self_path), and reading source text through a
replaceable provider (src_read, src_set_provider) so that a language
server can supply unsaved editor buffers. Running a program is optional
(plat_can_run, plat_run_start, plat_run_wait): process_spawn.c on
macOS and Linux, process_none.c on EmbLinkOS, which has no fork/exec,
and nothing may depend on it -- only the driver's several sources in one
command use it.
What every host shares is src/platform/platform_common.c, in ISO C.
The console and the binary's own path are platform_posix.c (macOS,
Linux, EmbLinkOS) or platform_iso.c (any host with a C library, chosen
with make PLATFORM=iso); a new host is another file beside them. See
Porting EmbCC to a new host.
Nothing reads the host's architecture: an embcc running on macOS and
one running on EmbLinkOS must produce the same object from the same
input and target.
Machine knowledge lives in src/arch/#
Target-dependent behaviour is a question asked by name of
src/arch/target.h (target_ptr_size(), target_char_unsigned(),
target_va_list_is_pointer(), ...); the data model comes from
g_model[] in target.c, one row per architecture, read from the target
database in src/targets/
(D-012). New target-dependent behaviour is a new
function there, not a test of target_get() where it is needed. Such
tests do remain outside src/arch/, in src/parse/parse.c,
src/sema/sema.c, src/ir/irgen.c, src/opt/opt.c,
src/debug/dwarf.c, src/as/gas.c, the C++ front end, and the
driver's choice of backend and object writer.
EmbCC compiles itself#
The compiler's own source must be accepted by EmbCC. This is a gate,
not a goal: tests/golden/x86_64/self-host.sh reads SRCS from the
Makefile, compiles every file with ./embcc, compiles each a second
time to check that the objects are byte-identical, and links the result
with embld into an EmbLinkOS executable with no unresolved symbols (it
is skipped when the EmbLinkOS runtime and newlib are not installed).
tests/golden/host-agnostic.sh builds EmbCC with two different host
compilers and requires the objects the two produce from a test corpus to
be byte-identical. Together they
support the self-hosting fixed point: a stage-1 EmbCC built by EmbCC
must build a byte-identical stage 2.
In practice this means:
- Plain C99. The Makefile builds with
-std=c99 -Wall -Wextra -Werror. - No construct or builtin EmbCC does not implement. EmbCC does not
implement the math builtins (
__builtin_floor,__builtin_ldexpand the rest of that family); a call to one insrc/breaks the self-host test although the host compiler accepts it. - No system headers for object formats:
src/elf/elf.h,src/macho/macho.handsrc/coff/coff.hdefine what the writers need. Operating-system headers (<unistd.h>,<mach-o/dyld.h>) appear only insrc/platform/platform_posix.c; the rest ofsrc/includes nothing beyond the ISO C library. - Deterministic output: no order-of-evaluation dependence between two IR-emitting calls passed as arguments to one call, no timestamps, no current directory in the output.
The full rules are in Contributing.
The compilation pipeline#
For embcc -c FILE.c -o FILE.o, main in src/driver/main.c parses
the options, selects the target, and calls compile, which installs the
error boundary and runs compile_unit. compile_unit runs the stages
in order:
directory entry point what it hands on
--------------- --------------------- ----------------------------------
src/platform src_read the file's bytes
|
src/cpp cpp_process preprocessed text, with line
| markers (# N "FILE")
src/cxx cxx_translate C text (C++ input only)
|
src/lex lex_next tokens, on demand to the parser
src/parse parse_unit struct unit: the AST
|
src/sema sema_check the same tree, every expression
| typed, every conversion explicit
src/ir irgen struct ir_unit: EmbIR
|
src/opt opt_run the same ir_unit, optimized
| (-O1 and above)
src/arch/<arch> codegen_unit* struct code (the .text bytes) and
regalloc.c ra_allocate relocation sites (enum reloc_kind)
|
src/debug dwarf_emit, eh_emit debug and unwind sections, with
| their relocations
src/elf elfw_* a relocatable object:
src/macho machow_* ELF, Mach-O or COFF
src/coff coffw_*
|
src/link embld_link an executable (ET_EXEC ELF), when
-c is absent; EMBX from embld
| Stage | Entry point | Directory | Described in |
|---|---|---|---|
| Driver | main, compile, compile_unit |
src/driver |
Invoking EmbCC |
| Source input | src_read |
src/platform |
The front end |
| Preprocessor | cpp_process |
src/cpp |
The front end |
| C++ front end | cxx_translate |
src/cxx |
The front end |
| Lexer | lex_init, lex_next |
src/lex |
The front end |
| Parser | parse_unit |
src/parse |
The front end |
| Semantic analysis | sema_check |
src/sema |
The front end |
| IR generation | irgen |
src/ir, src/arch/<arch>/irgen.c |
EmbIR |
| Optimizer | opt_run |
src/opt |
The optimizer |
| Register allocation | ra_allocate, ra_allocate_fp |
src/arch/regalloc.c |
Register allocation |
| Code generation | codegen_unit, codegen_unit_arm64, codegen_unit_thumb, codegen_unit_riscv, codegen_unit_mips, codegen_unit_avr |
src/arch/<arch> |
Backends |
| Debug and unwind tables | dwarf_emit, eh_emit |
src/debug |
Object files |
| Object writers | elfw_write, machow_write, coffw_write |
src/elf, src/macho, src/coff |
Object files |
| Linker | embld_link |
src/link, src/embx |
EmbLD |
Notes on the order:
- The C++ front end is a translator. It parses and analyses C++, writes
C, and the C front end compiles that C exactly as it compiles a C file
(D-013). Everything after
cxx_translateis shared between the two languages. - The lexer is not a separate pass. The parser holds a
struct lexerand callslex_nextas it goes; the C++ front end lexes its input whole with the same lexer in C++ mode (lex_init_mode). - Each front-end stage that recovers from errors is followed by a check
of its error count (
cx_nerrors,parse_error_count(),sema_error_count()); if it is nonzero the driver printscompilation terminated: N errorsand no later stage runs. - Register allocation is not a separate stage in the driver. Each
backend calls the shared allocator for each function, and only when
the driver passes it
regalloc(at-O2,-O3,-Osand-Oz). - Between the optimizer and code generation the driver removes, at
-O1and above, thestaticfunctions that no root reaches. It then moves functions with asectionattribute to the end, grouped by section. - The backend is chosen by
target_get()incompile_unit: one call per architecture, with RV32 and RV64 sharingcodegen_unit_riscv(D-016). All six have the same signature and return the same structures, so nothing after this point knows which machine produced the bytes. - The driver, not the backends, lays out
.data,.bss,.rodataand the thread-local sections, turns relocation sites into the object format's relocations, and writes the file. For-Sit hands the same bytes and sites toasm_emit_unit(src/driver/asmout.c) instead of an object writer. Object files describes this step in full.
What each stage hands to the next#
| Data | Structure | Declared in | Built by | Read by |
|---|---|---|---|---|
| Source text | char * |
src/platform/platform.h |
src_read |
cpp_process |
| Preprocessed text | char *, with # N "FILE" line markers |
src/cpp/cpp.h |
cpp_process, cxx_translate |
the parser |
| Tokens | struct token inside struct lexer |
src/lex/lex.h |
lex_next |
the parser, the C++ front end |
| AST | struct unit: lists of struct func, struct global, struct econst and struct topasm (file-scope asm), with struct stmt and struct expr trees |
src/parse/ast.h |
parse_unit |
sema_check, irgen, the driver |
| C types | struct type, struct member |
src/sema/type.h |
the parser and sema_check (ty_* in src/sema/type.c) |
everything up to and including irgen |
| EmbIR | struct ir_unit holding struct ir_func arrays of struct ir_ins, the symbol table (struct ir_sym) and the string pool (struct ir_str) |
src/ir/ir.h |
irgen, or ir_parse from text |
opt_run, the backends, dwarf_emit, eh_emit, asm_emit_unit |
| Machine code | struct code: a growable byte buffer and the data ranges inside it |
src/arch/code.h |
each backend's encoder (src/arch/<arch>/emit.c) |
the driver, the object writers |
| Relocation sites | struct extcall, struct strsite, struct gsite, struct fsite, each with a patch_off and an enum reloc_kind |
src/arch/backend.h, src/arch/target.h |
the backends | the driver |
| Debug and unwind sections | struct dwarf_out, struct eh_out, each with its relocation list |
src/debug/dwarf.h, src/debug/eh.h |
dwarf_emit, eh_emit |
the driver |
| Object under construction | struct elfw, struct machow, struct coffw |
src/elf/write.h, src/macho/write.h, src/coff/write.h |
the driver | written to disk by elfw_write, machow_write, coffw_write |
Properties a stage can rely on:
- After
sema_check, every expression node carries a type and every implicit conversion C performs is an explicitEXPR_CASTnode. IR generation never infers a width or a signedness. - EmbIR is linear three-address code over virtual registers, typed by width and flags rather than by C types. The ABI decisions that need C types (how an argument is passed, how a structure is returned) are made during IR generation and recorded on the instruction (EmbIR).
- EmbIR is not yet independent of the AST.
ir_func.srcpoints at thestruct functhe function came from, where the backend records itscode_offandcode_len, and a call carries its callee'sstruct func *alongside the index intoir_unit.syms. The AST therefore lives until the object is written. - Relocations are machine-neutral until the driver writes them. A
backend records a
reloc_kind(for exampleRK_ADR_HI21andRK_ADD_LO12for an AArch64 address,RK_PCREL32for an x86-64 RIP-relative one), andtarget_reloc_type,target_macho_relocandtarget_coff_relocinsrc/arch/target.cmap the kind to the object format's numbering (Object files). - There is no machine IR between EmbIR and bytes. Each backend selects
instructions and encodes them directly from EmbIR;
embcc inspect mirexplains this instead of printing a dump.
Where the pipeline stops early#
Several options run the pipeline part of the way and print what the last stage built. They are the intended way to see the hand-off between two stages.
| Command | Stops after | Writes |
|---|---|---|
embcc -E FILE, embcc inspect pp FILE |
the preprocessor | preprocessed text |
embcc -c -M FILE, -c -MM |
the preprocessor | a make rule |
embcc --emit-c FILE.cc |
the C++ front end | the C it lowered to |
embcc inspect tokens FILE |
the lexer | the token stream |
embcc inspect ast, symbols, types FILE |
semantic analysis | the tree, the declarations, the structure layouts |
embcc --emit-interfaces FILE |
semantic analysis | interface hashes (src/driver/iface.c), read by embidx |
embcc -fsyntax-only FILE |
semantic analysis | diagnostics only |
embcc inspect ir, cfg, callgraph FILE |
the optimizer, at the -O level given |
EmbIR text, the control-flow graph, the call graph |
embcc why DECISION [SUBJECT] FILE |
the optimizer | the remarks a pass recorded (src/driver/remark.c) |
embcc -S FILE |
code generation | the emitted bytes as assembly text |
embcc inspect ir FILE.ir reads EmbIR's textual form with ir_parse
and prints it back, so a pass can be studied with no C source and no
backend; printing, parsing and printing again gives the same bytes.
Given an -O level, it runs opt_run on the parsed unit first. The
option reference is Invoking EmbCC.
Other inputs#
The driver dispatches on the input's suffix before the C pipeline runs:
| Input | Handled by | Notes |
|---|---|---|
FILE.c, or any file with -x c |
the pipeline above | |
FILE.cc, .cpp, .cxx, .C, .c++, .cp, .CPP, .ii, or -x c++ |
the pipeline, through cxx_translate |
|
FILE.s, FILE.S |
gas_assemble in src/as/gas.c |
GNU syntax for AArch64, ARMv7-M, RISC-V, MIPS32 and AVR, encoded by each target's own inline-asm assembler; .S is preprocessed first |
FILE.asm |
as_assemble in src/arch/x86_64/as.c |
NASM syntax, x86-64 only; the same code as embas |
FILE.ir |
ir_parse in src/ir/irparse.c |
with embcc inspect ir only |
The compiler's state is per process, so one process compiles one
source. Given several (embcc a.c b.c -o OUT), the driver runs itself
once per source with -c and a temporary object (multi_source), up to
-j N at a time, then links the objects in command-line order among the
other inputs and removes them. That needs a host that can run a program
(plat_can_run); on one that cannot (EmbLinkOS), a second source is
refused with the way round it: compile each with -c and link the
objects. Objects, archives and -l libraries go to the link as they
are.
Linking#
Without -c, compile_and_link compiles the input to a temporary
object beside the output (OUT.embcc-tmp.o) and calls embld_link in
the same process with, in order: crt1.o (hosted targets), the object,
the command line's objects, archives and -l libraries, libcxx.a for a
C++ input, libc.a, and librt.a (-nostdlib, -nodefaultlibs and
-nostartfiles leave them out). The files are found through
paths_target_file (src/driver/paths.c), relative to the embcc
binary. A hosted target refuses to link without its crt1.o and
libc.a; a C++ input refuses to link without libcxx.a. The link
options are those -Wl, and -Xlinker gave (apply_wl): EmbLD's own
-e, -Ttext, -Tdata, -Tstack, --rom-limit and --lma-offset
are applied, options that change nothing about the image are accepted,
and any other is refused (EmbLD).
The driver links x86-64 ELF programs and, for the firmware targets
(ARMv7-M, ARMv8-M, RV32, RV64, MIPS32, AVR), images whose memory map the build
gives: a linker script (-T, ARM and RISC-V) or -Wl,-Ttext/-Tdata.
A firmware link without one stops with embcc: error: linking a TRIPLE image needs its memory map. Every other target (AArch64 ELF, Mach-O,
COFF) stops with embcc: error: cannot link for TRIPLE, because embld
does not read those objects.
The standalone embld links more than the driver uses: it accepts
x86-64, ARMv7-M and ARMv8-M, RV32, RV64 and AVR objects, and refuses
AArch64 ones. EMBX, EmbLinkOS's native executable format, is written by
embld --embx from the same linked image (D-003);
src/embx holds the container definition that embld and embread
share. The compiler never writes EMBX directly. See EmbLD.
Errors and the fatal boundary#
A stage shares its process with its caller, which may be a server
that must keep running, so a stage that meets an error does not end the
process. compile installs a setjmp boundary with
fatal_set_boundary (src/driver/util.h) around compile_unit, and a
stage that cannot continue leaves through it:
diag_fatalanddiag_atrecord a diagnostic and unwind.fatal_unwindunwinds after a diagnostic is already recorded.internal_errorreports an impossible state as a compiler bug and unwinds.
With no boundary installed, the same calls flush the diagnostics and
call exit(1), so a tool that does not install one still behaves
correctly. Diagnostics are records rendered once, at the boundary or at
exit, as caret text or JSON (src/driver/diag.c).
compile also fails a unit that ran to the end but recorded an error,
which is how a warning promoted by -Werror or -Werror=NAME ends:
when diag_error_count() is nonzero it returns 1 and removes the output
file it was writing, so no object, assembly file or executable is left
for make to take as up to date. compile_and_link then stops before
linking.
The following still end the process directly:
xmalloc,xcallocandxreallocon out-of-memory, where building a diagnostic would itself allocate.- The refusal functions of the embedded backends (
t_refuseinsrc/arch/thumb/codegen.c,rv_refuseinsrc/arch/riscv/codegen.c,mips_refuseinsrc/arch/mips/codegen.c,a_refuseinsrc/arch/avr/codegen.c), which print thecannot lower ... yetmessage and callexit(1). - Consistency checks in the Thumb encoder (
src/arch/thumb/emit.c), which callabort()because the file is also linked into the encoding checkers, which have no driver.
How each front-end stage recovers is described in The front end.
Target selection#
One process compiles for one target, fixed before the front end runs.
A target is a triple of architecture (enum target_arch), operating
system (enum target_os) and object format (enum target_fmt), all
declared in src/arch/target.h (D-014). The
driver sets it in this order:
- The built-in default,
x86_64-elf: the initial values of the globals insrc/arch/target.c. target_apply_default, before any option is read. It usesEMBCC_DEFAULT_TARGETfrom the environment if set, otherwise the triple compiled in bymake DEFAULT_TARGET=TRIPLE(D-017). An unknown name stops the compiler and says which of the two it came from.- Every
--target=TRIPLEon the command line, in a scan made before the other options are parsed, so that--version,-dumpmachineand--dump-predefdescribe the requested target.target_from_triplelooks the name up ing_triples[], the explicit table of accepted spellings (the target database'sTRIPLErows); an unknown name is refused withembcc: error: unknown target 'NAME'and the list of known triples. Once the scan is done, the backend's "this operation calls a runtime helper" predicate is installed for the optimizer (target_set_calls_helper), from the target finally chosen, so a compiler with a configured default makes the same code as one given that target by--target=. Thumb, RISC-V and AArch64 have one; x86-64 and AVR have none. - After all options, the target's
options_donehook (Thumb'sthumb_options_done, insrc/arch/thumb/options.c) settles the FPU and float ABI from-mfpu=,-mfloat-abi=and an-eabihftriple.
Everything downstream reads the result through target.h: the data
model (g_model[], one row per architecture), the predefined-macro
table (src/arch/predef.c chooses among the generated tables in
src/arch/<arch>/predef.c and predef_cxx.c), the backend
compile_unit calls, the object writer (target_fmt_get()), and the
relocation numbering. Every backend is linked into every embcc; a
configured default changes only which one is used when no --target=
is given. The triples and what each implies are listed in
Backends and
Targets.
Source tree#
| Directory | Contents |
|---|---|
src/driver/ |
main.c: options, target selection, the pipeline, data layout and object emission. diag.c and util.c: diagnostics, allocation, the fatal boundary. explain.c: --explain. inspect.c: the inspect dumps. remark.c: optimization remarks for why. asmout.c: -S. iface.c: --emit-interfaces. paths.c: the installed headers and libraries, found relative to the binary. version.h: the version string. |
src/platform/ |
The host interface (platform.h) and its POSIX implementation. |
src/cpp/ |
The preprocessor. |
src/lex/ |
The lexer, used by the C parser, the C++ front end and inspect tokens. |
src/parse/ |
The C parser and the AST (ast.h). |
src/sema/ |
Semantic analysis (sema.c); the type system and layout (type.c); exact compile-time long double arithmetic (ldfloat.c); 128-bit integer arithmetic (w128.c); -Wuninitialized (uninit.c); -Wformat (format.c). |
src/cxx/ |
The C++ front end. translate.h is its one public header; cxx.h is internal. |
src/ir/ |
EmbIR (ir.h), its generation (irgen.c, irgen_int.h), and its textual form (irprint.c, irparse.c). |
src/opt/ |
The optimizer and the IR verifier, in opt.c. |
src/arch/ |
Target selection and the data model (target.c), the backend contract (backend.h), the code buffer (code.c), the choice of macro table (predef.c), the shared register allocator (regalloc.c), and one directory per architecture. See Backends. |
src/debug/ |
DWARF 4 debug information (dwarf.c) and .eh_frame and .gcc_except_table (eh.c). |
src/elf/, src/macho/, src/coff/ |
The object-file definitions and writers for each format. |
src/as/ |
The GNU-syntax assembler front end for .s and .S files. |
src/link/ |
EmbLD, the linker, as a library (link.h). |
src/embx/ |
The EMBX container definition and checksum, shared by embld and embread. |
include/ |
The freestanding headers installed with the compiler (stddef.h, stdint.h, stdarg.h, ...). |
lib/ |
The libraries EmbCC compiles for its targets: libc (one implementation with a backend per operating system under lib/libc/os/), libcxx (the C++ runtime) and rt (the compiler runtime). See Libraries. |
tests/ |
The test suite and the QEMU harnesses. See Testing. |
tools/ |
The toolchain programs other than embcc, the encoding checkers, and scripts. See Tools. |
build.ebm |
The EmbBuild manifest that builds EmbCC on EmbLinkOS. |
The build#
The Makefile builds EmbCC with any C99 compiler. The defaults are
CC = cc, CFLAGS = -std=c99 -Wall -Wextra -Werror -g, and objects in
build/ (BUILD=). Every object depends on every header, so a header
edit rebuilds everything.
| Target | Builds |
|---|---|
embcc |
the compiler: every file in SRCS, plus tools/embdbg/embdbg.c compiled with -DEMBDBG_NO_MAIN (build/embdbg_core.o), whose .embdbg writer the linker library calls |
all |
embcc, embread, embld, embas, embls, embidx |
embdbg |
the debugger (not part of all) |
$(BUILD)/embcc |
the compiler linked inside the object directory, leaving ./embcc alone |
check, test, test-arm64, test-libstdcxx |
the test suites; see Testing |
libc-*, libcxx-*, rt-embedded |
the libraries, compiled by ./embcc |
install, install-files, uninstall |
installation under PREFIX, staged under DESTDIR |
clean |
removes build/, embcc, embread, embld, embdbg, embas and embls |
Name a target. Plain make builds only the first rule in the Makefile,
build/embdbg_core.o, and leaves ./embcc as it was.
Each tool has its own link rule and its own list of sources (EMBLS_SRCS
for embls, explicit lists for embas and embld). These lists, SRCS
and build.ebm are kept by hand; adding a file to src/ means adding it
to each list that needs it
(Contributing).
make DEFAULT_TARGET=TRIPLE embcc compiles in a default target
(D-017). Building and installing are described for
users in Getting started and for
contributors in Contributing.
Tools#
The programs in tools/ are host programs built around the libraries in
src/. Unlike src/, they may use the host directly: embls, for
example, runs embcc for diagnostics and parses in a forked child.
Toolchain programs#
| Program | Source | What it links from src/ |
Reference |
|---|---|---|---|
embcc |
src/driver/main.c |
all of SRCS |
Invoking EmbCC |
embld |
tools/embld/embld.c, doctor.c |
src/link, src/embx, the RISC-V, MIPS and AVR encoders (for the RISC-V and MIPS entry stubs and AVR relocations), the x86-64 decoder, the embdbg core |
EmbLD, embld |
embas |
tools/embas/embas.c |
the NASM-syntax assembler (src/arch/x86_64/as.c) and the ELF writer |
embas |
embread |
tools/embread/embread.c |
src/embx |
embread |
embdbg |
tools/embdbg/embdbg.c, remote.c |
the x86-64 decoder (src/arch/x86_64/disasm.c) |
embdbg |
embls |
tools/embls/embls.c |
the preprocessor, parser, semantic analysis, IR generation, optimizer and backends (EMBLS_SRCS) |
embls |
embidx |
tools/embidx/embidx.c |
nothing; it runs embcc --emit-interfaces and indexes the text |
embidx |
Encoding checkers#
Each backend encodes its own instructions, so each encoder and each inline-asm assembler has a checker that compares its output with an external assembler or disassembler. The checkers are compiled by the golden tests that use them, not by the Makefile.
| Checker | Checks | Test |
|---|---|---|
tools/a64check/a64check.c, a64asmcheck.c |
the AArch64 encoder and inline-asm assembler | tests/golden/aarch64/arm64-encoding.sh, arm64-asm.sh |
tools/thumbcheck, tools/tasmcheck, tools/vfpcheck |
the Thumb encoder, the Thumb inline-asm assembler, the VFP instructions | thumb-encoding.sh, thumb-asm.sh, thumb-vfp.sh |
tools/t1check |
the ARMv6-M (Thumb-1) encoders, t1_* in src/arch/thumb/emit.c |
thumb-v6m-encoding.sh |
tools/riscvcheck, tools/rvasmcheck |
the RISC-V encoder and inline-asm assembler | riscv-encoding.sh, riscv-compressed.sh, riscv-asm.sh |
tools/mipscheck, tools/mipsasmcheck |
the MIPS32 encoder and inline-asm assembler | mips-encoding.sh, mips-asm.sh |
tools/avrcheck, tools/avrasmcheck |
the AVR encoder and inline-asm assembler | avr-encoding.sh, avr-asm.sh |
tools/pmovecheck |
ra_parallel_move, by executing every small case against a model register file |
parallel-move.sh |
Tests without a directory are in tests/golden/. See
Backends and
Testing.
Scripts#
| Script | Purpose |
|---|---|
gen-predef.sh |
Regenerates src/arch/<arch>/predef.c and predef_cxx.c from the target's reference compiler. The only way those files change. |
gen-embbuild-manifest.sh, gen-kernel-manifest.sh |
Generate build.ebm, and the EmbBuild manifest for the EmbLinkOS kernel. |
gen-selfhost-ref.sh |
Builds the reference objects for the self-hosting fixed point on EmbLinkOS and relinks stage 1. |
build-rt.sh |
Builds librt.a for one embedded target (used by make rt-embedded). |
build-ref-gxx.sh, build-libstdcxx.sh |
Build the reference g++ and its libstdc++, and libstdc++ compiled by EmbCC. |
bench-opt.sh |
Compares optimized code with gcc and clang on tests/bench/kernels.c. |
x86-identity.sh |
Requires x86-64 objects to be byte-identical to those of a baseline revision. |
gap-probe.sh |
Re-runs the feature audit against GCC and Clang. |
hostpaths.sh |
The one place the host locations of cross tools, newlib and an EmbLinkOS tree are set. |
embbuild-run.sh, os-stage.sh, os-build-embld.sh |
Run an EmbBuild manifest on the host, and stage programs and embld into an EmbLinkOS image. |
Related pages#
The front end, EmbIR, The optimizer, Register allocation, Backends, Object files, EmbLD, Testing, Contributing, Design decisions, Status.