132 lines
5.1 KiB
Markdown
132 lines
5.1 KiB
Markdown
# 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`](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`](docs/superpowers/plans/2026-11-10-tms34010-m0-fork-and-bit-address-semantics.md)
|
||
- Spike: [`spike/REPORT-23.md`](spike/REPORT-23.md) (current, LLVM 23.1.5);
|
||
[`spike/REPORT.md`](spike/REPORT.md) (historical, 19.1.7)
|
||
|
||
## Repositories
|
||
|
||
- **Compiler fork:** <https://git.wut.ee/opencode.siil.arti.ee/llvm-tms34010>
|
||
(branch `tms34010`) — the full buildable LLVM 23.1.5 tree with the TMS34010
|
||
target and clang bit-address changes.
|
||
- **This project:** <https://git.wut.ee/opencode.siil.arti.ee/tms-c-compiler>
|
||
— plans/specs, VT1200 integration tooling, `tms-bitaddr`, `tms-clang`,
|
||
symbols and the spike.
|
||
|
||
The compiler fork is the canonical source for LLVM changes. `patches/llvm`
|
||
here is a lightweight mirror used by `scripts/build-llvm.sh`, so the project
|
||
can be built without cloning 3 GB of LLVM; keep it in sync with the fork's
|
||
`tms34010` branch.
|
||
|
||
## What M0 provides
|
||
|
||
- `clang --target=tms34010-unknown-none`: 32-bit bit-addressed pointers,
|
||
8-bit signed `char`, 16-bit `short`, 32-bit `int`/`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)p` stays an
|
||
integer subtraction.
|
||
- `tools/tms-bitaddr`: GEP `--scale` and late `--normalize` passes, including
|
||
constant-expression GEPs.
|
||
- `scripts/tms-clang`: the M0 pipeline
|
||
`clang -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
|
||
|
||
```text
|
||
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:
|
||
|
||
```sh
|
||
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:
|
||
|
||
```sh
|
||
./scripts/fetch-vt1200.sh # -> vendor/vt1200, pinned 17dfd24...
|
||
```
|
||
|
||
## Build the pinned fork
|
||
|
||
```sh
|
||
./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
|
||
|
||
```sh
|
||
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
|
||
|
||
```sh
|
||
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.
|