build: clean LLVM fork build from pinned tag and patches
This commit is contained in:
1 parent
4a2a9b2135
commit
795fcdc14a
4 files changed
+167
-1
No files matched your search
@@ -0,0 +1,117 @@
|
||||
# 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)
|
||||
|
||||
## 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.
|
||||
@@ -1,3 +1,18 @@
|
||||
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
|
||||
index 3aba4d261..8b863dc92 100644
|
||||
--- a/clang/include/clang/Basic/TargetInfo.h
|
||||
+++ b/clang/include/clang/Basic/TargetInfo.h
|
||||
@@ -524,6 +524,10 @@ public:
|
||||
unsigned getCharWidth() const { return 8; } // FIXME
|
||||
unsigned getCharAlign() const { return 8; } // FIXME
|
||||
|
||||
+ /// Number of bits in the smallest addressable unit. Targets with
|
||||
+ /// bit-addressed pointers return 1; byte-addressed targets return 8.
|
||||
+ virtual unsigned getAddressUnitBits() const { return 8; }
|
||||
+
|
||||
/// getShortWidth/Align - Return the size of 'signed short' and
|
||||
/// 'unsigned short' for this target, in bits.
|
||||
unsigned getShortWidth() const { return ShortWidth; }
|
||||
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
|
||||
index 6f7b7e7d6..f59cebdf6 100644
|
||||
--- a/clang/lib/CodeGen/CGExprScalar.cpp
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
# Build the pinned LLVM 23.1.5 fork from a clean clone and the committed
|
||||
# patch series. Intended for CI and for verifying that patches/llvm is the
|
||||
# complete fork delta.
|
||||
set -eu
|
||||
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||
cd "$ROOT"
|
||||
mkdir -p build
|
||||
SRC=${LLVM_SRC:-build/llvm-clean}
|
||||
BUILD=${LLVM_BUILD:-build/llvm-clean-build}
|
||||
TAG=llvmorg-23.1.5
|
||||
|
||||
if [ ! -d "$SRC/.git" ]; then
|
||||
git clone --depth 1 --branch "$TAG" \
|
||||
https://github.com/llvm/llvm-project.git "$SRC"
|
||||
fi
|
||||
git -C "$SRC" checkout --detach "$TAG"
|
||||
git -C "$SRC" reset --hard
|
||||
git -C "$SRC" clean -fdx
|
||||
|
||||
PATCHROOT=$(pwd)/patches/llvm
|
||||
for p in "$PATCHROOT"/*.patch; do
|
||||
[ -e "$p" ] || continue
|
||||
git -C "$SRC" apply "$p"
|
||||
done
|
||||
|
||||
cmake -S "$SRC/llvm" -B "$BUILD" -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON \
|
||||
-DLLVM_ENABLE_PROJECTS=clang \
|
||||
-DLLVM_TARGETS_TO_BUILD="X86;TMS34010" \
|
||||
-DLLVM_INCLUDE_TESTS=ON -DLLVM_INCLUDE_EXAMPLES=OFF \
|
||||
-DLLVM_INCLUDE_BENCHMARKS=OFF
|
||||
ninja -C "$BUILD" clang opt llvm-config FileCheck count not
|
||||
@@ -19,7 +19,8 @@ git -C "$SRC" diff "$TAG" -- \
|
||||
clang/lib/Basic/Targets clang/lib/Basic/Targets.cpp \
|
||||
clang/lib/Basic/CMakeLists.txt clang/test/CodeGen/TMS34010 \
|
||||
> "$OUT/0003-clang-target.patch"
|
||||
git -C "$SRC" diff "$TAG" -- clang/lib/CodeGen/CGExprScalar.cpp \
|
||||
git -C "$SRC" diff "$TAG" -- \
|
||||
clang/include/clang/Basic/TargetInfo.h clang/lib/CodeGen/CGExprScalar.cpp \
|
||||
> "$OUT/0004-clang-ptrdiff.patch"
|
||||
|
||||
find "$OUT" -type f -empty -delete
|
||||
Reference in new issue
Block a user