docs: correct the GEP scaling warning and M1 data limits

Raw clang IR has byte GEP offsets that llc treats as bits, so addresses
are 8x too small; always run tms-clang/tms-bitaddr --scale first.
Document that M1 supports only zero-initialized globals and rejects
.data/string literals loudly, and defer the spec's .data initializer
probe to M2.
This commit is contained in:
arti committed 2026-11-11 10:15:32 +00:00
1 parent 937a8cc800
commit eacaab68f6
2 files changed
+32 -17

No files matched your search

+20 -9
View File
@@ -40,9 +40,12 @@ M1 fills in the M0 target skeleton and stops at assembly:
bit offset (`ADDI 24`, not `ADDI 192`).
- Hard errors, not silent fallbacks, for calls (`M1 has no calls; M2 adds the
TI ABI`), stack frames (`M1 has no stack frame`), more than four register
arguments, and unsupported types.
- Nine `llvm-lit`/FileCheck tests under
`llvm/test/CodeGen/TMS34010/m1-*.ll` in the compiler fork.
arguments, unsupported signatures (varargs, `i64`/float/aggregate
parameters, `sret`/`byval`/`inreg`/`nest`/`returned`), unsupported return
types, and initialized globals or string literals.
- Seventeen `llvm-lit`/FileCheck tests under
`llvm/test/CodeGen/TMS34010/m1-*.ll` in the compiler fork, including
negative tests that pin the loud refusals.
- An end-to-end path: `scripts/tms-clang` IR → `llc -O0 -filetype=asm` →
**1987 GSPA/GSPLNK 2.00 under DOSBox** → COFF → the VT1200 loader in MAME.
The run checks `add(20, 22) == 42`, `load(&word) == 0x12345678`,
@@ -171,7 +174,7 @@ TMS_BITADDR=$PWD/tools/tms-bitaddr/tms-bitaddr \
These are the documented commands; all three must pass:
```sh
# 1. LLVM codegen tests: 9 passed
# 1. LLVM codegen tests: 17 passed
build/llvm-clean-build/bin/llvm-lit -v \
build/llvm-clean-build/test/CodeGen/TMS34010 --filter='m1-'
@@ -205,14 +208,22 @@ build/llvm-clean-build/bin/llc -march=tms34010 -O0 -filetype=asm \
/tmp/add.ll -o /tmp/add.s
```
Use `-O0` on the IR that `tms-clang` already optimized and scaled; feeding
raw clang IR to `llc` double-scales GEP offsets. The lit tests use
`llc -march=tms34010 -O2 -filetype=asm` on hand-written IR to exercise the
selector pipeline directly. Output is assembly only: `llc` cannot emit an
object file or a usable COFF for this target.
Always produce the IR with `scripts/tms-clang` (or run `tms-bitaddr --scale`)
before `llc`: raw clang IR carries byte GEP offsets, but `llc` treats every
surviving GEP offset as a *bit* offset, so addresses would be 8× too small.
Run `llc -O0` on the normalized IR that `tms-clang` already optimized and
scaled. `tms-bitaddr --normalize` consumes that scaled IR and now rejects a
typed (non-`i8`) or vector GEP instead of emitting its byte offset as bits.
The lit tests use `llc -march=tms34010 -O2 -filetype=asm` on hand-written IR
to exercise the selector pipeline directly. Output is assembly only: `llc`
cannot emit an object file or a usable COFF for this target.
## Not yet supported (M2 and later)
- **Data:** only zero-initialized mutable globals (`.bss`) are supported.
Initialized globals, string literals and constant/private data (`.data`,
`.rodata`) make `llc` fail loudly; the `.data` initializer probe moves to
M2.
- **Object emission:** no `MCCodeEmitter`, object writer, `llc -filetype=obj`,
`clang -c`, or native COFF. GSPA assembles and GSPLNK links; the existing
COFF loader loads.
@@ -345,12 +345,15 @@ non-constant pointer expression by 8×.
`harness/sdk-scratch/dis2as34.py`). Emit section sizes and labels in bits.
- Linker command files are CRLF; `SECTIONS` origins are bit addresses.
- **Constant GEPs** become `symbol + bit_addend` (for example
`inttoptr(add(ptrtoint(@.str), 16))`). Before M1 relies on it, verify that
GSPA/gsplnk can carry and relocate a bit addend in both a `MOVI` immediate
and a `.data` initializer. Fallbacks if they cannot: leave `symbol+addend`
entirely to link time, materialize the addend at runtime (`MOVI symbol;
ADDI addend`), or pre-resolve in the linker script. Test a string literal
with an offset, `&arr[1]`, and a global pointer initializer.
`inttoptr(add(ptrtoint(@.str), 16))`). M1 verifies the `MOVI` immediate
form with `&arr[1]`. M1 does not emit `.data`, `.rodata` or string literals
at all: any non-null initializer makes `llc` fail loudly. Verifying a
`symbol+bit_addend` relocation in a `.data` initializer, a string literal
with an offset, and a global pointer initializer is **deferred to M2**
along with `.data` support. Fallbacks if GSPA/gsplnk cannot carry the
addend then: leave `symbol+addend` entirely to link time, materialize the
addend at runtime (`MOVI symbol; ADDI addend`), or pre-resolve in the
linker script.
- Later: native `as34`/`ld34` plus a COFF converter/loader extension, or an
LLVM MC COFF writer. `ld34` output is not COFF, so this is a separate step.
@@ -386,8 +389,9 @@ non-constant pointer expression by 8×.
verifier test; M1 adds the same program through `llc`, checking that late GEPs
carry bit offsets and are not scaled twice (§7.3.1). The spike only reached
`opt`; this is a new gate.
- **Constant-GEP relocation test**: `symbol + bit_addend` in `MOVI` and in
`.data`, plus `&arr[1]` and a global pointer initializer.
- **Constant-GEP relocation test**: M1 covers `symbol + bit_addend` in a
`MOVI` with `&arr[1]`. The `.data` initializer, string-literal and global
pointer initializer parts are deferred to M2 with `.data` support.
- MAME end-to-end: compile a C file, assemble/link, load via
`dwt/loader/loader.lua`, check markers and frame. This is the CI gate.
- Real unit: `dwt/loader/hostload.py`, rdebug. Periodic/optional confirmation,