kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 79fec5699a0062b63c3c49b97b4adafc61a1d5de
parent 7b5e7555d188cf472b3cc976fe9e822bfe44bc56
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 17 Jun 2026 12:11:44 -0700

doc/ARM32: record DSP/flag-macro/density/disasm follow-ons + parse-corpus triage

Mark the four landed follow-on items (full -mcpu/-march/-mfpu/-mfloat-abi parsing
+ __ARM_* macros [done]; DSP saturating asm/disasm [partial — packed-SIMD +
builtin lowering deferred]; 16-bit density [done] + shifted-register fold
[gated off]; cosmetic shifted-MOV disasm [done]). Document the O1 frameless-leaf
return-address fix and list the remaining 17 broad-parse-corpus reds as a triage
TODO (i128/ldbl now skip-sidecar'd, parse lane 921/17/58).

Diffstat:
Mdoc/plan/ARM32.md | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 84 insertions(+), 15 deletions(-)

diff --git a/doc/plan/ARM32.md b/doc/plan/ARM32.md @@ -11,10 +11,62 @@ emit `.ARM.attributes`, ARM32 `.thumb_func` symbols carry the ABI Thumb bit, and C inline asm templates now route real Thumb-2 mnemonics through `src/arch/arm32/asm.c`. -Verification note: `make test-cross TARGET=freestanding-arm32 DEPTH=full` -currently fails in the broad parse lane (89 parse-corpus failures, many outside -the arm32 core scope such as i128 / long-double cases). The core signals above -are green; the broad parse corpus still needs separate skip/portability triage. +### Follow-on landed — 2026-06-17 — DSP, flag/macro parsing, code density, disasm + +Four follow-on items landed (parallel worktree agents, serial cherry-pick behind +the qemu gate). See the "Follow-on variants / polish" checklist below for status: +- **Full `-mcpu`/`-march`/`-mfpu`/`-mfloat-abi` parsing + the `__ARM_*` macro + set** — done. New `ArchImpl` hooks `target_feature_apply_cpu` (the previously + unconsumed `opts->cpu` now maps cortex-m3→armv7-m, cortex-m4/m7→armv7e-m+`dsp`) + and `feature_predefines` (feature-keyed `__ARM_ARCH_7M__`/`7EM__`, + `__ARM_FEATURE_DSP`/`SIMD32`, and the `__ARM_FP`/`__SOFTFP__`/`__ARM_PCS_VFP` + float set). Validated against host clang (`test/smoke/arm32_macros.sh`, 8/0). +- **ARMv7E-M DSP saturating** — SSAT/USAT/QADD/QSUB/QDADD/QDSUB encoders + ISA + rows + asm/disasm (assembler-permissive, inline-asm usable). Packed-SIMD and + automatic saturating-builtin lowering deferred (no frontend builtin exists). +- **16-bit-encoding density** — narrow PUSH/POP, LDR/STR (T1 imm5 + T2 sp), ADD/ + SUB sp, ADDS/SUBS/MOVS/LSLS/LSRS/ASRS where operands fit (−5%…−25% .text on + samples). Shifted-register operand folding is implemented but **gated off** — + enabling it tripped a shared `src/opt/pass_combine.c` addr-synth rule that + drops the L7 shift rider for `base+(i<<k)` (k≥4); re-enable once that's fixed. +- **Cosmetic disasm** — shifted-MOV now renders `lsl.w/lsr.w/asr.w/ror.w/rrx` + (and MVN shift suffix) matching llvm-objdump. + +Verification note: `make test-cross TARGET=freestanding-arm32 DEPTH=full` toy lane +is **423/0/2**; the broad parse lane is **921 pass / 17 fail / 58 skip**. The 58 +skips are the i128 + binary128-long-double cases (unsupported by design, now +`.arm32.skip`-sidecar'd to match rv32). The remaining 17 fails are a genuine +follow-on triage list — see "Broad parse-corpus triage" below. The fix that took +the parse lane from 33 to 17 fails: the O1 frameless-leaf tier returned through a +bare `BX lr` while the backend uses `lr` as an emit scratch (global-address +staging, overflow/popcount/bitfield/byte-copy), so any such leaf clobbered its +return address (the 16-case O1 globals/statics/attributes `rc 134` cluster). The +slim tier now saves `lr` (`PUSH {lr}`/`POP {pc}`). + +### Broad parse-corpus triage — outstanding (NOT core; freestanding-arm32 parse lane) + +17 reds remain in `make test-cross TARGET=freestanding-arm32 DEPTH=full` (parse +lane). None are in the closed core checklist; each needs separate triage: +- **Emit/codegen gaps (5):** + - [ ] `asm_01_grammar` O0+O1 — `arm32 inline asm: optimizer asm input not in a + register` (inline-asm operand binding at the parse-corpus's harder cases). + - [ ] `builtin_31_readcyclecounter` O0+O1 — `arm32` does not support the + `readcyclecounter` intrinsic (needs a DWT/CYCCNT or unsupported gate). + - [ ] `gnu_labels_as_values_threaded` O1 — `opt native emit: no scratch + register` (computed-goto under -O1 register pressure). +- **Wrong runtime result (12):** + - [ ] `6_5_2_2_06_struct_param_mixed_fp_int` O0 (got 229) + O1 (got 5) — mixed + fp/int struct-param ABI lowering. + - [ ] `6_5_64_unsigned_size_division` O0+O1 (got 10) — unsigned size division. + - [ ] `6_8_29_switch_signed_negative` O1 (got 42, want 100) — signed-negative + switch at O1. + - [ ] `builtin_generic_overflow` O0+O1 (got 6, want 7) — `__builtin_*_overflow` + generic-selection edge. + - [ ] `far_slot_large_frame` O0+O1 (got 4, want 7) — large-frame far slot + addressing. + - [ ] `rv64_atomic_widths_orders` O0+O1 (got 9, want 42) — atomics widths/orders + (the case is rv64-named but runs in the arm32 lane). + - [ ] `variadic_02_many_ints` O1 (got 0) — many-int varargs at O1. ## Core checklist — remaining items (single source of truth) @@ -63,14 +115,28 @@ are now checked there too). **Follow-on variants / polish** (NOT required for "core"; the `variant` seam, §4/§5): - [ ] Hard-float (FPv4-SP, `arm-none-eabihf`): VFP codegen + softfp/hard axis. -- [ ] DSP / ARMv7E-M saturating + packed-SIMD behind the `dsp` feature. + (The macro/feature machinery — `vfp`/`fpv5` features, `__ARM_FP`/ + `__ARM_PCS_VFP`, the softfp/hard `resolve_float_abi` branch — is in; the + driver still rejects non-soft `-mfloat-abi` until VFP codegen lands.) +- [~] DSP / ARMv7E-M saturating behind the `dsp` feature — SSAT/USAT/QADD/QSUB/ + QDADD/QDSUB encoders + ISA rows + asm/disasm landed (2026-06-17), usable + from inline asm. **Remaining:** packed-SIMD (SADD16/SEL/… + GE flags) and + automatic saturating-builtin lowering (no frontend builtin / CG intrinsic + exists yet; the `KIT_CG_INTOP_SATURATE_*` flags are unwired). - [ ] ARMv6-M / Thumb-1 (no IT / MOVW-MOVT / hardware divide / 32-bit Thumb). -- [ ] Full `-mcpu`/`-march`/`-mfpu`/`-mfloat-abi` parsing + the complete - `__ARM_FEATURE_*` predefined-macro set. +- [x] Full `-mcpu`/`-march`/`-mfpu`/`-mfloat-abi` parsing + the `__ARM_*` + predefined-macro set (2026-06-17; `target_feature_apply_cpu` + + `feature_predefines` hooks, clang-cross-validated). - [ ] Multi-threaded TLS (variant-I tp-relative; replaces TLS-as-static). -- [ ] 16-bit-encoding density + shifted-register-operand peephole (toward tcc). -- [ ] (cosmetic) disassembler renders shifted-MOV (`mov.w rd,rs,lsl #N`) as plain - `mov` — encodings are correct; listings lose the shift. +- [~] 16-bit-encoding density (landed 2026-06-17, −5%…−25% .text) + + shifted-register-operand peephole (**implemented but gated off** — a shared + `src/opt/pass_combine.c` addr-synth rule drops the L7 shift rider on + `base+(i<<k)`, k≥4; re-enable `arm_can_fold_shift_into_alu` once fixed). + Narrow intra-function branches (16-bit B/Bcond) still deferred. Note: the + O1 frameless-leaf tier now costs +2 bytes/leaf (`PUSH {lr}`/`POP {pc}`) for + return-address correctness — see the O1-leaf fix above. +- [x] (cosmetic) disassembler renders shifted-MOV as `lsl.w/lsr.w/asr.w/ror.w/ + rrx` (+ MVN shift suffix), matching llvm-objdump (2026-06-17). --- @@ -451,16 +517,19 @@ names the design, not a workaround. ### 4. Profiles / ABIs — new variants via the clean `variant` seam, not forks - [ ] **Hard-float** (FPv4-SP, `arm-none-eabihf`): VFP codegen + the softfp/hard float-abi axis (`double` stays soft on FPv4-SP). -- [ ] **DSP / ARMv7E-M** saturating + packed-SIMD behind the `dsp` feature. +- [~] **DSP / ARMv7E-M** saturating behind the `dsp` feature — SSAT/USAT/QADD/ + QSUB/QDADD/QDSUB asm+disasm landed (2026-06-17); packed-SIMD + automatic + saturating-builtin lowering deferred. - [ ] **ARMv6-M / Thumb-1** (no IT / MOVW-MOVT / hardware divide / 32-bit Thumb). -- [ ] Full **`-mcpu`/`-march`/`-mfpu`/`-mfloat-abi`** parsing + the complete - `__ARM_FEATURE_*` predefined-macro set. +- [x] Full **`-mcpu`/`-march`/`-mfpu`/`-mfloat-abi`** parsing + the + `__ARM_*` predefined-macro set (2026-06-17). ### 5. Polish (correctness-neutral, do last) - [x] `.ARM.attributes` (Tag_ABI build attributes) for external-toolchain interop. -- [ ] 16-bit-encoding density + shifted-register operands (deferred peephole); - `-O0` code density toward tcc. +- [~] 16-bit-encoding density landed (2026-06-17); shifted-register-operand + peephole implemented but gated off (pass_combine shift-rider drop). - [x] The kit-compiled Cortex-M reset stub. +- [x] (cosmetic) disassembler shifted-MOV rendering (2026-06-17). ### Exit criterion Core closure is the top checklist: toy X 423/0/2, `test-smoke-arm32`, the