Files
tms-c-compiler/README.md
T

4.4 KiB
Raw Blame History

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).

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

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.