docs(phase-32): T4b (8) ledger — func_800CD92C banked (md_MAIN_009 100% C), backlog re-rendered, the Fable draft + report + verdict kept; queue updated

This commit is contained in:
Drew T
2026-09-05 18:55:02 -06:00
parent 4a9a67c59e
commit 511afcf75c
6 changed files with 305 additions and 10 deletions
@@ -0,0 +1,5 @@
CC build/src/md_MAIN_009/md_MAIN_009.o
LD build/md_MAIN_009/md_MAIN_009.elf
OBJCOPY build/md_MAIN_009/md_MAIN_009
[ OK ] build/md_MAIN_009/md_MAIN_009
sha1 d270f695b793b5c03db159b7aabcc066daa87eda == config/check.md_MAIN_009.sha (BYTE-IDENTICAL)
+211
View File
@@ -0,0 +1,211 @@
/* func_800CD92C — md_MAIN_009 (-O2). Builds six 0x18-byte SPRT-with-own-tpage prims
* (tag / 0xE1xxxxxx draw-mode word / rgb+code 0x64 / xy / uv+clut / wh) at the
* D_800A71D0 prim cursor and addPrim()s each onto OT word [0] of the frame's
* ordering table D_800ABA24[D_800BAE22 * 0x1000], then republishes the advanced
* cursor. Four 256-wide tiles at (x-0xA0 + 0x100*i, y-0x78) plus a fixed
* 2x(0xA0 x 0x100) backdrop. Same-TU sibling: func_800CD674 (4 prims).
*
* MATCH 247/247 with ZERO register pins (P32 T5x, Fable). The two prologue
* mechanisms, both read from the gcc-2.7.2 source and the -dS/-dl dumps:
*
* A. `m24` lands in $t1 by REF COUNT. local_alloc orders qtys by
* floor_log2(n_refs)*n_refs/life with n_refs = flow's count, taken BEFORE
* combine (toplev.c) and never adjusted by it (combine.c:56). The libgpu
* P_TAG bitfield store re-masks an already-masked getaddr() value
* (store_fixed_bit_field must_and), so the pre-combine RTL holds
* `(and (and ot m24) m24)`; combine folds it (associative rule +
* simplify_binary_operation op0==op1) to ONE `and`, but m24 keeps 19 refs
* (4*19=76) against la's 13 (3*13=39) and is allocated first -> $9. The
* `(... & m24) & m24` below IS that double mask; a `register ... $9` pin is
* the wrong tool (it also forbids $9 to every retried allocno, cf. 501-E).
*
* B. tp8D/tp8F float to the block top because the TAG LOAD is an in-place
* (multi-set) pseudo, exactly as the bitfield RMW expands (`t = *p;
* t &= FF00; t |= v; *p = t` on ONE pseudo). sched1 splits every large
* constant into lui+ori (sched.c:4826, mips.md large_int) and
* update_n_sets makes reg_n_sets 2, so the tpage constants are unboosted
* pri-1 floaters; a floater is consumed only by an EMPTY ready-list cycle,
* and each RMW chain has one (the lhu->sll latency gap). A single-set tag
* load is birthing-boosted and glued to its `and`; a multi-set one is not,
* and it fills those gaps instead -- so nothing eats tp8D/tp8F, they float
* like tp89/m24/tp8B, and local-alloc hands out $16..$19 in the target's
* order (tp8B < tp86 < tp8D < tp8F by life; tp87 shares $16 with tp8B).
* The mask temp `v` must stay a fresh expression: an in-place `v &= m24`
* is a 4-ref/2-insn qty that outranks `p` and steals $2 (the $v0/$v1 swap).
* Statement order matters once more: `v` (the OT read) BEFORE `t &= FF00`,
* so the FF00 constant's UID is above the index `sll` -- among two boosted
* insns sched1 picks the higher UID first, and with FF00 emitted early it
* takes prim 1's lhu->sll gap, the tag load then lingers into the store
* stream (memory-unit `blocking insn`), and its bubble hands tp8F's `ori`
* the wrong LUID (the last closeness-2 residual).
*
* Kept from the t3 draft (each byte-measured there): plain `*(T *)(p + off)`
* field stores (a non-QImode MEM_IN_STRUCT_P varying store is exempt from
* conflicting with the fixed non-struct `lhu D_800BAE22`, so struct fields let
* the sh stores sink -- sched.c true_dependence); the OT store as an ARRAY_REF
* lvalue with a block-scoped `oi` (lets the final publish hop above the last
* OT RMW); `x -= 0xA0` on the parameter; the chained r0=g0=b0 store.
* D_800BAE22 must stay the TU's plain scalar: any struct/array/cast spelling
* goes through change_address -> memory_address -> force_reg (one shared
* `la`), which is not the target's 12 lui/lhu macro loads.
*/
extern u8 *D_800A71D0;
extern u32 D_800ABA24[];
extern u16 D_800BAE22;
void func_800CD92C(s32 x, s32 y, s32 c) {
u8 *p;
u32 m24;
p = D_800A71D0;
x -= 0xA0;
y -= 0x78;
*(u8 *)(p + 0x3) = 5;
*(u32 *)(p + 0x4) = 0xE1000089;
*(u8 *)(p + 0xB) = 0x64;
*(u16 *)(p + 0x12) = 0x7840;
*(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = c;
*(s16 *)(p + 0xC) = x;
*(s16 *)(p + 0xE) = y;
*(u8 *)(p + 0x10) = 0;
*(u8 *)(p + 0x11) = 0;
*(s16 *)(p + 0x14) = 0x100;
*(s16 *)(p + 0x16) = 0x100;
m24 = 0x00FFFFFF;
{
u32 v = (D_800ABA24[D_800BAE22 * 0x1000] & m24) & m24;
u32 t = *(u32 *)p;
t &= 0xFF000000;
t |= v;
*(u32 *)p = t;
}
{
s32 oi = D_800BAE22 * 0x1000;
D_800ABA24[oi] = (D_800ABA24[oi] & 0xFF000000) | ((u32)p & m24);
}
p += 0x18;
*(u8 *)(p + 0x3) = 5;
*(u32 *)(p + 0x4) = 0xE100008B;
*(u8 *)(p + 0xB) = 0x64;
*(u16 *)(p + 0x12) = 0x7840;
*(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = c;
*(s16 *)(p + 0xC) = x + 0x100;
*(s16 *)(p + 0xE) = y;
*(u8 *)(p + 0x10) = 0;
*(u8 *)(p + 0x11) = 0;
*(s16 *)(p + 0x14) = 0x100;
*(s16 *)(p + 0x16) = 0x100;
{
u32 v = (D_800ABA24[D_800BAE22 * 0x1000] & m24) & m24;
u32 t = *(u32 *)p;
t &= 0xFF000000;
t |= v;
*(u32 *)p = t;
}
{
s32 oi = D_800BAE22 * 0x1000;
D_800ABA24[oi] = (D_800ABA24[oi] & 0xFF000000) | ((u32)p & m24);
}
p += 0x18;
*(u8 *)(p + 0x3) = 5;
*(u32 *)(p + 0x4) = 0xE100008D;
*(u8 *)(p + 0xB) = 0x64;
*(u16 *)(p + 0x12) = 0x7840;
*(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = c;
*(s16 *)(p + 0xC) = x + 0x200;
*(s16 *)(p + 0xE) = y;
*(u8 *)(p + 0x10) = 0;
*(u8 *)(p + 0x11) = 0;
*(s16 *)(p + 0x14) = 0x100;
*(s16 *)(p + 0x16) = 0x100;
{
u32 v = (D_800ABA24[D_800BAE22 * 0x1000] & m24) & m24;
u32 t = *(u32 *)p;
t &= 0xFF000000;
t |= v;
*(u32 *)p = t;
}
{
s32 oi = D_800BAE22 * 0x1000;
D_800ABA24[oi] = (D_800ABA24[oi] & 0xFF000000) | ((u32)p & m24);
}
p += 0x18;
*(u8 *)(p + 0x3) = 5;
*(u32 *)(p + 0x4) = 0xE100008F;
*(u8 *)(p + 0xB) = 0x64;
*(u16 *)(p + 0x12) = 0x7840;
*(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = c;
*(s16 *)(p + 0xC) = x + 0x300;
*(s16 *)(p + 0xE) = y;
*(u8 *)(p + 0x10) = 0;
*(u8 *)(p + 0x11) = 0;
*(s16 *)(p + 0x14) = 0x40;
*(s16 *)(p + 0x16) = 0x100;
{
u32 v = (D_800ABA24[D_800BAE22 * 0x1000] & m24) & m24;
u32 t = *(u32 *)p;
t &= 0xFF000000;
t |= v;
*(u32 *)p = t;
}
{
s32 oi = D_800BAE22 * 0x1000;
D_800ABA24[oi] = (D_800ABA24[oi] & 0xFF000000) | ((u32)p & m24);
}
p += 0x18;
*(u8 *)(p + 0x3) = 5;
*(u32 *)(p + 0x4) = 0xE1000086;
*(u8 *)(p + 0xB) = 0x64;
*(u16 *)(p + 0x12) = 0x7880;
*(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = c;
*(s16 *)(p + 0xC) = -0xA0;
*(s16 *)(p + 0xE) = -0x78;
*(u8 *)(p + 0x10) = 0;
*(u8 *)(p + 0x11) = 0;
*(s16 *)(p + 0x14) = 0xA0;
*(s16 *)(p + 0x16) = 0x100;
{
u32 v = (D_800ABA24[D_800BAE22 * 0x1000] & m24) & m24;
u32 t = *(u32 *)p;
t &= 0xFF000000;
t |= v;
*(u32 *)p = t;
}
{
s32 oi = D_800BAE22 * 0x1000;
D_800ABA24[oi] = (D_800ABA24[oi] & 0xFF000000) | ((u32)p & m24);
}
p += 0x18;
*(u8 *)(p + 0x3) = 5;
*(u32 *)(p + 0x4) = 0xE1000087;
*(u8 *)(p + 0xB) = 0x64;
*(u16 *)(p + 0x12) = 0x7880;
*(u8 *)(p + 0x8) = *(u8 *)(p + 0x9) = *(u8 *)(p + 0xA) = c;
*(s16 *)(p + 0xC) = 0;
*(s16 *)(p + 0xE) = -0x78;
*(u8 *)(p + 0x10) = 0x20;
*(u8 *)(p + 0x11) = 0;
*(s16 *)(p + 0x14) = 0xA0;
*(s16 *)(p + 0x16) = 0x100;
{
u32 v = (D_800ABA24[D_800BAE22 * 0x1000] & m24) & m24;
u32 t = *(u32 *)p;
t &= 0xFF000000;
t |= v;
*(u32 *)p = t;
}
{
s32 oi = D_800BAE22 * 0x1000;
D_800ABA24[oi] = (D_800ABA24[oi] & 0xFF000000) | ((u32)p & m24);
}
p += 0x18;
D_800A71D0 = p;
}
+80
View File
@@ -0,0 +1,80 @@
# func_800CD92C (md_MAIN_009, 247 ins) — Fable arm (t5x) — **MATCH 247/247, real TU, zero pins**
Deliverable: `.run/P32/t5x/fable/func_800CD92C.c` (N9b). `match_one` MATCH; `rtu_match --split md_MAIN_009 --source md_MAIN_009`
MATCH in the real TU; relocation audit (R1c) 2×D_800A71D0 (lw/sw), 2×D_800ABA24 (la + `lw D_800ABA24($3)`), 12×D_800BAE22 —
identical to the target's `%hi/%lo` counts. Externs spelled as the TU's file-scope lines 224-226 (`extern u8 *D_800A71D0;`
`extern u32 D_800ABA24[];` `extern u16 D_800BAE22;`); no typedefs, no `register`, no `__asm__` (the Opus draft's five §17
pins are gone — the prior `extern u32 D_800A71D0` now CC1-FAILs in the TU because func_800CD674 was banked with `u8 *`).
## What the residual actually was (read from the compiler + `-dS/-dl` dumps, not guessed)
The Opus draft's 15 was NOT "sched2 prologue weave steered by nothing". Two independent mechanisms, both decided in sched1
and local-alloc, both fixed by spelling the addPrim the way libgpu's `P_TAG` bitfield macros expand:
**1. m24's register is a REF-COUNT effect, not a pin.** `qty_compare` (local-alloc.c:1579) = floor_log2(n_refs)·n_refs·size /
(death−birth) with `qty_n_refs = reg_n_refs` (local-alloc.c:297) — FLOW's count, computed before combine (toplev.c:2983 vs
3004) and not adjusted by combine (combine.c:56). la (13 refs, life 342) beats an unpinned m24 (13 refs, life 420) → la=$9
(E1 measured: 41 mismatched — Opus's "dropping the m24 pin → 41"). The libgpu `setaddr(p, getaddr(ot))` bitfield store
re-masks its already-masked value (`store_fixed_bit_field` must_and, expmed.c:608-620): pre-combine RTL `(and (and ot m24)
m24)`, folded by combine's associative rule (combine.c:3140-3170 → `simplify_binary_operation` AND op0==op1, cse.c:3930) to
ONE `and` — but m24 keeps 19 refs → 4·19=76 > la's 39 → m24 first → $9, la $10, FF00 $11. Spelled `(ot & m24) & m24` with
`u32 m24 = 0xFFFFFF` (E3: identical bytes to the pinned draft, closeness 15, m24 "used 19 times" in `-dl`).
**2. tp8D/tp8F float because the TAG LOAD is a multi-set pseudo.** sched1 `try_split`s every insn before scheduling
(sched.c:4826; mips.md:3210 `large_int` → lui+ori) and `update_flow_info` → `update_n_sets` bumps `reg_n_sets` to 2
(sched.c:4617/4234), so every 0xE10000xx constant is an unboosted pri-1 floater (pinned or not — E2 no-pins had the identical
stall picks). Backward list scheduling consumes a floater only in an EMPTY ready-list cycle; each RMW chain has exactly one
(the `lhu→sll` latency gap, cost 2 queue): base trace stalls T-44/54, 81/91, 116/126, 150/160 = prim (k−1)'s two gaps eat
prim k's constant (tp87→r5, tp86→r4, tp8F→r3, tp8D→r2; tp8B/m24/tp89 reach the top). In the target's sched2 top block
(= ascending LUID of the pri-1 pool, memory ops hazard-first) tp8D/tp8F sit BELOW li5, i.e. they floated. The bitfield
RMW expands `t = *p; t &= FF00; t |= v; *p = t` on ONE pseudo (expand_binop target reuse): `reg_n_sets`=3 → no birthing
boost (sched.c:2490) → the tag load is not glued to its `and` and fills the `lhu→sll` gap instead (N1 trace T-52,
N7 stall list shrinks to one) → tp8D/tp8F float, and local-alloc's life order gives tp8B $16, tp86 $17, tp8D $18, tp8F $19,
tp87 sharing $16 (N6/N7 dumps). Spelled `{ u32 v = (ot & m24) & m24; u32 t = *(u32 *)p; t &= 0xFF000000; t |= v;
*(u32 *)p = t; }`.
**Two sub-lessons inside #2 (each cost one probe):**
* `v` must be a FRESH expression: `v &= m24` in place makes a 4-ref/2-insn qty (pri 2.0 > p's 1.6) that is allocated
before `p` and takes $2 → the 178-diff $v0/$v1 swap (N4/N6).
* `v` (the OT read) must precede `t &= FF00`: the FF00 constant is force_reg'd where the `and` is expanded; if its UID is
below the index `sll`'s, sched1's boosted tie (LUID rule) picks the `sll` first and FF00 drops into prim 1's `lhu→sll`
gap; the unboosted tag load then lingers into the store stream, is memory-unit `blocking insn 81` each cycle, and its
bubble (T-207) takes the highest-LUID floater = tp8F's `ori` → the closeness-2 `li $t7`/`ori $s3` swap (N7 vs N1 traces).
## Why the natural libgpu form itself is NOT the draft (measured, for the record)
N1 (struct fields + `P_TAG` bitfield addPrim + `/s` index) reproduces the whole prologue/body SHAPE (239 ins, only −8),
but any struct/array/cast spelling of D_800BAE22 goes through `change_address → memory_address → force_reg` (constant
address, pre-cse) = one shared `la $11,D_800BAE22` + 12 `lhu 0($11)`, which steals $11 and shifts every later register.
The target's 12 `lui/lhu D_800BAE22` gas-macro loads mean the original read it as the plain scalar the TU declares. A `/s`
tag store with a plain scalar index would CSE the second `lhu` (§364: cse.c `note_mem_written` sets `all=0` for a
MEM_IN_STRUCT_P or PLUS-address non-QI store, `invalidate_memory` then spares non-struct fixed entries), so the tag store
stays the non-`/s` `*(u32 *)p` while the mask/pseudo SHAPE of the bitfield expansion is kept by hand. The OT side keeps the
t3 levers (ARRAY_REF lvalue, block-scoped `oi`) — N6 showed the OT spelling is irrelevant to the prologue.
## Levers measured (all in `.run/P32/t5x/work/func_800CD92C/`, dumps in `dumps_<variant>/`)
| variant | change | result |
|---|---|---|
| base (Opus t3) | 5 pins | 15 |
| v_unpin8D8F | tp8D/tp8F inline, other pins kept | 245 ins (alloc shift) |
| e1_m24unpin | m24 plain local | 41 (la takes $9) |
| e2_nopins | everything plain | 241 ins, frame 16 |
| e3_dblmask | m24 plain + `(ot&m24)&m24` | **15, byte-identical to base** (m24 $9 by 19 refs) |
| n1_libgpu | struct fields + P_TAG bitfields + `/s` index | 239 ins (−8 = the `la` index), prologue SHAPE = target |
| n2A/B/C/D, n3 | other `/s` index spellings (array, cast, asm-label alias) | `la` in all but A; A is non-`/s` and CSEs to 6 loads (222) |
| n4_inplace | E3 + in-place `t`/`v`/`o` temps, no pins | 247, 178 ($v0/$v1 swap) |
| n5_otonly / n6_tagonly | bisect | OT side inert (241); tag side = 178 |
| n7_tagT | in-place `t`, fresh `(ot&m24)&m24`, FF00 first | **2** (`li 5`/`ori $s3` swap) |
| n8_u8ptr | n7 + TU's `extern u8 *D_800A71D0` | 2, rtu compiles |
| n9a / n9b | FF00 after the OT read | **MATCH** (both instruments) |
## Cookbook-worthy generalizations (for the coordinator's harvest)
* **REF-COUNT ALLOCATION LEVER:** a mask/constant's local-alloc priority counts flow-time refs; a source that produces a
combine-foldable redundant use (`(x & m) & m`, the bitfield must_and) raises the pseudo's priority at zero bytes. This is
how libgpu's bitfield addPrim puts the 24-bit mask in `$t1` ahead of the OT base in every SPRT/POLY function — check
`-dl` "used N times" before pinning a mask register (§17 pins are a symptom-fix here; §501-E shows their side effects).
* **UNBOOSTED TAG LOAD = STALL FILLER:** an in-place RMW temp (multi-set) frees the `lhu→sll` gaps that otherwise eat
the split large-constant floaters; the "prologue weave" of hoisted `lui/ori` pairs is decided by which pseudos are
single-set in the RMW chains, not by any prologue-side lever (extends map §S7/§S2).
* **Struct-member GLOBAL access = one `la`:** `change_address → memory_address` force_regs a constant address pre-cse; a
target with N `lui/lhu SYMBOL` macro loads read a plain scalar — do not spell it as a struct field.
* **Statement order inside an RMW block sets the UID tie among boosted insns** (FF00 vs the index `sll`): materialize a
mask constant AFTER the address expression it competes with.
+1 -2
View File
@@ -1,7 +1,6 @@
# T4b Fable resume queue (Drew 2026-09-05: "resume agents, but not all at once, just 3 at a time"). Delete a line when resumed.
# fn agentId closeness
func_8017DC80 a7c2c1e4865e5590d 46
func_800CF408 aac6ce9fdfdcc093c 49
func_800CF6D0 a7f7e477e9878acdd 137
func_80011380 a60ffea4022b891fc 6 (-O0, §474 PROVED — last)
# RUNNING: func_800CD92C a5587b9d5c7006214 · func_80039308 a55fbfb4fb896bd71 · func_80185810 a547e70e9a7735c8a (DONE MATCH: 391D4 39DEC CD674 DF28 20DA4 1834A4 CF3E8; NEAR: 32A74 1)
# RUNNING: func_80039308 a55fbfb4fb896bd71 · func_80185810 a547e70e9a7735c8a · func_8017DC80 a7c2c1e4865e5590d (DONE MATCH: 391D4 39DEC CD674 DF28 20DA4 1834A4 CF3E8 CD92C; NEAR: 32A74 1)
+1
View File
@@ -6,3 +6,4 @@
{"fn": "func_801834A4", "binary": "ov_SC03_105", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_801834A4.c", "note": "CSE-quantity split, not loop.c: expand_divmod (expmed.c:3034-3057) emits const/mult/sra/subu adjacently from ONE op0 so loop.c treats mult and sra alike (force_movables loop.c:1226 doubles K's savings -> hoists all, or a hard-reg dividend kills all). cse.c canon_reg never rewrites a hard reg but hashes by reg_qty: `sign = half >> 31` at the loop TOP (movable, maybe_never==0) + `hh = half` (register $2) + `pos[0] -= hh / 3` makes the mult read $2 (not movable; K unlinked, inline) while the division's sra is CSE'd into sign (hoisted); combine folds the copy into the mult. Traps: a callee-saved pin enters regs_ever_live before combine -> global pass 0 gives it to j (7); an asm feed for the unread sign store adds +2 weighted refs and swaps half/sign in allocno_compare (4) -> a dead `sign = 0` initializer instead (flow deletes it). Coordinator rtu MATCH 106/106; bank.sh byte-identical", "session": "491895ad"}
{"fn": "func_80032A74", "binary": "main", "arm": "fable", "status": "NEAR", "closeness": 1, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_80032A74.c", "note": "rtu DIFF 1 in src/800_b_2.c (idx 244 lh vs lhu; frame 0x78 exact); the lhu respelling is code-exact 422/422 with vars=56. Residual mechanism READ + byte-reproduced: the never-referenced 8-byte slot at 0x48 is a GHOST pseudo — a stranded middle temp of a 3-insn combine whose refs-zeroing is skipped when newi2pat!=0 (combine.c:2306-2313); zero occurrences -> regclass 'ST_REGS or none' -> reload1.c:658 alter_reg(i,-1) 8-byte slot in regno order = right after the three param slots (ghost1 reproducer vars=8, no code). The caller-save-area hypothesis (S83 HYPOTHESIS.md) is REFUTED: order_regs_for_reload (reload1.c:3606-3700) picks zero-use regs first so a pseudo homed in $t0 makes $t1 the spill reg (+30 rows); an area needs caller_save_needed (global.c:1085-1091) and a pseudo kept in a call-used reg with save/restore at every live call (caller-save.c:264, 349-470). The only ghost species from a memory value is the SIGN_EXTEND narrow-load split (combine.c:1887-1930) whose signature IS lh; a jump-target second promotion is folded by cse follow-jumps (n0a/b/c: vars 56, +86 rows); a fall-through one needs a register sign_extend MIPS lacks; the generic two-SETs split (combine.c:1963-2020) has no candidate (cse pre-folds constant offsets). Inert: expA/expB, n16 (2 ghosts), n0a/n0b/n0c. 402k tokens, 23 min", "session": "491895ad"}
{"fn": "func_800CF3E8", "binary": "md_MAIN_003", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_800CF3E8.c", "note": "27 -> MATCH 469/469; three passes each owned one defect: (1) sched1 birthing boost on the tag load (sched.c:2507/2469) killed with a SECOND LIVE SET of the loaded variable `tag6 = *(u32*)p6; ... tag6 &= 0xFF000000;` (reg_n_sets=2, zero bytes); (2) the S83 +1 nop was the phantom `__asm__(\"\" :: \"r\"(ot))` USE filling the load-delay slot in sched2's model only — removed, plus the fence after the tpage store removed so `lui m24` reaches slot 378 via its $a2 anti-dep; (3) local-alloc qty_compare had mhi out-ranking m24 for $a2 — spelling prims 5..1's OT link as libgpu's P_TAG bitfield adds store_fixed_bit_field's redundant 0xFFFFFF re-mask (folded by combine, counted by flow: m24 13 -> 18 refs) so m24 wins $a2, mhi -> $t0, tag -> $t2; last 2 rows = p5 x0/y0 in natural source order. Ablations: non-compound tag 89; phantom re-added 70@470; fence re-added 8; manual masks on all six prims 74. Coordinator rtu MATCH 469/469; bank.sh byte-identical", "session": "491895ad"}
{"fn": "func_800CD92C", "binary": "md_MAIN_009", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_800CD92C.c", "note": "MATCH 247/247, ZERO register pins. (1) m24 takes $t1 by REF COUNT: local-alloc qty_compare uses flow's reg_n_refs (pre-combine, combine.c:56); the libgpu P_TAG bitfield store's must_and re-mask (expmed.c:608) leaves a combine-foldable (and (and ot m24) m24) (combine.c:3140-3170) so m24 keeps 19 refs vs la's 13 -> spelled (ot & m24) & m24, unpinned. (2) tp8D/tp8F float to the top when the TAG LOAD is an in-place multi-set pseudo (bitfield RMW shape t=*p; t&=FF00; t|=v; *p=t): sched1 splits large consts (sched.c:4826) and update_n_sets kills their birthing boost, so they are pri-1 floaters eaten only by the lhu->sll latency stall of each RMW chain; a single-set tag load is boosted and glued to its and, a multi-set one fills those stalls -> local-alloc gives $16..$19 in the target order. Sub-levers: the mask temp v must be a FRESH expression (in-place v&=m24 steals $2); v (OT read) precedes t&=FF00; plain scalar D_800BAE22 (struct/array/cast spellings force one shared la); tag store non-/s *(u32*)p; TU spelling extern u8 *D_800A71D0. Coordinator rtu MATCH 247/247; bank.sh d270f695. 509k tokens, 39 min", "session": "491895ad"}
+7 -8
View File
@@ -2,16 +2,15 @@
> 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:** 9 · by status {'near': 8, 'failed': 1} · by class {'WALL-CANDIDATE': 1, 'WALL-PROVED': 1, 'SCHED': 4, 'REGALLOC': 1, 'FRAME': 1, None: 1}
**Open near-misses:** 8 · by status {'near': 7, 'failed': 1} · by class {'WALL-CANDIDATE': 1, 'WALL-PROVED': 1, 'REGALLOC': 1, 'SCHED': 3, 'FRAME': 1, None: 1}
| # | addr | reach | class | nins | status | closeness | where it stuck | best draft |
|--:|------|------:|-------|-----:|--------|----------:|----------------|------------|
| 1 | func_80032A74 | None | WALL-CANDIDATE | 422 | near | 1 | WALL candidate CONFIRMED in the real TU (S83): 422/422, sole residual idx 244 `lh v0,0x18(s1)` vs target `lhu` — extendhisi2 is a force_not_mem EXPAND (the orphan frame slot is minted only at an lh; §172 producer 3 caller-save area, reload1.c:1445), so lhu loses the 8 frame bytes; ~200 byte-probes + 100-variant retyping sweep (S79) + permuter_ils 8x150s null (S80). Citation current (§172, reload1.c:1445). Draft synced to the TU (typedefs stripped via cdecl.strip_provided_typedefs; D_80064D44/D_8006A970/func_8003F144/func_800316F8 spelled as the TU) | `.run/P32/t4/drafts/func_80032A74_tuclean.c` |
| 2 | func_80011380 | None | WALL-PROVED | 192 | near | 6 | §474 PROVED C-level floor (boot -O0): fold-const.c:882 split_tree merges MULT(MULT(i,2),2); the two escapes each cost one instruction (stupid.c:497 adjacency / expand_decl use-brackets); §388 -O0 colouring oracle. Pinned S79 #8; re-probed S83 in the real TU: DIFF 6 (unchanged) | `.run/m3/opus/func_80011380.c` |
| 3 | func_800CD92C | None | SCHED | 247 | near | 15 | map §S7 prologue WEAVE: the {sw,lui,ori} groups for 0xE100008D/8F land after the 9-insn li block instead of before — the §17 pins reproduce the ALLOCATION but the hoist happens in sched2. Same SPRT family as func_800CD674 (§364 mirror levers applied) | `.run/P32/t3/opus/func_800CD92C.c` |
| 4 | func_80039308 | None | REGALLOC | 518 | near | 17 | sched2 + cross-block regalloc: preheader 49/50 swap, un-spellable addu $a2,$a0,$zero (every p=r form cse-propagated), a temp on $t0 vs $s7, and 11 insns of one alias fact (2nd D_80073140[j] load cannot schedule above the D_800C7D20 store from C; /s unlock costs the address allocation, net 20-24). 34->17 via s16 b4 widening copy + dead-local identity sweep (.run/P32/t3/restored/sweep_func_80039308.py) + $2 pin. permuter_ils --klass REGALLOC 2x150s: no gain | `.run/P32/t3/opus/func_80039308.c` |
| 5 | func_80185810 | None | SCHED | 489 | near | 35 | [permuter] 4 emission windows (see report .run/P32/t3/reports/func_80185810__opus__*.md); exact length, rtu-clean | `.run/P32/t3/opus/func_80185810.c` |
| 6 | func_8017DC80 | None | FRAME | 346 | near | 46 | the historic -33 LENGTH wall CLOSED (GTE macros must be REAL macros — the TU house block; the splat Handwritten tag is wrong): 346/346, exact 0x70 frame + 9 callee-saved. Residual: reload-slot frame + the la $a0 slot; cse1 unifies OT index and n<4 across func_80010A08(8) (§500-D2 zero-byte asm retire) | `.run/P32/t3/opus/func_8017DC80.c` |
| 7 | func_800CF408 | None | SCHED | 178 | near | 49 | [permuter] 3 hunks: two prologue sched2 slots, an mlo/mhi allocno tie, a 3-insn block-2 head hoist. Two LENGTH-bearing pins found (tp $17 shared by 0xE1000087/97 = the 6th callee-saved; ob $10 fixes the $t1/$t2/$t3 rotation, 56->49). §351 family (func_8001212C -O0 / func_8017DD04 -O2 exemplars) | `.run/P32/t3/opus/func_800CF408.c` |
| 8 | func_800CF6D0 | None | SCHED | 249 | near | 137 | sched1 rank_for_schedule last-insn-CLASS tie (every store priority 2, equal refs; QImode stores grouped, loads floated, HImode after — 5 of 6 blocks) + $t1<->$t3 local-alloc swap of the two masks. 249/249 exact length only with tpage-before-len field order (19 swept). Inert at 137: pins on tpage constants/masks, asm re-ties, volatile/memory fences, /s-denial on any store subset, *0x4000 vs <<14, p++ vs p+0x18, / swap. decomp-permuter 122 was semantically wrong (R63) | `.run/P32/t3/opus/func_800CF6D0.c` |
| 9 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | |
| 3 | func_80039308 | None | REGALLOC | 518 | near | 17 | sched2 + cross-block regalloc: preheader 49/50 swap, un-spellable addu $a2,$a0,$zero (every p=r form cse-propagated), a temp on $t0 vs $s7, and 11 insns of one alias fact (2nd D_80073140[j] load cannot schedule above the D_800C7D20 store from C; /s unlock costs the address allocation, net 20-24). 34->17 via s16 b4 widening copy + dead-local identity sweep (.run/P32/t3/restored/sweep_func_80039308.py) + $2 pin. permuter_ils --klass REGALLOC 2x150s: no gain | `.run/P32/t3/opus/func_80039308.c` |
| 4 | func_80185810 | None | SCHED | 489 | near | 35 | [permuter] 4 emission windows (see report .run/P32/t3/reports/func_80185810__opus__*.md); exact length, rtu-clean | `.run/P32/t3/opus/func_80185810.c` |
| 5 | func_8017DC80 | None | FRAME | 346 | near | 46 | the historic -33 LENGTH wall CLOSED (GTE macros must be REAL macros — the TU house block; the splat Handwritten tag is wrong): 346/346, exact 0x70 frame + 9 callee-saved. Residual: reload-slot frame + the la $a0 slot; cse1 unifies OT index and n<4 across func_80010A08(8) (§500-D2 zero-byte asm retire) | `.run/P32/t3/opus/func_8017DC80.c` |
| 6 | func_800CF408 | None | SCHED | 178 | near | 49 | [permuter] 3 hunks: two prologue sched2 slots, an mlo/mhi allocno tie, a 3-insn block-2 head hoist. Two LENGTH-bearing pins found (tp $17 shared by 0xE1000087/97 = the 6th callee-saved; ob $10 fixes the $t1/$t2/$t3 rotation, 56->49). §351 family (func_8001212C -O0 / func_8017DD04 -O2 exemplars) | `.run/P32/t3/opus/func_800CF408.c` |
| 7 | func_800CF6D0 | None | SCHED | 249 | near | 137 | sched1 rank_for_schedule last-insn-CLASS tie (every store priority 2, equal refs; QImode stores grouped, loads floated, HImode after — 5 of 6 blocks) + $t1<->$t3 local-alloc swap of the two masks. 249/249 exact length only with tpage-before-len field order (19 swept). Inert at 137: pins on tpage constants/masks, asm re-ties, volatile/memory fences, /s-denial on any store subset, *0x4000 vs <<14, p++ vs p+0x18, / swap. decomp-permuter 122 was semantically wrong (R63) | `.run/P32/t3/opus/func_800CF6D0.c` |
| 8 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | |