tms-c-compiler
A modern C toolchain for the DEC VT1200 / TI TMS34010, built as a small fork of upstream LLVM.
Status: M0. Clang understands the tms34010-unknown-none target, the TI
data model, and bit-addressed pointers. There is no machine-code backend
yet: M0 stops at LLVM IR. The backend, TI ABI, ROM calls, Xlib and real
clients are M1–M5 and are separate plans (see the design spec).
- Design:
docs/superpowers/specs/2026-11-10-tms34010-llvm-design.md - M0 plan:
docs/superpowers/plans/2026-11-10-tms34010-m0-fork-and-bit-address-semantics.md - Spike:
spike/REPORT-23.md(current, LLVM 23.1.5);spike/REPORT.md(historical, 19.1.7)
What M0 provides
clang --target=tms34010-unknown-none: 32-bit bit-addressed pointers, 8-bit signedchar, 16-bitshort, 32-bitint/long, packed structs,sizeof(struct { char; int; void*; }) == 9.- Pointer arithmetic scaled by 8; pointer difference divided by 8
(
char *→/8,int *→/32), while(int)(p+1) - (int)pstays an integer subtraction. tools/tms-bitaddr: GEP--scaleand late--normalizepasses, including constant-expression GEPs.scripts/tms-clang: the M0 pipelineclang -O0→tms-bitaddr --scale→opt -O2→tms-bitaddr --normalize.- Lit tests for the triple, data model and pointer difference; an integration test over a real Xlib client IR.
Repository layout
build/llvm-src/ local fork (ignored; created by build-llvm.sh or manually)
build/llvm-build/ Ninja build of the fork (ignored)
build/llvm-clean*/ clean CI clone/build (ignored)
patches/llvm/ the complete fork delta against llvmorg-23.1.5
tools/tms-bitaddr/ GEP scale/normalize tool
scripts/tms-clang M0 pipeline wrapper
scripts/tests/m0/ M0 integration tests
scripts/build-llvm.sh clean clone + patches + build
scripts/fetch-vt1200.sh fetch the VT1200 RE tree at its pinned commit
spike/ measurement corpus and reports
symbols/ per-ROM import tables (v2.2 subset)
vendor/ fetched assets and LLVM sources (ignored)
docs/ design and plans
Prerequisites
cmake, ninja-build, ccache, a C++17 host compiler (GCC 14 is used here),
Python 3, and about 20 GB of disk for the LLVM source and build. On Debian:
sudo apt-get install -y cmake ninja-build ccache
Fetch the VT1200 assets
The compiler contract is checked against the VT1200 tree (TI hello.s, the
Xlib call sequence, as34, dis34, SDKs, manuals). It is not vendored:
./scripts/fetch-vt1200.sh # -> vendor/vt1200, pinned 17dfd24...
Build the pinned fork
./scripts/build-llvm.sh
# binaries: build/llvm-clean-build/bin/{clang,opt,llvm-config,FileCheck,llvm-lit}
The script clones llvmorg-23.1.5, applies patches/llvm/*.patch, and builds
clang/opt with X86 (host) and TMS34010. A first build takes roughly
20–40 minutes; rebuilds are incremental.
For development, build/llvm-src is the working fork and build/llvm-build is
its build tree. scripts/export-patches.sh regenerates the committed patch
series with git diff (including new files via git add -N).
Build the M0 tool and run the tests
LLVM_CONFIG=$PWD/build/llvm-clean-build/bin/llvm-config \
tools/tms-bitaddr/build.sh
TMS_CLANG=$PWD/build/llvm-clean-build/bin/clang \
TMS_OPT=$PWD/build/llvm-clean-build/bin/opt \
TMS_BITADDR=$PWD/tools/tms-bitaddr/tms-bitaddr \
./scripts/tests/m0/run.sh
# -> M0 pipeline: PASS
build/llvm-clean-build/bin/llvm-lit -v \
build/llvm-clean-build/tools/clang/test --filter='TMS34010'
# -> 3 passed
Use
scripts/tms-clang -O2 -I spike -o /tmp/client.ll spike/xclient.c
The output is LLVM IR in which every address is a bit address. It is not
assembly or an object file; llc support is M1.
What is deliberately missing
- TMS34010 instruction selection, registers, frame lowering, asm/MC output.
- The TI ABI: A8 return, A13/A14/A15 dual stack,
RETS 2,FS1 = 32. - ROM import symbols beyond the subset in
symbols/. - Xlib headers/clients on the target,
memcpy/byval/varargs/float/bitfield lowering, native COFF.
These are M1–M5 in the design spec, written as separate plans because their tasks depend on what M0/M1 measure.