kit

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

commit 8ace7b4efb4478f3c7a24fd0a4bccf7ab89cc54a
parent dbed4e112a29d1493ee3b7a73a44ba7e33956cf3
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 17 Jun 2026 05:39:11 -0700

doc(ARM32): add a single-source-of-truth Core checklist

Consolidate the remaining work into one scannable checklist near the top: Core
outstanding (AEABI self-build / GNU numeric labels, full coro runtime fault,
kit-compiled reset stub, .ARM.attributes, inline-asm real-mnemonics via asm.c),
Core done, and Follow-on variants/polish. Reconcile the stale §1-§5 checkboxes
(§1 + §2 tail/memmove/varargs/hints now [x]; §3 rt-self-build marked PARTIAL) and
point them at the new checklist.

Diffstat:
Mdoc/plan/ARM32.md | 82++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 69 insertions(+), 13 deletions(-)

diff --git a/doc/plan/ARM32.md b/doc/plan/ARM32.md @@ -14,6 +14,56 @@ AEABI alias layer (GNU numeric local labels), the full coro runtime fault, the kit-compiled reset stub, and `.ARM.attributes` remaining. See the §3 status and "Remaining work" below. +## Core checklist — remaining items (single source of truth) + +What is left to call the arm32 **core** complete, plus the follow-on variants +that are explicitly out of "core" scope. This list is authoritative; the prose +"Remaining work" §1–§5 below is the original design rationale (its done items +are now checked there too). + +**Core — outstanding** (all are §3 toolchain / §2 inline asm): +- [ ] **AEABI alias layer self-build** — re-enable `RT_arm-eabi-thumb2_AEABI = + thumb2`. Blocked on **GNU numeric local labels** (`1:` / `1f` / `1b`) in + `kit as`, which the soft-float compare helpers (`DEFINE_AEABI_DCMP/FCMP`) + use. Everything else in `aeabi_thumb2.S` already assembles with kit. +- [ ] **Full coroutine runtime** — `coro_init`/`coro_resume`/`coro_yield` faults + on bare-metal arm32 (a `coro/coro.c`-level static-stack/TLS layout + interaction; the switch/trampoline asm itself is byte-correct and + setjmp/longjmp round-trips). The coro layer self-builds; this is the + runtime correctness gap. +- [ ] **kit-compiled Cortex-M reset stub** — replace the clang-assembled + `start.S` in `test/lib/exec_bare.sh` (rewrite off literal pools / post- + indexed `[rN],#4` to MOVW/MOVT + explicit add, or add those asm forms; + needs BKPT — present — and the semihosting exit sequence). +- [ ] **`.ARM.attributes`** — emit the minimal Tag_ABI build-attributes section + (Tag_CPU_arch=ARMv7-M, Tag_THUMB_ISA_use, Tag_ABI_VFP_args=base, …) in + `src/obj/elf/emit.c` for external-toolchain interop. +- [ ] **Inline asm real mnemonics via `asm.c`** — route `asm_block` (case 20 and + friends) through the descriptor-driven assembler instead of the minimal + template runner, so arbitrary Thumb-2 mnemonics work (operand binding for + r/i/m/=&r/inout/clobbers already lands; this is the template-run seam). + +**Core — done** (closed; details under "Residual reds" + §1/§2 below): +- [x] Unified wide/addressing memory layer; i64/wide stores to global/frame + (§1). [x] Tail/sibling calls, `@memmove`, varargs edge cases, wide hint + intrinsics (§2). [x] The five -O0/-O1 edge reds 112/123/124/140/154. + [x] Inline-asm operand binding (case 20 green). [x] coro **layer** self- + builds with kit-as (save/restore verified). [x] `kit as` hardening: cmp/mov + `#imm`, SP-relative add/str/ldr + high-reg T3, UDF, `;` separator, + `#imm`-in-macro, `__ELF__`/empty `__USER_LABEL_PREFIX__`, soft-float + `__ARM_FP` undefined. + +**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. +- [ ] 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. +- [ ] 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. + ## Status — 2026-06-16 — Phase 2b — memory/frame/ABI correctness landed The arm32 backend is a working -O0/-O1 Cortex-M C toolchain: it compiles, links @@ -144,6 +194,10 @@ checklist below. ## Remaining work — design these correctly; do NOT keep patching +> For the scannable list of what is left, see the **Core checklist** near the top +> — it is the single source of truth. The §1–§5 below are the original design +> rationale, with done items checked in place. + Phase 2 surfaced a clear lesson. Several separate correctness bugs — a branch placeholder addend, two scratch-register clobbers (`str lr,[lr]`; ip-resident-base clobber), and an incomplete wide-access split — all lived in the @@ -158,12 +212,12 @@ i64/wide-store-to-global bug in §1 is the latest). **The items below must be do as coherent, correct-by-construction designs, not as more spot patches.** Each names the design, not a workaround. -### 1. Correctness — the wide / addressing memory layer (highest priority) -- [ ] **i64/wide stores to global/static addresses, and an i64 struct field at a +### 1. Correctness — the wide / addressing memory layer (DONE — Phase 2b) +- [x] **i64/wide stores to global/static addresses, and an i64 struct field at a non-zero offset, are miscompiled** (i64 global *reads* work; *writes* do not). Located: the 8-byte split's high lane + the GLOBAL-base address/offset + scratch selection are not uniform across base kinds. -- [ ] **Design:** one memory-access lowering, correct by construction — +- [x] **Design:** one memory-access lowering, correct by construction — (a) a single address-resolver that maps any `NativeAddr` × byte offset × width to a legal `(base, in-range-offset)`, or materializes the full effective address once into a *reserved* scratch, choosing a scratch that @@ -174,24 +228,26 @@ names the design, not a workaround. place. This retires the ad-hoc `lr`/`ip` rescue paths added during Phase 2. ### 2. Functional features — real implementations, not stubs -- [ ] **Tail / sibling calls** (`arm_emit_call` panics on `CG_CALL_TAIL`) — +- [x] **Tail / sibling calls** (`arm_emit_call` panics on `CG_CALL_TAIL`) — AAPCS tail-call lowering (epilogue-before-jump, in-place arg shuffle, `BX`/`B.W` to the callee) covering musttail / sret / variadic forms. -- [ ] **`@memmove`** — overlap-safe, direction-aware copy (compare dst vs src), +- [x] **`@memmove`** — overlap-safe, direction-aware copy (compare dst vs src), sharing the granule engine with `copy_bytes`. -- [ ] **Varargs edge cases** — mixed int/fp/i64, stack-arg + result-on-stack: +- [x] **Varargs edge cases** — mixed int/fp/i64, stack-arg + result-on-stack: complete `va_arg` over the unified arg window, validated against the GP-save-area layout (no per-width special cases). -- [ ] **Wide (i64) hint intrinsics** — `@expect`/`assume_aligned` on 8-byte +- [x] **Wide (i64) hint intrinsics** — `@expect`/`assume_aligned` on 8-byte values currently move only the low lane; fold them through the wide path. -- [ ] **Full inline asm** — route `asm_block` through the real descriptor-driven - assembler instead of the minimal template runner. +- [ ] **Full inline asm** — operand binding (r/i/m/=&r/inout/clobbers) lands and + case 20 is green on the minimal template runner; routing real mnemonics + through the descriptor-driven assembler is the remaining piece (Core + checklist, top). ### 3. Toolchain / runtime completeness -- [ ] **kit-self-built rt with no exclusions** — grow the descriptor-driven - assembler to cover the M-profile system + hand-written-asm idioms, then - re-enable the AEABI alias layer + coroutine register-switch asm (`AEABI`/ - `CORO` in `mk/rt.mk` + the driver's `kRtSrcArm32`), which are clang-only now. +- [ ] **kit-self-built rt with no exclusions** — PARTIAL: the coroutine layer + (`CORO` in `mk/rt.mk`) now self-builds with kit-as; the AEABI alias layer + (`AEABI`) is still clang-only, blocked on GNU numeric local labels (Core + checklist, top). The full coroutine runtime also still faults at run time. - [ ] **Multi-threaded TLS** — replace single-thread TLS-as-static with a real variant-I tp-relative model (software thread pointer + reset-stub seed).