docs: finalize M3 limitations and M4 prerequisites

This commit is contained in:
arti committed 2026-11-11 20:30:37 +00:00
1 parent 2681be26c0
commit 24f877362b
1 file changed
+50 -11
+50 -11
View File
@@ -7,8 +7,8 @@ upstream LLVM.
TI ABI: integer/pointer arguments are pushed on the program stack, the result is
returned in `A8`, frames use `A13`/`A14`/`A15`, and functions end in `RETS 2`
(`RETS 0` without arguments). M3 adds conditional/unconditional branches,
loops, integer ALU/shift operations, and the first compiled C Xlib client: a
four-call window opened with `XOpenDisplay`, created with
ordinary `while`/`for` loops, integer ALU/shift operations, and the first
compiled C Xlib client: a four-call window opened with `XOpenDisplay`, created with
`XCreateSimpleWindow`, mapped with `XMapWindow` and synchronized with `XSync`.
It is still **assembly-only**: no object writer, no `clang -c`, and no native
COFF; GSPA/GSPLNK under DOSBox produce the COFF. XImage/XEvent, the real client,
@@ -47,8 +47,9 @@ assembly-only:
- Conditional and unconditional branches for `i32` and pointer values:
`CMP`/`CMPI` plus `JAEQ`/`JANE`, the signed `JALT`/`JALE`/`JAGT`/`JAGE`, the
unsigned `JALO`/`JALS`/`JAHI`/`JAHS`, and `JAUC` for an unconditional jump.
Loops, if/else and `?:` work; `?:` expands to a compare plus a two-block
diamond (`SELECTCC`), and `setcc` becomes that diamond over 1/0.
Ordinary `while`/`for` loops (subject to the M3 limitations below), if/else
and `?:` work; `?:` expands to a compare plus a two-block diamond
(`SELECTCC`), and `setcc` becomes that diamond over 1/0.
- Integer ALU and shift operations: `SUB`, `AND`, `OR`, `XOR`, `NEG`, `NOT`,
`SLL`, `SRL`, `SRA`, plus `ADDI`/`ANDI`/`SLLK`/`SRAK`/`SRLK` immediates.
- The first compiled C Xlib window: `XOpenDisplay`, `XCreateSimpleWindow`
@@ -61,13 +62,27 @@ assembly-only:
- Misaligned accesses: `MOVE`/`MOVB` and the FS0/FS1 field-size forms have no
alignment requirement on the TMS34010, so packed and bit-addressed struct
fields select directly instead of being split into byte-wide accesses.
- Eight `m3-*.ll` lit tests, for a total of 45 with the M2 suite; the M3
- Nine `m3-*.ll` lit tests, for a total of 46 with the M2 suite; the M3
end-to-end, dis34, layout and differential gates (below).
M3 remains an `i32`/pointer milestone. Narrow integer loads/stores and `setcc`
are supported, but narrow (`i8`/`i16`) parameters and returns are still
rejected. Branches on `i64`, floats, aggregates, varargs and indirect calls are
not supported. The backend still emits assembly only.
M3 remains an `i32`/pointer milestone. `setcc` is supported, but narrow
(`i8`/`i16`) parameters and returns are still rejected. Branches on `i64`,
floats, aggregates, varargs and indirect calls are not supported. The backend
still emits assembly only.
### M3 limitations
- **Narrow loads are sign-extending only.** `MOVB` handles signed `char` and
the FS0 `MOVE` handles signed `short`; `unsigned char`, `unsigned short` and
`_Bool` loads need a zero-extending pattern that M3 does not have. They stop
`llc` with a raw `Cannot select`, which `m3-reject-zext.ll` pins. M4 adds the
zero-extending loads; do not assume general narrow-load support in M3.
- **`-O2` loop exit-value rewriting is not lowered.** IndVarSimplify can turn
`sumto`'s loop into a closed-form `i33` multiply, which M3 cannot select. The
M3 harness therefore builds `branch.c` with `-replexitval=never`. Ordinary
`while`/`for` loops that keep a real back-edge and phi work. M4/M5 must add
multiply/`i64` lowering, a target-level pass policy, or a target diagnostic
instead of a raw abort.
## What M2 provides (branch `m2`)
@@ -129,7 +144,7 @@ These are the documented commands on branch `m3`; all must pass.
# 1. Build llc, opt, clang and the test tools
ninja -C build/llvm-clean-build llc opt clang llvm-config FileCheck count not
# 2. LLVM codegen tests: 45 passed (37 m2-* + 8 m3-*)
# 2. LLVM codegen tests: 46 passed (37 m2-* + 9 m3-*)
build/llvm-clean-build/bin/llvm-lit -v \
build/llvm-clean-build/test/CodeGen/TMS34010 --filter='(m2|m3)-'
@@ -313,7 +328,9 @@ M2 deliberately rejects or omits:
`musttail` is not implemented (M2 C does not emit it). Real tail calls remain
a later milestone.
- **Narrow ABI types:** `i8`/`i16` parameters, `i64`, and narrow returns remain
rejected; narrow loads/stores inside a function are supported.
rejected. Narrow accesses inside a function are sign-extending only: `MOVB`
for signed `char` and FS0 `MOVE` for signed `short`; zero-extending
`unsigned char`/`unsigned short`/`_Bool` loads are M4 work.
- **Object output:** no `MCCodeEmitter`, object writer, `llc -filetype=obj`,
`clang -c` or native COFF. GSPA assembles and GSPLNK links the asm.
- **Xlib and clients:** no X11 headers, Xlib calls or real VT1200 clients in
@@ -340,6 +357,28 @@ M3 deliberately stops at the first window and ordinary integer control flow:
The `JR`/branch-relaxation code-size pass is M5 as well.
- **Varargs, `musttail`, narrow ABI parameters/returns:** unchanged from M2.
## M4 prerequisites (carry-forwards)
The final M3 review left these concrete prerequisites for M4:
- **Add zero-extending narrow loads.** M3 rejects `unsigned char`,
`unsigned short` and `_Bool` loads (pinned by `m3-reject-zext.ll`); M4 must
add the `ZEXTLOAD i8`/`i16` patterns and replace the reject test.
- **Namespace every private label.** `scripts/tests/m3/run.sh` prefixes
`LBB<n>_<m>` per translation unit, but deterministic private string labels
are not renamed. Two TUs with literals therefore collide in GSPA's flat
symbol table. M4 must namespace all private labels or make compiler private
names module-unique.
- **Add unsigned/`<=` runtime coverage.** `JALE`, `JALO`, `JAHI` and `JALS`,
`JAHS`, `JANE`, `JAGE` are covered by lit tests only and do not appear in the
compiled M3 image. M4 should add an unsigned/`<=` runtime marker.
- **Replace fragile test plumbing.** The `always_inline` root helper and the
register-hardcoded nine-argument dis34 check are test-strength aids that will
not survive real M4 code; make them operand- and register-independent.
- **Tighten test strength.** `m3-cmpi`'s `CHECK-DAG` for 0/1 does not pin their
order, and `layout.sh` pairs the root probe with fixed constants; neither
weakens the current pass, but both should be tightened.
## Repository layout
```text