Welcome to the foundational toolchain for the NeoCore CPU family (NeoCore-FX and NeoCore-16x32).
I built this project from scratch because my original philosophy was to own the entire stack: from the silicon up to the parser. This modular ecosystem lets me write assembly or C, assemble it into custom object files, and link it into flat memory binaries that run natively on my own architectures.
Ecosystem Expansion & C Compilers:
nc-cc: My fully custom, built-in C compiler. It successfully targets both the NeoCore-FX and the older NeoCore-16x32 architecture natively, from parsing to object generation. While it is a fully functional compiler and a massive achievement in its own right, its development feature-set is now frozen so I can focus purely on backend optimizations.- neocorefx-llvm: To scale software compatibility, I expanded the ecosystem with an experimental LLVM backend. By leaning on LLVM's industrial-grade frontend, compiling massive, real-world C projects for the NeoCore-FX architecture is incredibly efficient.
nc-asandnc-ld: The assembler and linker form the bedrock of this project. They remain actively maintained and are required to assemble and link the.soutput generated by bothnc-ccand the LLVM backend.
Right now the main executables are:
nc-as(Assembler)nc-ld(Linker)nc-cc(Original C pipeline)
assembler/assembler sourcelinker/linker sourcecompiler/C frontend, MIR, backend, and driverconfig/ISA descriptions, target plugins, and linker scriptsneocore-fx/NeoCoreFX docs and ABI notesprograms/sample programs grouped by architecturetests/test coverage for parser, backend, integration, and more
Build everything with:
makeThat gives you these executables in the repo root:
nc-asnc-ldnc-ccrun_tests
Assemble a file:
./nc-as -i programs/neocore-fx/pseudo_features.s -o /tmp/pseudo_features.o -m config/neocore-fx.mdescLink an object:
./nc-ld /tmp/pseudo_features.o -o /tmp/pseudo_features.bin -T config/neocore-fx.ldCompile C for NeoCoreFX using nc-cc:
./nc-cc hello.c --target neocore-fx -o /tmp/hello_fx.binDump MIR only:
./nc-cc hello.c --target neocore-fx --emit-ir /tmp/hello.mir -S -o /tmp/hello.snc-as takes .m or .s input and emits LF02 object files. It is actively maintained and handles all output generated by the LLVM backend.
It supports:
- named sections like
.text,.data,.bss, and custom.section - symbols through
.globaland.extern - relocations including NeoCoreFX branch and jump relocations
- a built-in preprocessor with
.set,.equ,.if,.elseif,.else,.endif,.include, and.macro
Basic form:
./nc-as -i <input_file> -o <output_file> [-m <machine_description.mdesc>] [-p] [-s]Flags:
-penables the dual-issue scheduler / packer pass-sprints scheduling stats and implies-p
Example preprocessor snippet:
.set BUF_SIZE, 64
.macro LOAD reg, value
mov \reg, #(\value + 1)
.endm
.if BUF_SIZE > 32
LOAD r1, 41
.endifnc-ld links one or more LF02 object files into a flat binary image. It is a core piece of both the nc-cc and LLVM pipelines.
Basic form:
./nc-ld <input_files...> -o <output_file> [-T <linker_script>] [--arch-id <id>]Example:
./nc-ld /tmp/test.o -o /tmp/test.bin -T config/neocore16x32.ldSupported linker script features right now:
MEMORY { region : ORIGIN = <addr>, LENGTH = <size> }SECTIONS { .name : ALIGN(<n>) { *(.name) } > region }NOLOADfor sections like.bss
Note: For compiling large, modern C codebases targeting the NeoCore-FX CPU, I recommend checking out my neocorefx-llvm backend.
My original custom C pipeline (nc-cc) successfully runs its entire native flow:
- lex + parse
- semantic checks
- MIR generation
- backend lowering
- assembly
- object generation
- linking
Examples:
./nc-cc hello.c --target neocore16x32 -o /tmp/hello16.bin
./nc-cc hello.c --target neocore-fx -o /tmp/hello_fx.binUseful flags:
-Semit assembly only-cemit object only--emit-ir <path>dump MIR text-T <linker_script>override the target default linker script
NeoCoreFX notes:
- default ABI details are in
neocore-fx/c-abi.md - global and call lowering currently follow a PIC-flavored approach
- default linker profile is
config/neocore-fx.ld - that profile targets a single
64 KBwritable BRAM image - a future split-memory layout lives in
config/neocore-fx-split-future.ld
I designed the ISA to load from .mdesc files at runtime, meaning this single toolchain binary can target completely different CPUs.
Main files:
config/neocore16x32.mdescconfig/neocore-fx.mdescconfig/targets/neocore16x32.targetconfig/targets/neocore-fx.target
If you want to add a custom architecture:
- make or copy a
.mdesc - set
architecture_nameandarchitecture_id - point the assembler or target plugin at it
There is a starter template at config/template_custom_cpu.mdesc.
Run the test suite with:
./run_testsThis codebase started as an ambitious attempt to build absolutely everything from scratch, and it successfully established the bedrock assembly and linking layers for the NeoCore ecosystem.
With nc-cc natively handling both foundational architectures and my external LLVM backend now expanding the ecosystem to support massive real-world projects, the toolchain is more powerful than ever. Moving forward, nc-as and nc-ld will continue to serve as the critical layers bridging compiler output to the silicon. Thanks for checking out my work!