diff --git a/.run/P32/t3s3/bank.sh b/.run/P32/t3s3/bank.sh index b71f809026..6f87246e6f 100644 --- a/.run/P32/t3s3/bank.sh +++ b/.run/P32/t3s3/bank.sh @@ -27,6 +27,6 @@ $title $body- one build for the same-TU batch: make build BINARY=$bin -j8 rc 0; sha1 $got == config/check.$bin.sha (BYTE-IDENTICAL) - $tu: $left INCLUDE_ASM left -Claude-Session: 491895ad-3c84-4037-b04f-bf7e5ee16a0c +Claude-Session: ${CLAUDE_SESSION:-72d8b4b1-048d-4361-b177-a5261ede0e07} EOM git log --oneline -1 diff --git a/.run/P32/t3s3/bank_md_MAIN_007_120600.log b/.run/P32/t3s3/bank_md_MAIN_007_120600.log new file mode 100644 index 0000000000..dae13864d1 --- /dev/null +++ b/.run/P32/t3s3/bank_md_MAIN_007_120600.log @@ -0,0 +1,5 @@ + CC build/src/md_MAIN_007/md_MAIN_007.o + LD build/md_MAIN_007/md_MAIN_007.elf + OBJCOPY build/md_MAIN_007/md_MAIN_007 +[ OK ] build/md_MAIN_007/md_MAIN_007 + sha1 2ff702b605ab5cfc18474c464c4c07e5f8ffd48c == config/check.md_MAIN_007.sha (BYTE-IDENTICAL) diff --git a/.run/P32/t4c/func_800CF408/NOTES.md b/.run/P32/t4c/func_800CF408/NOTES.md new file mode 100644 index 0000000000..7060dcaf3b --- /dev/null +++ b/.run/P32/t4c/func_800CF408/NOTES.md @@ -0,0 +1,40 @@ +# md_MAIN_007:func_800CF408 (178 ins) — T4b HAND PASS, S84 (2026-09-06) — **BANKED byte-identical** (`commit:4001`) + +## What closed it (one probe of the right kind after 135 of the wrong kind) +The residual (3 rows, idx 10–12: `ori $s5,0x96` two slots below its `lui`) was correctly attributed by the T4b Fable agent to +sched1's T-139 memory-unit bubble (the unboosted tag load lingering behind the store stream, its blocked cycle handed to the +highest-LUID floater) coupled to the `$t2/$t3` `qty_compare` contest (§501-L). Every cure inside the draft's own spelling +oscillated between 3 / 13 / 18 — the draft was the wrong SHAPE, not the wrong dial. + +**The banked sibling `md_MAIN_009:func_800CD92C` (same four-prim SPRT+tpage family, §501-H) matched with a simpler shape:** +`v = (OT[idx * 0x1000] & m24) & m24; t = *(u32 *)p; t &= 0xFF000000; t |= v; *(u32 *)p = t;` and +`OT[oi] = (OT[oi] & 0xFF000000) | ((u32)p & m24);` on a TRUE `u32` ARRAY_REF of the OT symbol — no `ob` pointer variable, no +named `mhi`, no `arg1 = 0` kill, no `y1/y2` temps, the colour stores chained. Porting that spelling to this function's constants +(`0xE1000086/87/96/97`, `0x7980`, `0x80`, u=`0x20/0x40`, w/h `0xA0/0x100`, `x`/`x + 0xA0`, `y`/`y + 0x100`) = **MATCH 178/178 in the +real TU (`rtu_match --split md_MAIN_007 --source md_MAIN_007`)**, first try (`b0d_sibport_alias.c`). + +**The one obstacle was the TU's declaration:** `src/md_MAIN_007/md_MAIN_007.c:317` declares `extern u8 D_800AA60C[];`, so the +sibling's `u32` array form CC1-FAILs (`b0_sibport.c`: conflicting types) and every `u8`-based respelling (`*(u32 *)&D_800AA60C[oi]`, +a one-member struct view, the P_TAG bitfield on `&D_800AA60C[oi]` — `b0b`/`b0c`) keeps ALL eight OT accesses in the raw +`lui $at/addu $at/lw %lo()($at)` macro form: cse binds the base into `$t2` only for the `u32` ARRAY_REF (element size 4, the +`(plus (mult idx 4) sym)` address goes through `memory_address → force_reg (sym)`; the `u8` form's `(plus sym idx)` never does). +The fleet's standard spelling for a second typed view of one symbol is the asm-label alias (1,438 banked files: +`extern u16 hD_80076240 __asm__("D_80076240"); extern s16 sD_80076240 __asm__("D_80076240");`): +`extern u32 wD_800AA60C[] __asm__("D_800AA60C");` — a declaration, not an asm body (R62 untouched). + +## Measured this session (all in `.run/P32/t4c/func_800CF408/`) +| variant | change | result | +|---|---|---| +| b0_sibport | sibling port, `extern u32 D_800AA60C[]` | CC1 FAIL (TU declares `u8 D_800AA60C[]`) | +| b0b_sibport_otw | port on the `u8` array, one-member struct view for the OT word | far (raw `$at` form ×8) | +| b0c_sibport_ptag | port on the `u8` array, P_TAG bitfield write | far (same) | +| b1_pm1asm | draft + named prim-1 masked temp, 2-set via trailing `__asm__ volatile("" : "=r"(pm1))` (func_800CD674's lever 7) | worse: the volatile asm makes hard regs live → m24/colour swap `$t1↔$t0` | +| b2 | b1 + cure A + ob-after-index | same swap | +| b3_draft_alias | the Fable draft with only the OT accesses respelled to the alias array | 16 (frame 0x28: an extra slot — the named temps) | +| **b0d_sibport_alias** | **the sibling port with `wD_800AA60C[]` alias** | **MATCH 178/178** | + +## Two facts worth keeping +* The draft's `vars= 8` frame (the target's too) is a combine-minted GHOST (`tools/ghost_census.py`: pseudo 92, refs 2, + `ST_REGS or none; pointer` → SLOT) — the same producer proved for row (a); the sibling port reproduces it for free. +* The prologue-weave residual class (§501-H/L) is a SHAPE symptom: when a same-family sibling is banked, port its spelling + before dialing the draft (135-variant sweep + 3 agents + a hand pass measured nothing the port did not give at once). diff --git a/.run/P32/t4c/func_800CF408/b0_sibport.c b/.run/P32/t4c/func_800CF408/b0_sibport.c new file mode 100644 index 0000000000..a04cf4a343 --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b0_sibport.c @@ -0,0 +1,111 @@ +extern u8 *D_800A5E60; +extern u32 D_800AA60C[]; +extern s16 D_800B9A02; + +void func_800CF408(s32 x, s32 y) { + u8 *p; + u32 m24; + + p = D_800A5E60; + x -= 0xA0; + y -= 0x78; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0x00FFFFFF; + { + u32 v = (D_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + D_800AA60C[oi] = (D_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (D_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + D_800AA60C[oi] = (D_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (D_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + D_800AA60C[oi] = (D_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (D_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + D_800AA60C[oi] = (D_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + D_800A5E60 = p; +} diff --git a/.run/P32/t4c/func_800CF408/b0b_sibport_otw.c b/.run/P32/t4c/func_800CF408/b0b_sibport_otw.c new file mode 100644 index 0000000000..4852013dcc --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b0b_sibport_otw.c @@ -0,0 +1,115 @@ +extern u8 *D_800A5E60; +extern u8 D_800AA60C[]; +extern s16 D_800B9A02; + +void func_800CF408(s32 x, s32 y) { + typedef struct { u32 w; } OTW; + typedef struct { u32 addr:24; u32 len:8; } P_TAG; +#define OTE(oi) (((OTW *)&D_800AA60C[(oi)])->w) + u8 *p; + u32 m24; + + p = D_800A5E60; + x -= 0xA0; + y -= 0x78; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0x00FFFFFF; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + OTE(oi) = (OTE(oi) & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + OTE(oi) = (OTE(oi) & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + OTE(oi) = (OTE(oi) & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + OTE(oi) = (OTE(oi) & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + D_800A5E60 = p; +#undef OTE +} diff --git a/.run/P32/t4c/func_800CF408/b0c_sibport_ptag.c b/.run/P32/t4c/func_800CF408/b0c_sibport_ptag.c new file mode 100644 index 0000000000..357074b2f5 --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b0c_sibport_ptag.c @@ -0,0 +1,115 @@ +extern u8 *D_800A5E60; +extern u8 D_800AA60C[]; +extern s16 D_800B9A02; + +void func_800CF408(s32 x, s32 y) { + typedef struct { u32 w; } OTW; + typedef struct { u32 addr:24; u32 len:8; } P_TAG; +#define OTE(oi) (((OTW *)&D_800AA60C[(oi)])->w) + u8 *p; + u32 m24; + + p = D_800A5E60; + x -= 0xA0; + y -= 0x78; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0x00FFFFFF; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + ((P_TAG *)&D_800AA60C[oi])->addr = (u32)p; + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + ((P_TAG *)&D_800AA60C[oi])->addr = (u32)p; + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + ((P_TAG *)&D_800AA60C[oi])->addr = (u32)p; + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (OTE(((u16)D_800B9A02) << 14) & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = ((u16)D_800B9A02) << 14; + ((P_TAG *)&D_800AA60C[oi])->addr = (u32)p; + } + p += 0x18; + + D_800A5E60 = p; +#undef OTE +} diff --git a/.run/P32/t4c/func_800CF408/b0d_sibport_alias.c b/.run/P32/t4c/func_800CF408/b0d_sibport_alias.c new file mode 100644 index 0000000000..5c220a38ef --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b0d_sibport_alias.c @@ -0,0 +1,111 @@ +extern u8 *D_800A5E60; +extern u32 wD_800AA60C[] __asm__("D_800AA60C"); +extern s16 D_800B9A02; + +void func_800CF408(s32 x, s32 y) { + u8 *p; + u32 m24; + + p = D_800A5E60; + x -= 0xA0; + y -= 0x78; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0x00FFFFFF; + { + u32 v = (wD_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + wD_800AA60C[oi] = (wD_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (wD_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + wD_800AA60C[oi] = (wD_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (wD_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + wD_800AA60C[oi] = (wD_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = 0x80; + *(s16 *)(p + 0xC) = x + 0xA0; + *(s16 *)(p + 0xE) = y + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v = (wD_800AA60C[(u16)D_800B9A02 * 0x1000] & m24) & m24; + u32 t = *(u32 *)p; + t &= 0xFF000000; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (u16)D_800B9A02 * 0x1000; + wD_800AA60C[oi] = (wD_800AA60C[oi] & 0xFF000000) | ((u32)p & m24); + } + p += 0x18; + + D_800A5E60 = p; +} diff --git a/.run/P32/t4c/func_800CF408/b1_pm1asm.c b/.run/P32/t4c/func_800CF408/b1_pm1asm.c new file mode 100644 index 0000000000..be62847798 --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b1_pm1asm.c @@ -0,0 +1,130 @@ +extern u8 *D_800A5E60; +extern u8 D_800AA60C[]; +extern s16 D_800B9A02; + +void func_800CF408(s32 arg0, s32 arg1) { + typedef struct { u32 addr:24; u32 len:8; } P_TAG; + u8 *p; + u8 *ob; + u32 m24; + u32 mhi; + u32 pad[2]; + s32 y1, y2; + u32 pm1; + + p = D_800A5E60; + arg0 -= 0xA0; + y1 = arg1 - 0x78; + arg1 = 0; + mhi = 0xFF000000; + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0; + *(s16 *)(p + 0xE) = y1; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0xFFFFFF; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)D_800AA60C + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ob = D_800AA60C; + pm1 = (u32)p & m24; + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = pm1; + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0 + 0xA0; + *(s16 *)(p + 0xE) = y1; + y2 = y1 + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)ob + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = (u32)p; + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0; + *(s16 *)(p + 0xE) = y2; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)ob + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = (u32)p; + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0 + 0xA0; + *(s16 *)(p + 0xE) = y2; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)ob + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = (u32)p; + p += 0x18; + + D_800A5E60 = p; + __asm__ volatile("" : "=r"(pm1)); +} diff --git a/.run/P32/t4c/func_800CF408/b2_cureA_v2_pm1asm.c b/.run/P32/t4c/func_800CF408/b2_cureA_v2_pm1asm.c new file mode 100644 index 0000000000..38f7f7a72a --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b2_cureA_v2_pm1asm.c @@ -0,0 +1,133 @@ +extern u8 *D_800A5E60; +extern u8 D_800AA60C[]; +extern s16 D_800B9A02; + +void func_800CF408(s32 arg0, s32 arg1) { + typedef struct { u32 addr:24; u32 len:8; } P_TAG; + u8 *p; + u8 *ob; + u32 m24; + u32 mhi; + u32 pad[2]; + s32 y1, y2; + u32 pm1; + + p = D_800A5E60; + arg0 -= 0xA0; + y1 = arg1 - 0x78; + arg1 = 0; + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0; + *(s16 *)(p + 0xE) = y1; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0xFFFFFF; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + mhi = 0xFF000000; + v = (*(u32 *)((s32)D_800AA60C + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + { + s32 oi = (((u16)D_800B9A02) << 14); + ob = D_800AA60C; + pm1 = (u32)p & m24; + ((P_TAG *)((s32)ob + oi))->addr = pm1; + } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0 + 0xA0; + *(s16 *)(p + 0xE) = y1; + y2 = y1 + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)ob + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = (u32)p; + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0; + *(s16 *)(p + 0xE) = y2; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)ob + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = (u32)p; + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0 + 0xA0; + *(s16 *)(p + 0xE) = y2; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (*(u32 *)((s32)ob + oi) & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + ((P_TAG *)((s32)ob + (((u16)D_800B9A02) << 14)))->addr = (u32)p; + p += 0x18; + + D_800A5E60 = p; + __asm__ volatile("" : "=r"(pm1)); +} diff --git a/.run/P32/t4c/func_800CF408/b3_draft_alias.c b/.run/P32/t4c/func_800CF408/b3_draft_alias.c new file mode 100644 index 0000000000..f2e98b3d2b --- /dev/null +++ b/.run/P32/t4c/func_800CF408/b3_draft_alias.c @@ -0,0 +1,126 @@ +extern u8 *D_800A5E60; +extern u8 D_800AA60C[]; +extern u32 wD_800AA60C[] __asm__("D_800AA60C"); +extern s16 D_800B9A02; + +void func_800CF408(s32 arg0, s32 arg1) { + typedef struct { u32 addr:24; u32 len:8; } P_TAG; + u8 *p; + u32 m24; + u32 mhi; + u32 pad[2]; + s32 y1, y2; + + p = D_800A5E60; + arg0 -= 0xA0; + y1 = arg1 - 0x78; + arg1 = 0; + mhi = 0xFF000000; + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000086; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0; + *(s16 *)(p + 0xE) = y1; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + m24 = 0xFFFFFF; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (wD_800AA60C[oi >> 2] & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + { s32 oi = (u16)D_800B9A02 * 0x1000; wD_800AA60C[oi] = (wD_800AA60C[oi] & mhi) | ((u32)p & m24); } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000087; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0 + 0xA0; + *(s16 *)(p + 0xE) = y1; + y2 = y1 + 0x100; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (wD_800AA60C[oi >> 2] & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + { s32 oi = (u16)D_800B9A02 * 0x1000; wD_800AA60C[oi] = (wD_800AA60C[oi] & mhi) | ((u32)p & m24); } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000096; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0; + *(s16 *)(p + 0xE) = y2; + *(u8 *)(p + 0x10) = 0x20; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (wD_800AA60C[oi >> 2] & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + { s32 oi = (u16)D_800B9A02 * 0x1000; wD_800AA60C[oi] = (wD_800AA60C[oi] & mhi) | ((u32)p & m24); } + p += 0x18; + + *(u8 *)(p + 0x3) = 5; + *(u32 *)(p + 0x4) = 0xE1000097; + *(u8 *)(p + 0xB) = 0x64; + *(u16 *)(p + 0x12) = 0x7980; + *(u8 *)(p + 0xA) = 0x80; + *(u8 *)(p + 0x9) = 0x80; + *(u8 *)(p + 0x8) = 0x80; + *(s16 *)(p + 0xC) = arg0 + 0xA0; + *(s16 *)(p + 0xE) = y2; + *(u8 *)(p + 0x10) = 0x40; + *(u8 *)(p + 0x11) = 0; + *(s16 *)(p + 0x14) = 0xA0; + *(s16 *)(p + 0x16) = 0x100; + { + u32 v, t; + s32 oi; + oi = (((u16)D_800B9A02) << 14); + v = (wD_800AA60C[oi >> 2] & m24) & m24; + t = *(u32 *)p; + t &= mhi; + t |= v; + *(u32 *)p = t; + } + { s32 oi = (u16)D_800B9A02 * 0x1000; wD_800AA60C[oi] = (wD_800AA60C[oi] & mhi) | ((u32)p & m24); } + p += 0x18; + + D_800A5E60 = p; +} diff --git a/docs/accelerators.md b/docs/accelerators.md index d7add68fc3..0102e6fa78 100644 --- a/docs/accelerators.md +++ b/docs/accelerators.md @@ -802,3 +802,12 @@ the mult results' alternate class — without compiling a variant of the draft ( It also found a new ghost producer (`optimize_reg_copy_2`, §501-M) and measured why it cannot slot. Accelerator: a frame residual gets a producer table first (`tools/cc1_dumps.sh` + `tools/ghost_census.py`), a spelling sweep last — and a "PROVED" verdict is the table with every row refuted, not a sweep that came back empty (extends (9), (11), R40). + +**(13) When a same-family sibling is banked, port its SPELLING with the row's constants before touching a dial on the draft +(P32 T4b hand pass, `md_MAIN_007:func_800CF408`, S84).** The row had consumed three agent passes, a 135-variant sweep and a hand +pass on a draft that carried five dials (named mask, base pointer, two temps, a dead parameter kill); its residual class had +been named correctly (§501-H/L) and every cure oscillated. The banked sibling `func_800CD92C` (§501-H, same four-prim family) +had matched with the plain libgpu shape; porting that body with this function's constants matched first try — the only work +was the TU's `u8` declaration of the OT symbol, solved by the fleet's asm-label alias (§501-N). Accelerator: a wave card for a +row whose family has a banked exemplar must carry that exemplar's SOURCE as the seed (family_cousins/seed_ref), and a hand pass +must open with `grep -l` for the family's banked bodies; a residual-class name is the family's signature, not a lever list. diff --git a/docs/backlog.md b/docs/backlog.md index ad6323d711..ce4bfdbe7f 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -2,12 +2,11 @@ > Generated by `tools/backlog.py render` from `.run/backlog.jsonl`. These are functions the Phase-21 automation got **close** on but did NOT byte-match. The whole-binary byte-gate is the sole arbiter (G3/P9): **byte-matches bank and are NOT listed here** — only genuine near-misses/blockers are. Ranked by hand-session priority: **reach** (×N propagation leverage) → **closeness** (match_one mismatch count, lower = closer) → **size**. Each row's `best_draft` is the closest C the machine reached — resume from there. -**Open near-misses:** 5 · by status {'near': 4, 'failed': 1} · by class {'WALL-PROVED': 1, 'SCHED+REGALLOC': 1, 'FRAME+SCHED': 1, 'SCHED': 1, None: 1} +**Open near-misses:** 4 · by status {'near': 3, 'failed': 1} · by class {'WALL-PROVED': 1, 'FRAME+SCHED': 1, 'SCHED': 1, None: 1} | # | addr | reach | class | nins | status | closeness | where it stuck | best draft | |--:|------|------:|-------|-----:|--------|----------:|----------------|------------| | 1 | func_80032A74 | None | WALL-PROVED | 422 | near | 1 | T4b HAND PASS S84 (2026-09-06, Fable Max): PROVED at 1 by producer census. Residual = ONE reload-time slot at sp+0x48 (the u16 lhu draft is 422/422 with DIFF 22 = frame rows only; the s16 lh draft is DIFF 1 at idx 244 with the frame exact). The four post-parameter slot producers (reload1.c:658 ghost alter_reg / caller-save.c:249 area / reload1.c:879 invalid-equiv address / reload1.c:3499 spill_stack_slot) each refuted on the bytes: the site loads lhu and the function has no lb and no double load (combine newi2pat ghosts re-derive a narrow load); no register-only insn shares a block with a call (no sched.c:4962 staleness, so no save area without sw/lw); no unallocated single-block equiv pseudo; $t0 holds no pseudo (else $t1 would be the spill reg) and LO mult results retry into GR_REGS. NEW mechanism measured: optimize_reg_copy_2 ghosts (tmp = x; tmp op= c; x = tmp) are minted AFTER regclass -> GR_REGS, allocated, vars=0 (P14). 18 isolated reproducers, 0 draft variants; cookbook §501-M; notes .run/P32/t4c/func_80032A74/NOTES.md | `.run/P32/t4/drafts/func_80032A74_tuclean.c` | -| 2 | func_800CF408 | None | SCHED+REGALLOC | 178 | near | 3 | S83 Fable: 49 -> 3, zero pins (the §501-H shape + a dead arg1 kill against cse re-association + the P_TAG OT write + a named mhi born before block 1). Residual idx 10-12 = §501-H verbatim (the unboosted tag load blocks one cycle behind the tpage sw; the empty cycle eats the highest-LUID floater ori $s5,0x96) COUPLED to the $t2/$t3 qty_compare contest (2389 vs 2400): every cure of one re-opens the other. NEXT: fill the OT-chain lhu gap with an UNBOOSTED `p & m24` as the target does (needs a 2-set a3 that combine does not re-merge — combine.c:2309 decrements reg_n_sets on the merge — e.g. a second set through a different width/mode or a volatile-qualified temp), or move the contest margin by one ref elsewhere (an extra ob use in a block that does not touch the tag load) | `.run/P32/t5x/fable/func_800CF408.c` | -| 3 | func_80039308 | None | FRAME+SCHED | 518 | near | 4 | S83 Fable: 17 -> 4 in the real TU. Closed the 11-row alias block (natural spelling; tail via a pointer so the li follows the addu in RTL) and rows 390/391 (p = r + a dead reset). Residual 4 = two causes: rows 49/50 the hoisted constant 2 vs the pinned vbase preheader order (move_movables splices after source preheader code); rows 412/415 a PHANTOM 8-byte frame slot with no traffic at sp+8 between the arg1 HImode spill (sp+0) and cnt (sp+0x10) — `lhu $s7` is reload's spill register; storing arg1 directly reproduces sh $a1/lhu $s7 but not the slot (frame 0x38 vs 0x40). NEXT: induce the phantom slot — a hard-reg spill_stack_slot (reload1.c spill_hard_reg on LO or $s7 during retry_global_alloc), cf. §501-E (pins forbid regs at retry) and the func_80032A74 ghost-pseudo finding (a stranded combine temp -> alter_reg 8-byte slot in regno order) | `.run/P32/t5x/fable/func_80039308.c` | -| 4 | func_80185810 | None | SCHED | 489 | near | 13 | S83 Fable: 35 -> 13 at exact length; 3 of 4 windows closed (P_TAG bitfield OT link + integer add for the addu operand order; sched1 flush_pending_lists at the 33rd memory op explains the load order -> HI temps; hard-reg destinations are not birthing-boosted -> pins uu $4 / mode $5 / ot16 $6 give the LUID order; shf pin $3). Residual ONE cause idx 363-380: `cl &= 0xFFFF` is an unboosted 2nd set — the fence after p[7]/= is needed (else its two reads float to the block head, 43/51) yet it blocks sched2 fillers crossing into the tpage/code window. NEXT: a spelling in which cl is single-set (its high half cleared at birth: cl = *(u16*)... or the shift form) so no fence is needed, or the two cl reads consume a fresh single-set copy that combine cannot fold (nonzero_bits defeats a plain andi copy; try a subreg/HI-mode temp) | `.run/P32/t5x/fable/func_80185810.c` | -| 5 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | +| 2 | func_80039308 | None | FRAME+SCHED | 518 | near | 4 | S83 Fable: 17 -> 4 in the real TU. Closed the 11-row alias block (natural spelling; tail via a pointer so the li follows the addu in RTL) and rows 390/391 (p = r + a dead reset). Residual 4 = two causes: rows 49/50 the hoisted constant 2 vs the pinned vbase preheader order (move_movables splices after source preheader code); rows 412/415 a PHANTOM 8-byte frame slot with no traffic at sp+8 between the arg1 HImode spill (sp+0) and cnt (sp+0x10) — `lhu $s7` is reload's spill register; storing arg1 directly reproduces sh $a1/lhu $s7 but not the slot (frame 0x38 vs 0x40). NEXT: induce the phantom slot — a hard-reg spill_stack_slot (reload1.c spill_hard_reg on LO or $s7 during retry_global_alloc), cf. §501-E (pins forbid regs at retry) and the func_80032A74 ghost-pseudo finding (a stranded combine temp -> alter_reg 8-byte slot in regno order) | `.run/P32/t5x/fable/func_80039308.c` | +| 3 | func_80185810 | None | SCHED | 489 | near | 13 | S83 Fable: 35 -> 13 at exact length; 3 of 4 windows closed (P_TAG bitfield OT link + integer add for the addu operand order; sched1 flush_pending_lists at the 33rd memory op explains the load order -> HI temps; hard-reg destinations are not birthing-boosted -> pins uu $4 / mode $5 / ot16 $6 give the LUID order; shf pin $3). Residual ONE cause idx 363-380: `cl &= 0xFFFF` is an unboosted 2nd set — the fence after p[7]/= is needed (else its two reads float to the block head, 43/51) yet it blocks sched2 fillers crossing into the tpage/code window. NEXT: a spelling in which cl is single-set (its high half cleared at birth: cl = *(u16*)... or the shift form) so no fence is needed, or the two cl reads consume a fresh single-set copy that combine cannot fold (nonzero_bits defeats a plain andi copy; try a subreg/HI-mode temp) | `.run/P32/t5x/fable/func_80185810.c` | +| 4 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index a47b2e08d0..9784ca3458 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -37434,3 +37434,23 @@ under-counted, §172 note); `vars=` on the `.frame` line remains the arbiter. ** residual, enumerate the artefact's PRODUCERS from the source and refute each on the bytes — the site's load width (`lh` vs `lhu`), the call blocks' contents, the spill register's identity and the mult results' alternate class each kill one producer without a compile. Probes and notes: `.run/P32/t4c/func_80032A74/`. + +**§501-N — A BANKED SIBLING'S SPELLING BEATS THE DRAFT'S DIALS; the `u32` array view of a `u8`-declared symbol is the fleet's +asm-label alias (P32 T4b hand pass, S84 2026-09-06; `md_MAIN_007:func_800CF408` 178/178 BANKED `commit:4001`, zero pins, zero asm +bodies).** The 3-row prologue-weave residual (§501-L: the T-139 memory-unit bubble handing `ori 0x96` the wrong LUID, coupled to +the `$t2/$t3` `qty_compare` contest) was a SHAPE symptom: the draft carried a named `mhi`, an `ob` base pointer, `y1/y2` temps +and an `arg1 = 0` kill, each a dial against the previous dial. The same-family sibling `md_MAIN_009:func_800CD92C` (§501-H) had +banked with the plain libgpu shape — `v = (OT[idx * 0x1000] & m24) & m24; t = *(u32 *)p; t &= 0xFF000000; t |= v; *(u32 *)p = +t;` then `OT[oi] = (OT[oi] & 0xFF000000) | ((u32)p & m24);` on a TRUE `u32` ARRAY_REF, `x -= 0xA0; y -= 0x78;` in place and +`x + 0xA0` / `y + 0x100` inline, colours chained `*(p+8) = *(p+9) = *(p+0xA) = c` — and porting it with this function's constants +matched first try. **Why the ARRAY_REF matters:** with element size 4 the address `(plus (mult idx 4) sym)` goes through +`memory_address → force_reg (sym)`, so cse keeps prim 1's read in the gas `lui $at/addu $at/lw %lo(sym)($at)` form and binds the +base into `$t2` for every later access (the target's shape); a `u8`-array spelling (`*(u32 *)&sym[oi]`, a one-member struct view, +a P_TAG bitfield on `&sym[oi]`) has `(plus sym idx)`, never binds, and emits the macro form eight times (measured). When the TU +declares the symbol with another type, take the fleet's alias: `extern u32 wD_800AA60C[] __asm__("D_800AA60C");` (1,438 banked +files carry `extern T name __asm__("D_…")` views; a declaration, not an asm body — R62 untouched). Also measured: the sibling's +lever-7 trailing `__asm__ volatile("" : "=r"(tmp))` 2-set dial is NOT portable here — the volatile asm makes hard regs live at its +position and flips the m24/colour `$t1/$t0` order. **Law:** when a same-family sibling is banked, port its spelling with the row's +constants BEFORE touching a dial on the draft; the residual class name (§501-H) is the family's signature, not a lever list. The +target's `vars= 8` here is a combine-minted ghost (§501-M species, `ghost_census.py`: `ST_REGS or none` → SLOT) reproduced by the +port for free. Notes and every variant: `.run/P32/t4c/func_800CF408/`. diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 5afe96b8e6..7b4218a750 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -99,7 +99,7 @@ Scale estimate: 3–5 sessions. `func_80011380` → `.run/m3/opus/func_80011380.c`; `func_801834A4` → `.run/S71_gate14/ov_SC03_105*/`), `exclude_audit --write`, `backlog.py render`; a T3 idiom naming a wall's mechanism re-opens that row (bounded: one attempt, permuter first). Wall table into this file; cookbook §496+; decision log; accelerators. -- [~] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive; supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish")** — **FIRST PASS COMPLETE 2026-09-05 (S83): 11 of 15 BANKED byte-identical, 4 carried to the NEXT session's HAND pass (Drew: no second agent round; hand-crack the remaining ones).** Hand pass first (22 spellings, 0 banks, every blocker refined to a mechanism in `.run/P32/t4b//NOTES.md`), then one Fable agent per row (permission, not requirement — Drew), resumed 3-at-a-time through three usage-limit outages. Banked (each: coordinator `rtu_match` in the CURRENT real TU → `gate_main` / `bank.sh` byte-identical → one commit; pins dropped by `exclude_audit --write`; mechanism in cookbook §501–§501-L): `main:func_800391D4` `commit:3956` · `main:func_80039DEC` `commit:3959` · `md_MAIN_009:func_800CD674` `commit:3964` · `ov_SC06_022:func_8017DF28` `commit:3966` · `main:func_80020DA4` `commit:3969` · `ov_SC03_105:func_801834A4` `commit:3972` · `md_MAIN_003:func_800CF3E8` `commit:3976` · `md_MAIN_009:func_800CD92C` `commit:3979` · `ov_SC07_002:func_8017DC80` `commit:3983` · `main:func_80011380` `commit:3990` (the §474 "PROVED" wall) · `md_MAIN_007:func_800CF6D0` `commit:3992`. Ten of the eleven were T4 "walls" or long-standing NEARs. **HAND PASS S84 (2026-09-06, Fable Max, no agents): row (a) `main:func_80032A74` → PROVED at 1 (§501-M producer census: the 0x48 slot can only be a combine-minted ghost, which needs an `lh`/`lb`; the pin stays with its final verdict; ledger + `tools/ghost_census.py` + `cc1_dumps.sh` repair; rows (b)(c)(d) next).** Carried (4, all exact length, in `docs/backlog.md` with next levers): `main:func_80032A74` 1 (the last pin; ghost pseudo — near-proved) · `md_MAIN_007:func_800CF408` 3 · `main:func_80039308` 4 · `ov_SC03_105:func_80185810` 13. Close: fleet R22 **218 passed / 0 failed, exits 0/0/0** (23:33–23:36 MDT, `.run/P32/t4b/r22_full.log`); `make report`: instr 13,486,890 / 13,488,497 = 100.0% · distinct 5,814,982 / 5,816,589 = 100.0% (90,982 / 90,984 unique) · fn-count 363,210 / 363,214 = 100.00% · **INCLUDE_ASM 4**; main REAL 787 · LINKED 1,256 · VERBATIM 3 · stubs 2 · 2,089 / 2,091 = 99.90% · `143dbb89…`; census `.run/P32/frontier_t4b_close.json` 4 stubs / 1,607 ins; decision-log P32 S83 T4b (R31); accelerators (10)–(11); tools-health OK (`.run/P32/t4b/tools_health.log`). +- [~] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive; supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish")** — **FIRST PASS COMPLETE 2026-09-05 (S83): 11 of 15 BANKED byte-identical, 4 carried to the NEXT session's HAND pass (Drew: no second agent round; hand-crack the remaining ones).** Hand pass first (22 spellings, 0 banks, every blocker refined to a mechanism in `.run/P32/t4b//NOTES.md`), then one Fable agent per row (permission, not requirement — Drew), resumed 3-at-a-time through three usage-limit outages. Banked (each: coordinator `rtu_match` in the CURRENT real TU → `gate_main` / `bank.sh` byte-identical → one commit; pins dropped by `exclude_audit --write`; mechanism in cookbook §501–§501-L): `main:func_800391D4` `commit:3956` · `main:func_80039DEC` `commit:3959` · `md_MAIN_009:func_800CD674` `commit:3964` · `ov_SC06_022:func_8017DF28` `commit:3966` · `main:func_80020DA4` `commit:3969` · `ov_SC03_105:func_801834A4` `commit:3972` · `md_MAIN_003:func_800CF3E8` `commit:3976` · `md_MAIN_009:func_800CD92C` `commit:3979` · `ov_SC07_002:func_8017DC80` `commit:3983` · `main:func_80011380` `commit:3990` (the §474 "PROVED" wall) · `md_MAIN_007:func_800CF6D0` `commit:3992`. Ten of the eleven were T4 "walls" or long-standing NEARs. **HAND PASS S84 (2026-09-06, Fable Max, no agents): row (a) `main:func_80032A74` → PROVED at 1 (§501-M producer census: the 0x48 slot can only be a combine-minted ghost, which needs an `lh`/`lb`; the pin stays with its final verdict; ledger + `tools/ghost_census.py` + `cc1_dumps.sh` repair; row (b) `md_MAIN_007:func_800CF408` → **BANKED byte-identical `commit:4001`** (the banked sibling func_800CD92C's spelling ported with a u32 array alias of the OT symbol, §501-N; zero pins/asm); rows (c)(d) next).** Carried (4, all exact length, in `docs/backlog.md` with next levers): `main:func_80032A74` 1 (the last pin; ghost pseudo — near-proved) · `md_MAIN_007:func_800CF408` 3 · `main:func_80039308` 4 · `ov_SC03_105:func_80185810` 13. Close: fleet R22 **218 passed / 0 failed, exits 0/0/0** (23:33–23:36 MDT, `.run/P32/t4b/r22_full.log`); `make report`: instr 13,486,890 / 13,488,497 = 100.0% · distinct 5,814,982 / 5,816,589 = 100.0% (90,982 / 90,984 unique) · fn-count 363,210 / 363,214 = 100.00% · **INCLUDE_ASM 4**; main REAL 787 · LINKED 1,256 · VERBATIM 3 · stubs 2 · 2,089 / 2,091 = 99.90% · `143dbb89…`; census `.run/P32/frontier_t4b_close.json` 4 stubs / 1,607 ins; decision-log P32 S83 T4b (R31); accelerators (10)–(11); tools-health OK (`.run/P32/t4b/tools_health.log`). - [ ] **T5 — PhaseEnd** (Max, Tier 1 — prompt R27): P7 checkbox walk; milestone demo (R22 fleet N/N, tools-health, `verbatim_check --strict`, final census, wall ledger, parked-5 dispositions via `make audit-disc`, `make report` all three metrics + main `143dbb89…` with/without SDK dirs, corrected denominators); **WAIT @@ -135,6 +135,7 @@ cookbook before the next drafting step (R16/R30) · no `Co-Authored-By` trailer needed for T0–T2b; if T2d needs it: `tools/ghidra_mcp_start.sh` → pause → Drew runs `/mcp` (R29) → G2 ping. ## Log +- 2026-09-06 (S84, continued) — **T4b hand pass, row (b) `md_MAIN_007:func_800CF408` BANKED byte-identical (`commit:4001`: bank.sh — rtu MATCH 178/178 in the real TU, splice, `make build BINARY=md_MAIN_007 -j8` rc 0, sha `2ff702b6…` == `config/check.md_MAIN_007.sha`).** The Fable draft's 3-row prologue-weave residual (§501-L) was a shape symptom: the same-family banked sibling `md_MAIN_009:func_800CD92C` (§501-H) had matched with the plain libgpu addPrim shape; porting it with this function's constants matched first try (`b0d_sibport_alias.c`). The TU declares `extern u8 D_800AA60C[]`, which kills the sibling's `u32` ARRAY_REF (the form whose address `memory_address → force_reg` lets cse bind the OT base into `$t2`; every `u8` respelling emits the `$at` macro form ×8) — solved with the fleet's asm-label alias `extern u32 wD_800AA60C[] __asm__("D_800AA60C");` (1,438 banked files carry the pattern; a declaration, not an asm body). Measured and refuted on the way: the sibling's lever-7 trailing volatile asm 2-set dial (flips `$t1/$t0`), the struct-view and P_TAG-on-`u8` forms. Post-bank: `twin_rescan` 3 open / 0 newly free; `verbatim_check --strict` 5==5; backlog rendered 4 open (the row pruned). Harvest: cookbook **§501-N**, accelerators (13), NOTES `.run/P32/t4c/func_800CF408/NOTES.md` (7 variants). bank.sh's `Claude-Session` trailer now comes from `$CLAUDE_SESSION` (was S83's id hard-coded). NEXT = row (c) `main:func_80039308` (4). - 2026-09-06 (S84, session 72d8b4b1, Max, Fable 5.1) — **T4b hand pass, row (a) `main:func_80032A74` CLOSED: PROVED at 1 (verdict, not a bank).** Preflight: tree clean, `verbatim_check --strict` 5==5, `make check-all` 218 passed / 0 failed rc 0 (`.run/P32/t4c/check_all_preflight.log`). Re-verified in the real TU (`rtu_match … --tu src/800_b_2.c --asm-subdir asm/nonmatchings/800_b_2`): the `s16 u18` draft DIFF 1 (idx 244 `lh` vs `lhu`, frame exact); the `u16 u18` TU-clean variant DIFF 22 = the 22 frame rows only (422/422 code). The residual is ONE reload-time slot at sp+0x48. Instead of a spelling sweep, enumerated every post-parameter stack-slot producer from the 2.7.2 source (reload1.c:658 ghost `alter_reg` · caller-save.c:249 area · reload1.c:879 invalid-equiv address · reload1.c:3499 `spill_stack_slot`) and refuted each on the bytes/dumps: combine's `newi2pat` ghosts re-derive a narrow load (`lh`/`lb`) and the site is `lhu` with no `lb`/double load; a save area without `sw/lw` needs sched.c:4962 staleness and no register-only insn shares a block with any of the 7 calls; unallocated single-block equiv pseudos cannot exist; `$t0` holds no pseudo (`order_regs_for_reload`) and LO mult results retry into `GR_REGS`. Found and measured a NEW ghost producer — `local-alloc.c optimize_reg_copy_2` on `tmp = x; tmp op= c; x = tmp;` (P13 refs 5, P14 refs 1) — which cannot slot because it is minted after regclass (class `GR_REGS`, no conflicts → allocated, vars=0). 18 isolated reproducers, 0 draft variants. Deliverables: cookbook **§501-M**, `tools/ghost_census.py` (new) + `tools/cc1_dumps.sh` (repaired: frame line + census, the under-counting `(use)` grep gone) + SETUP rows (R21), accelerators (12), backlog row (WALL-PROVED) + `tools/backlog.py` tie-break repair (kept the EARLIEST record at equal closeness — the S84 row never rendered), `config/wave_exclude.txt` annotated (`exclude_audit --assert-fresh` 1/1), notes `.run/P32/t4c/func_80032A74/NOTES.md`. NEXT = row (b) `md_MAIN_007:func_800CF408` (3). - 2026-09-05 13:05–23:40 MDT (S83, continued) — **T4b first pass COMPLETE: 11 of 15 banked, 4 carried.** Fifteen Fable agents launched from `.run/P32/t5x/` (BRIEF + packs + the hand-pass NOTES); three usage-limit outages killed every run (resumed each time via SendMessage with context intact; "write deliverables early" saved one crack from a dead run); from the second outage on, resumed 3 at a time (Drew). Verdicts: 11 MATCH (each re-verified by the coordinator in the CURRENT real TU and banked byte-identical — main rows via `gate_main` slates, overlays/modules via `SPLIT=… DRAFT_DIR=.run/P32/t5x/fable bank.sh`), 4 NEAR at exact length (1 / 3 / 4 / 13) with pass-attributed residuals and next levers ledgered. Every crack came from READING a pass dump against the 2.7.2 source; cookbook §501–§501-L (12 new laws: cascades, cross-jump-after-alloc, dying-input vs birthing boost, hard-reg sets count, pins forbid retry regs, CSE-quantity split, three-passes-three-dials, constants as floaters, manufactured orphans, a proved tree wall is not an RTL wall, sched2's /s exemption, coupled dials); decision-log P32 S83 T4b; accelerators (10)–(11). Instrument defects: bank.sh (empty fn list → built the unchanged tree, exit 0; `_jr_` TU split; draft dir) hardened, and two premature "banked" ledger messages corrected in the next commit (memory: write the message from the tool's output). Pins 7 → 1. Fleet R22 218/218 at the close; `make report` fleet 100.0/100.0/100.00, 4 stubs. **Drew: no second agent round; hand-crack the remaining four next session.** NEXT = the hand pass on the four (see the 🛑 block), then T5. - 2026-09-05 12:05–12:40 MDT (S83, continued) — **T4 DONE.** Preflight: tree clean, verbatim 5==5, R22 218/218 (12:00), `exclude_audit --assert-fresh` 7/7. Every pinned wall's best draft re-run with `rtu_match` in its CURRENT real TU: `func_80011380` DIFF 6 (`--o0`), `func_80020DA4` DIFF 2, `func_8017DF28` DIFF 2, `func_801834A4` DIFF 6 ×3 variants; the three CC1-FAIL rows re-probed after their plumbing was understood — `func_80032A74` (7 TU-provided typedefs + 4 decl spellings → `cdecl.strip_provided_typedefs` + the TU's lines → DIFF 1 in the real TU), `func_80039DEC` and `func_800391D4` (a sandbox TU copy under `.run/P32/t4/tu/` with the declaration edited THERE → DIFF 2 / DIFF 3) — no `src/` edit, no byte-neutral commit spent on rows that will not bank. Leaf `match_one` re-measured all three (1 / 2 (permuter) / 3). **No verdict changed: 1 PROVED (§474) + 6 CANDIDATE**, citations current (§474, §172 reload1.c:1445, loop.md L4 2.7.2:1529, cse_expr.md [A23-2], the K&R promotion laws). Deliverables: the wall table (above), `config/wave_exclude.txt` per-row S83 lines, backlog rows for all 7 (+ the two path-less rows fixed, R62; `docs/backlog.md` 16 open), cookbook §500-I, accelerators (8), decision-log. NEXT = **T5 (Max, Tier 1 — prompt R27, WAIT for gate 2)**. @@ -150,36 +151,39 @@ cookbook before the next drafting step (R16/R30) · no `Co-Authored-By` trailer - 2026-09-05 — **T1a DONE — `resident:func_800D128C` BANKED (243 ins, byte-identical 8e17e02f, R22 213/213).** The stored S71 closeness-0 draft was byte-correct all along; the whole task was three instrument defects the resident (the fleet's one `common.h`-only, `--pre`-sandwich binary) exposed in overlay-only assumptions: (1) `jr_isolate_all` dropped a file-local typedef whose name engine_types.h also defines (§496 — fixed: provided types derived from the TU's own includes); (2) `jtbl_carve` regenerated `JTBL_INTERLEAVE` without the `--pre hdr.rodata.o` clause → extract refused → the gate linked a stale script and booked the byte-correct draft as DIFF; `harvest_verify` ignored that extract's rc (§498 — both fixed, R49/R61); (3) `interleave_check` read a `--pre` line as n=0 (false DRIFT; fixed). R38 then found two more stored MATCH bodies for T1b/T1c (see their rows). Effort stayed Max. - 2026-09-05 — **T0 DONE.** Baseline reads all green (`.run/P32/t0_baseline.log`): `verbatim_check --strict` 5 bodies == 5 rows; `exclude_audit --assert-fresh` 8 entries, 8 WALL, 0 stale; `frontier_classify` → 21 rows = the S80 census exactly; `make tools-health` OK (sigs fresh, corpus(+resident), cdecl, audit-binaries 213/213, report lint+dedup, cookbook-index, split_indicator 213 OK); `make check-all` 213 passed / 0 failed, rc 0. Harness task list #1–#11 built (R28). NEXT = T1a. -## 🛑 SESSION CHECKPOINT — T4b HAND PASS IN PROGRESS: row (a) PROVED at 1, rows (b)(c)(d) NEXT, then T5 (2026-09-06 ~12:00 MDT; written by session 72d8b4b1 "S84"; SUPERSEDES the 2026-09-05 23:45 block) +## 🛑 SESSION CHECKPOINT — T4b HAND PASS IN PROGRESS: row (a) PROVED at 1, row (b) BANKED, rows (c)(d) NEXT, then T5 (2026-09-06 ~13:30 MDT; written by session 72d8b4b1 "S84"; SUPERSEDES the 2026-09-05 23:45 block) ### 0. How to use this block You are a FRESH SESSION that has read `PROJECT_CONTEXT.md`, `phase-ends/DIGEST.md`, `PhaseEnd_Phase29/30/31.md` and this file, and nothing else (CLAUDE.md protocol, R64 candidate). Replay this block verbatim into your chat, state phase / done / NEXT / effort, -list the rules from the digest, then WAIT for Drew. **NEXT is the HAND pass on rows (b) → (c) → (d) — Drew (2026-09-05 23:2x MDT): +list the rules from the digest, then WAIT for Drew. **NEXT is the HAND pass on rows (c) → (d) — Drew (2026-09-05 23:2x MDT): "we will hand crack the remaining ones next session instead of using agents."** Non-obvious root-cause work: recommend -**effort: Max** (R7/R27 — prompt and wait for the `/effort`). No Agent tool, no Workflow. After the three (banked or honestly +**effort: Max** (R7/R27 — prompt and wait for the `/effort`). No Agent tool, no Workflow. After the two (banked or honestly ledgered), T5 = the PhaseEnd (Tier 1, Max, WAIT for gate 2). ### 1. Where we are **Phase 32 — the last 21 + the parked 5 (short, kill-gated) — extended by Drew's T4b directive: every function that is not original hand-asm or a PsyQ object must be cracked and banked before the phase closes.** Gate 1 approved 2026-09-05; R44–R63 ratified then; R64 candidate. Tasks: **T0 ✓ T1a ✓ T1b ✓ T1c ✓ T2a–c ✓ (T2d not needed) T3 ✓ T4 ✓ T4b first pass ✓ (11 of 15 banked)** · -**T4b hand pass IN PROGRESS: row (a) `main:func_80032A74` CLOSED as PROVED at 1 (S84, a verdict — nothing banked this session); -rows (b)(c)(d) open** · **T5 pending.** Harness tasks #1–#13 (#13 = T4b in_progress). -Fleet **218 binaries**. **No `src/`, `config/` (except `wave_exclude.txt` annotation) or carve state changed in S84.** Last fleet R22: +**T4b hand pass IN PROGRESS: row (a) `main:func_80032A74` CLOSED as PROVED at 1 (S84, a verdict); row (b) +`md_MAIN_007:func_800CF408` BANKED byte-identical `commit:4001` (S84 — md_MAIN_007 is now 100% C); rows (c)(d) open** · **T5 pending.** Harness tasks #1–#13 (#13 = T4b in_progress). +Fleet **218 binaries**. **S84 `src/` change: ONE bank (`src/md_MAIN_007/md_MAIN_007.c`, `commit:4001`, sha byte-identical by `make build`); no `config/` (except the `wave_exclude.txt` annotation) or carve-state change; a fleet R22 is still owed at the T4b close.** Last fleet R22: `make clean && make extract-all && make check-all` → 217+main extracted, **218 passed / 0 failed, exits 0/0/0 at 2026-09-05 23:36 MDT** (`.run/P32/t4b/r22_full.log`); S84 preflight `make check-all` → **218 passed / 0 failed, EXIT=0** (`.run/P32/t4c/check_all_preflight.log`). `make report` (S83 close, still current): **instr 13,486,890 / 13,488,497 = 100.0% · distinct 5,814,982 / 5,816,589 = 100.0% (90,982 / 90,984 unique fns) · fn-count 363,210 / 363,214 = 100.00% · INCLUDE_ASM 4**; main REAL 787 · LINKED 1,256 · VERBATIM 3 · stubs 2 · byte-identical 2,089 / 2,091 = 99.90% · sha `143dbb89…`. `verbatim_check --strict` 5 == 5 (S84). `config/wave_exclude.txt`: **1 entry** (`main:func_80032A74`, now carrying its S84 PROVED verdict), `exclude_audit --assert-fresh` 1/1 OK (S84). Census -`.run/P32/frontier_t4b_close.json`: **4 stubs / 1,607 ins**. `make tools-health` → OK at the S83 close (`.run/P32/t4b/tools_health.log`); +`.run/P32/frontier_t4b_close.json`: **4 stubs / 1,607 ins** at the S83 close — now **3 stubs / 1,429 ins** open after (b) (regenerate at the T4b close). `make tools-health` → OK at the S83 close (`.run/P32/t4b/tools_health.log`); `cookbook_index.py --check` OK (S84). Non-ghidra tree clean at HEAD after the S84 commit; the `ghidra/` churn is R23 restart-noise — never stage it. Claude commits, Drew pushes (R6; ~100 unpushed). 100% C: resident, md_SC03_053/054/056, md_MAIN_003, md_MAIN_009, ov_SC06_022, ov_SC07_002. ### 2. What S84 did (session 72d8b4b1, 2026-09-06, Max, Fable 5.1, no agents) -Row (a) only. Re-verified both best drafts in the real TU; then, instead of a spelling sweep, read every post-parameter stack-slot +Row (a) (verdict) and row (b) (BANKED). **Row (b):** the banked sibling `func_800CD92C`'s spelling ported with this row's constants = +MATCH first try; the TU's `u8` declaration of the OT symbol needed the fleet's asm-label alias `extern u32 wD_800AA60C[] +__asm__("D_800AA60C");` (§501-N, accelerators (13)); bank.sh (`.run/P32/t3s3/bank.sh`) did the rtu → splice → build → sha → commit chain. +**Row (a):** Re-verified both best drafts in the real TU; then, instead of a spelling sweep, read every post-parameter stack-slot producer out of `tools/reference/gcc-2.7.2` and refuted each on the bytes/dumps — the producer census is cookbook **§501-M** and `.run/P32/t4c/func_80032A74/NOTES.md`. Found a NEW ghost producer (`local-alloc.c optimize_reg_copy_2`) and measured why it cannot slot (post-regclass → allocatable). Tooling: **`tools/ghost_census.py`** (new; ghosts with stale refs and their class), **`tools/cc1_dumps.sh` @@ -188,14 +192,15 @@ tie-break repaired** (kept the EARLIEST record at equal closeness — the S84 PR (12), backlog row `WALL-PROVED`, the pin annotated. 18 isolated reproducers (`.run/P32/t4c/func_80032A74/p1..p18.c`), 0 draft variants. **Verdict for (a): PROVED at 1** — the honest final disposition the plan allows for this row (P9; nothing redefined). -### 3. THE THREE REMAINING ROWS — the hand-crack briefs (all at EXACT length, all rtu-clean; unchanged from the 23:45 block) +### 3. THE REMAINING ROWS — the hand-crack briefs (all at EXACT length, all rtu-clean; (c)(d) unchanged from the 23:45 block) Verify any draft with `rtu_match` in the REAL TU (main: `--tu src/.c --asm-subdir asm/nonmatchings/`; overlays/modules: `--split --source `); bank via `gate_main` (main) or `SPLIT= DRAFT_DIR= .run/P32/t3s3/bank.sh "" <fn>` (it refuses on red). RTL dumps: `tools/cc1_dumps.sh <self-contained draft> <tag>` → `.run/c294/dumps_<tag>/<tag>.i.{rtl,jump,cse,loop,flow,combine,sched,lreg,greg}` + the `.frame`/ins/spill/ghost summary (the draft must carry its own typedefs/externs; add `-O0` by editing the script's cc1 line for boot). Each row's Fable report (`.run/P32/t5x/reports/<fn>.md`) carries the dump citations and the measured-inert list — READ IT FIRST, do not repeat its sweeps. -**Do the producer census BEFORE any spelling probe (§501-M, accelerators (12)): name the pass and the dump line that owns the residual.** +**Do the producer census BEFORE any spelling probe (§501-M, accelerators (12)): name the pass and the dump line that owns the residual — and +BEFORE that, `grep -l` for a banked same-family sibling and port its spelling with the row's constants (§501-N, accelerators (13)).** **(a) `main:func_80032A74` — CLOSED: PROVED at 1 (S84).** Best drafts: `.run/P32/t4/drafts/func_80032A74_tuclean.c` (`s16 u18`, rtu DIFF 1 = idx 244 `lh` vs `lhu`, frame exact) and `.run/P32/t4c/func_80032A74/lhu_tuclean.c` (`u16 u18`, 422/422 code, DIFF 22 = the @@ -206,7 +211,9 @@ register-only insn shares a block with any call; reload1.c:879 needs an unalloca needs a pseudo in `$t0` (impossible: `lw $t0` param reloads) or a failed LO retry (mult results have alternate `GR_REGS`). `optimize_reg_copy_2` ghosts are post-regclass and allocatable (P14 vars=0). Do NOT reopen without a new producer. -**(b) `md_MAIN_007:func_800CF408` — 178 ins, closeness 3, zero pins.** TU `src/md_MAIN_007/md_MAIN_007.c`, sub `md_MAIN_007`, asm +**(b) `md_MAIN_007:func_800CF408` — CLOSED: BANKED byte-identical `commit:4001` (S84).** Draft `.run/P32/t4c/bank/func_800CF408.c` = the sibling +port (`b0d_sibport_alias.c`); notes `.run/P32/t4c/func_800CF408/NOTES.md`. The brief below is kept for the record only. +**(b, superseded) `md_MAIN_007:func_800CF408` — 178 ins, closeness 3, zero pins.** TU `src/md_MAIN_007/md_MAIN_007.c`, sub `md_MAIN_007`, asm `asm/md_MAIN_007/nonmatchings/md_MAIN_007/`. Draft `.run/P32/t5x/fable/func_800CF408.c`; report `.run/P32/t5x/reports/func_800CF408.md`; probes/dumps `.run/P32/t5x/work/func_800CF408/`. **Residual idx 10–12** (`ori $s5,0x96` below `sw $s0` / `li $s0,5`): §501-H's floater mechanism — the unboosted tag load lingers up block 1's store stream, is `blocking` one cycle behind the tpage `sw` at T-139, and the @@ -246,7 +253,8 @@ temp defeats `nonzero_bits`). 3,360-variant region-2 sweep best 14 — do not re ### 4. NEXT — in order 0. **Preflight:** `git status --short | grep -v ghidra/` (empty) · `verbatim_check --strict` (5 == 5) · `make check-all` → 218/218 (R56 baseline). Prompt `/effort max` (R27) and WAIT. -1. **The hand pass on (b) → (c) → (d), one row at a time:** read the report, reproduce the residual with `rtu_match`, dump the RTL +1. **The hand pass on (c) → (d), one row at a time:** FIRST `grep -l` the family's banked bodies (for (c): the main `800_c.c` neighbours; + for (d): the `ov_SC03_105`/`jr_80181C84` OT/DR_TPAGE shapes and §501-I) and port a sibling's spelling if one exists; then read the report, reproduce the residual with `rtu_match`, dump the RTL (`cc1_dumps.sh`), run the producer census where the residual is a frame/slot (§501-M), attribute the residual to a PASS and a dump line before the first probe (§501, accelerators (11)/(12)), then the row's next lever; ≤ ~10 draft probes per row before writing the verdict. A MATCH → bank + commit + `backlog.py render` + cookbook §501-N…; a plateau → `backlog.py log` (closeness, class, best draft, @@ -303,7 +311,9 @@ PRODUCERS of a frame residual before any spelling (§501-M, accelerators (12)) line · rules check every 4 tasks (P6) · harvest into the cookbook before the next drafting step (R16/R30) · no `Co-Authored-By` (R5) · never stage `ghidra/` (R23). -**Plain-English recap (R18).** This session took the first of the four leftover functions — the one that was a single instruction +**Plain-English recap (R18).** This session banked the second leftover function outright: instead of tuning the previous draft further, it +copied the wording of an already-finished cousin function from the same family, adjusted the numbers, and it matched on the first +try (the only snag was a type declaration in the file, solved the way 1,400 other files already do). It also took the first of the four leftover functions — the one that was a single instruction away — and, instead of trying more rewordings, listed every way the 1995 compiler can leave an unused slot in a function's stack frame and struck each off against the bytes. The only way that could produce this slot at zero cost needs a signed 16-bit load, and the original uses an unsigned one, so the function is now recorded as proved-unreachable by re-spelling, with the compiler pass named.