From e91859fb4a46897ba0dc20baaffe4f9c1cd00b74 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Tue, 30 Jun 2026 00:57:11 -0600 Subject: [PATCH] =?UTF-8?q?feat(phase-23):=20grinder=20per-binary=20fix=20?= =?UTF-8?q?(5-layer)=20=E2=80=94=20unlock=20non-077=20near-miss=20grinding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The grinder/backlog pipeline was ov_SC01_077-hardcoded 5 layers deep (same class as the T7 lora_grind bug). Fixed all so the permuter grinder can process a non-077 near-miss: 1. gate_stage.append_record stores the source "binary" 2. backlog.FIELDS keeps it (else append_record dropped it) 3. backlog.load_best/_open_stubs is fleet-aware: a fn matched in ov_SC01_077 but propagation-stuck stays OPEN in its overlay, so it surfaces via that record instead of being dropped as "matched" (the grinder must SEE it to grind it) 4. p16_permute.setup takes the target binary's asm-subdir (was hardcoded 077) 5. grinder resolves per-binary asm + gates grouped by binary + allows unknown nins Backward-compatible: legacy records (no binary) default ov_SC01_077. Validated end-to-end: the 3 fresh reach-134 close=1 ov_SC01_000 fns now surface, resolve to ov_SC01_000's asm, and gate via ov_SC01_000. TWO byte-evidenced findings (redirect the fuel strategy): - the reach>=2 close=1 fuel is MODEL semantic-misses, not permuter fuel: func_8012E27C's target is "return 1" but the 7B drafted an empty "void f(void){}" (corpus overfit empty-leaf); func_8012BF4C/AD64 are trivial sw/sh setters drafted empty. A corrected draft banks them (+3 byte-identical via the fixed gate, @commit:0326); the permuter cannot add a missing return/store. Lever = corpus-v3 leaf variety, not the permuter. - x reach is propagation-capped: the 3 are inline-matched in ov_SC01_077_a.c (the stuck- local cap) -> dedup_propagate "nothing to propagate" -> banked x1. Lever = dedup-collapse. check-all 136/136 throughout. docs/gen2-mips-matching-model.md + CURRENT_PHASE updated. --- docs/backlog.md | 353 ++++++++++++++++--------------- docs/gen2-mips-matching-model.md | 30 +++ docs/progress.fleet.md | 8 +- phase-ends/CURRENT_PHASE.md | 3 +- tools/backlog.py | 31 ++- tools/gate_stage.py | 2 +- tools/grinder.py | 38 +++- tools/p16_permute.py | 4 +- 8 files changed, 265 insertions(+), 204 deletions(-) diff --git a/docs/backlog.md b/docs/backlog.md index a6a470632..1e33c59e7 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -2,7 +2,7 @@ > 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:** 293 · by status {'near': 218, 'failed': 75} · by class {'WAVE': 20, 'plumbing': 42, 'other': 23, 'STUB': 2, 'schedule': 61, 'loose-typing': 7, 'struct': 61, 'regalloc-order': 58, 'remat': 4, 'iv-combine': 3, 'GIANT': 8, 'STRUCT': 3, 'PINS': 1} +**Open near-misses:** 296 · by status {'near': 220, 'failed': 76} · by class {'WAVE': 21, 'plumbing': 42, 'other': 23, 'STUB': 2, 'schedule': 61, 'loose-typing': 7, 'struct': 61, 'regalloc-order': 58, 'remat': 4, 'iv-combine': 3, 'GIANT': 8, 'STRUCT': 3, None: 2, 'PINS': 1} | # | addr | reach | class | nins | status | closeness | where it stuck | best draft | |--:|------|------:|-------|-----:|--------|----------:|----------------|------------| @@ -125,177 +125,180 @@ | 117 | func_801372B0 | 134 | schedule | 207 | near | 173 | STRUCTURALLY CRACKED from raw Ghidra-C (xHigh, Phase 22): 3D-gizmo/compass HUD drawer — SVEC in@0x10/out@0x18 + GsLINE prim@0x20; 4 axis unit-vectors -> ApplyMatrixSV(D_800AF630+0x18) -> GsSortLine(D_800A6518[D_800B9A02*0x14]) + func_80137030/178. Logic 100% (206/207 ins). Residual = giant scheduler/regalloc last-mile (10 held callee-saved regs; §17 pins place them but gcc list-scheduler orders prologue-saves+materializations differently -> pervasive positional diff). NOT C-steerable to byte-exact; too far for grinder (173>30). Future: focused permuter or accept as ceiling. Draft has the right types/decls/logic + pins as a head-start. | `.run/backlog_drafts/func_801372B0.c` | | 118 | func_80132784 | 134 | regalloc-order | 400 | near | 240 | 240/400 — prologue+frame+Blk16+both GTE pipelines match through idx114; residual is else-branch pu pointer ($s0) regalloc + GTE-section stack-ptr ($s0-$s5 sp+0x60/0x80/0xA0/0x82/0x84/0x94) allocation (pins hoist them; unpinned picks wrong regs) cascading the tail | `.run/backlog_drafts/func_80132784.c` | | 119 | func_80174650 | 134 | STUB | 9 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80174650.c` | -| 120 | func_8016B91C | 134 | WAVE | 18 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8016B91C.c` | -| 121 | func_80156600 | 134 | other | 18 | failed | | none — MATCH (simple counted scan, do-while form per Ghidra-C) | `.run/backlog_drafts/func_80156600.c` | -| 122 | func_801718AC | 134 | WAVE | 22 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801718AC.c` | -| 123 | func_80168B70 | 134 | WAVE | 27 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80168B70.c` | -| 124 | func_8016BA68 | 134 | plumbing | 29 | failed | | none — MATCH (29 ins, straight-line; lh narrow loads at call site) | `.run/backlog_drafts/func_8016BA68.c` | -| 125 | func_801494CC | 134 | WAVE | 30 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801494CC.c` | -| 126 | func_801708B0 | 134 | WAVE | 30 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801708B0.c` | -| 127 | func_80170CF0 | 134 | schedule | 30 | failed | | 4-ins PROLOGUE-ORDER residual (body insns 4-29 byte-identical). My cc1 hoists the funcptr lui/lw ABOVE the frame setup (lui,lw,addiu sp,sw s0); target keeps frame setup first (addiu sp,sw s0,lui,lw). Same prologue-order class as func_80177F84 (cookbook L1332) — no C lever found (intermediate var/cast/void*-vs-funcptr/pin/early-ptr all reproduce the hoist; barriers/empty-asm/volatile-local regress). KEY WIN: `case 0: break;` forces emit_case_nodes' slti<2;bnez→default lower-bound prune, exactly matching the target dispatch tree (a bare 2-case switch omits it). | `.run/backlog_drafts/func_80170CF0.c` | -| 128 | func_80149450 | 134 | WAVE | 31 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80149450.c` | -| 129 | func_80149F2C | 134 | WAVE | 31 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80149F2C.c` | -| 130 | func_80161A90 | 134 | other | 34 | failed | | none — MATCH (34 ins) at the overlay's STANDARD -O2 (match_one reports MATCH). NO -O1 split needed. | `.run/backlog_drafts/func_80161A90.c` | -| 131 | func_80152C80 | 134 | plumbing | 41 | failed | | none — MATCH expected (linear call/store sequence, no regalloc tension) | `.run/backlog_drafts/func_80152C80.c` | -| 132 | func_80173BC0 | 134 | plumbing | 41 | failed | | none — MATCH. Keys: invert mask branch (else-block = 80174650 path so func_8013E588 | `.run/backlog_drafts/func_80173BC0.c` | -| 133 | func_80130A18 | 134 | struct | 43 | failed | | none — MATCH (two separate Vec3s locals give the 8-byte-spaced sp+0x10/sp+0x18 blocks) | `.run/backlog_drafts/func_80130A18.c` | -| 134 | func_8014C1C8 | 134 | regalloc-order | 44 | failed | | none — MATCH (match_one 44/44 ins, relocation-masked) | `.run/backlog_drafts/func_8014C1C8.c` | -| 135 | func_80146750 | 134 | regalloc-order | 47 | failed | | none — MATCH (match_one 47/47; psVar4->$a3 / psVar3->$v1 pins forced the init order) | `.run/backlog_drafts/func_80146750.c` | -| 136 | func_8014680C | 134 | struct | 47 | failed | | none — MATCH (47 ins, relocation-masked) | `.run/backlog_drafts/func_8014680C.c` | -| 137 | func_8014C4AC | 134 | other | 47 | failed | | none — MATCH (shared-ret0 goto §16 flips final branch polarity + schedules ret=0 into delay slot; memcpy(t0+0x7C,a3,8) inlines the lwl/lwr/swl/swr 8-byte block §21; param_1 = unsigned short* for the lhu reads) | `.run/backlog_drafts/func_8014C4AC.c` | -| 138 | func_80151B98 | 134 | regalloc-order | 47 | failed | | none — MATCH | `.run/backlog_drafts/func_80151B98.c` | -| 139 | func_80147F78 | 134 | schedule | 48 | failed | | TWO residuals remain. (1) FRAME: target frame is 0x60 = exactly 64 bytes (16 words) of LIVE local vars on top of the 4 saved regs (s0,s1,s2,ra) + 0x10 arg area; my body has no locals so frame is 0x20. Reproducing 64B of live local needs an address-escaped local buffer, but the target has only the 3 visible jals (no 4th call to receive &buf), so I cannot make a 16-word local survive -O2 dead-store-elim without emitting an extra instruction. (2) RELOAD SCHEDULE: target reloads D_80127090/94/98 from memory (folded lui%hi;lw%lo) with the FIRST reload HOISTED up between store90 and store94 (free non-volatile scheduling); a "memory" clobber barrier (below) forces the folded reloads but pins them strictly AFTER all three stores. The natural source is almost certainly a 16-word local buffer that ALIASES the globals (non-volatile reloads, freely scheduled) — same construct that also explains the 0x60 frame. Closest faithful body kept below; folded reload bytes are correct, frame + hoist are the gap. | `.run/backlog_drafts/func_80147F78.c` | -| 140 | func_80151C54 | 134 | plumbing | 52 | failed | | none — MATCH (52 ins). Branch-polarity §3-T4: BD60 arm is fall-through (if !=1 && ==0x11), BC44 is else. | `.run/backlog_drafts/func_80151C54.c` | -| 141 | func_8017129C | 134 | struct | 58 | failed | | none — MATCH (58 ins); three aligned 16-byte block-copies via struct assignment (cookbook §21) | `.run/backlog_drafts/func_8017129C.c` | -| 142 | func_80173A60 | 134 | regalloc-order | 59 | failed | | none — MATCH (59 ins) | `.run/backlog_drafts/func_80173A60.c` | -| 143 | func_80130650 | 134 | plumbing | 60 | failed | | none — MATCH (60 ins). ((void (*)(void))func_801319E0)() called with NO arg in the >=0x10 branch (target jal+nop, no a0 setup) → no-proto extern (K&R), promotion-safe vs canonical void ((void (*)(void))func_801319E0)(s32). func_8012CBF4 returns s32 here vs canonical void → cast_call_sites handles it. | `.run/backlog_drafts/func_80130650.c` | -| 144 | func_8014A738 | 134 | regalloc-order | 62 | failed | | none — MATCH | `.run/backlog_drafts/func_8014A738.c` | -| 145 | func_80175308 | 134 | struct | 67 | failed | | none — MATCH (67 ins, relocation-masked) | `.run/backlog_drafts/func_80175308.c` | -| 146 | func_80132F40 | 134 | regalloc-order | 72 | failed | | gcc gives src (sp+0x10) a 5th saved reg ($s3, frame 0x38 not 0x40); target rematerializes | `.run/backlog_drafts/func_80132F40.c` | -| 147 | func_8014D610 | 134 | plumbing | 74 | failed | | none — MATCH (74 ins). for-loop + continue, single IV pointer p; gcc derives the $s0 = p+0x75 second induction var. Template: DEFINE_func_80163950 (sibling, same D_801202A0 loop + func_80135A4C). | `.run/backlog_drafts/func_8014D610.c` | -| 148 | func_80163534 | 134 | schedule | 76 | failed | | mismatch=13, a single 1-position scheduling tie. Instrs 1-30 byte-perfect; all registers correct | `.run/backlog_drafts/func_80163534.c` | -| 149 | func_8014CF04 | 134 | struct | 82 | failed | | none — MATCH (82 ins; array-of-struct scan, for-loop over Ent D_801202A0[96], stride 0x10C) | `.run/backlog_drafts/func_8014CF04.c` | -| 150 | func_80156670 | 134 | schedule | 83 | failed | | none — MATCH (83 ins). Key: hoist `iVar1 = uVar3*4;` as its OWN statement before the if so gcc schedules `sll v1,s1,2` into the bnez delay slot (computed unconditionally) and reuses v1 index-first (`iVar1 + (s32)&D_801150E0` → `addu v0,v1,v0`). 13-arg call to func_80157158 (a0-a3 + 9 stack args at 0x10..0x30); param_2/param_3 cast (u16) → andi; param_6 incoming as lhu(u16). Address args = integer math `iVar2 + (s32)&D_x` (index-first → lui;addiu;addu, index added first). | `.run/backlog_drafts/func_80156670.c` | -| 151 | func_8014D4C0 | 134 | schedule | 84 | failed | | none — MATCH (goto forces if-body out-of-line/last; `>=` fixes slt operand order) | `.run/backlog_drafts/func_8014D4C0.c` | -| 152 | func_8016A73C | 134 | struct | 85 | failed | | none — MATCH (85 ins, relocation-masked) | `.run/backlog_drafts/func_8016A73C.c` | -| 153 | func_80173CB4 | 134 | schedule | 90 | failed | | none — MATCH (switch form keeps cases unmerged; final block: reuse one temp for the D_8012750C test + the func_8013767C result -> $a0 alloc; invert if to !=0 for branch polarity + store order) | `.run/backlog_drafts/func_80173CB4.c` | -| 154 | func_8014C6F4 | 134 | regalloc-order | 91 | failed | | 19-off loop tie-break — target compiles the search as a while/for (pre-guard sltu;beqz present) with the found pointer snapshotted to $v0 split from the IV in $a0 and the +4 sunk into both call-arg delay slots; do-while is instruction-count-exact (91=91) but lacks the pre-guard, while every for/while form costs +4 ins (merge stays in $a0). §10 schedule/regalloc residual. | `.run/backlog_drafts/func_8014C6F4.c` | -| 155 | func_8014D12C | 134 | schedule | 93 | failed | | none — MATCH (93 ins). Block-order lever: success-continuation (return 1) | `.run/backlog_drafts/func_8014D12C.c` | -| 156 | func_801502EC | 134 | schedule | 93 | failed | | none — MATCH (93 ins). 8-byte block copy via alignment-1 struct (Blk8{u8 b[8]}) assignment reproduces the lwl/lwr/swl/swr; ret=0 hoisted before the block copy to fix the s3-vs-ra prologue save order. | `.run/backlog_drafts/func_801502EC.c` | -| 157 | func_80150170 | 134 | struct | 95 | failed | | none — MATCH (95/95). Keys: (1) two parallel 3-halfword groups via chained assign `sp10.x = sp18.x = v` (sp18 inner so 0x18 stores first); (2) align-1 blk8 struct copy for the lwl/lwr/swl/swr 8-byte copy into actor+0x80 (src = sp buf from func_801502EC, or u8[] D_801152A8); (3) f0/f2 = u16 (lhu), f1 = s16 (lh for the slt); (4) `(iVar5/iVar6)!=0` single-OR test + branch-polarity invert (not-both-zero is fall-through); (5) both-zero tail register pins: 0x7fff -> $v1 (`register s32 __asm__("$3")`), sp10.f0/f2 -> reused $a0 (`register u32 __asm__("$4")` written twice) to force gcc's hoist-load + reg reuse schedule. | `.run/backlog_drafts/func_80150170.c` | -| 158 | func_8014CD80 | 134 | regalloc-order | 97 | failed | | none — MATCH (97 ins). iVar3 pinned to $v1 (register __asm__("$3")) so | `.run/backlog_drafts/func_8014CD80.c` | -| 159 | func_8014E284 | 134 | WAVE | 108 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8014E284.c` | -| 160 | func_80167540 | 134 | WAVE | 117 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80167540.c` | -| 161 | func_8014F4C0 | 134 | WAVE | 141 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8014F4C0.c` | -| 162 | func_8014E048 | 134 | WAVE | 143 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8014E048.c` | -| 163 | func_80155800 | 134 | WAVE | 145 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80155800.c` | -| 164 | func_80138ED0 | 134 | GIANT | 159 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 165 | func_8012EC04 | 134 | GIANT | 178 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 166 | func_801392FC | 134 | GIANT | 182 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 167 | func_8013AF20 | 134 | GIANT | 185 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 168 | func_8012D098 | 134 | GIANT | 189 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 169 | func_80129CF8 | 134 | GIANT | 191 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 170 | func_8013A530 | 134 | GIANT | 204 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 171 | func_801372B0 | 134 | GIANT | 207 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 172 | func_80144B9C | 134 | other | 770 | failed | | -O0 cluster fn (prologue 21F0A003, fp-frame, all locals spilled+reloaded, load-delay nops). match_one compiles -O2 so it CANNOT match this; needs its own per-file -O0 split (Makefile CC1FLAGS:=-O0), like ov_SC01_077_o0.c. Body below is the faithful -O0 source; gate via whole-binary -O0 build only. | `.run/backlog_drafts/func_80144B9C.c` | -| 173 | func_80151944 | 4 | struct | 15 | near | 0 | none — MATCH (fn-pointer table dispatch; array-of-ptr indexing folds %lo) | `.run/backlog_drafts/func_80151944.c` | -| 174 | func_8016039C | 2 | STRUCT | 15 | near | 0 | match_one MATCH but gate rejected (declaration/TU plumbing) | `.run/backlog_drafts/func_8016039C.c` | -| 175 | func_8015DAF8 | 1 | struct | 15 | near | 0 | none — MATCH (proxy); identical idiom to matched func_8016901C in same overlay | `.run/backlog_drafts/func_8015DAF8.c` | -| 176 | func_8015FAAC | 1 | STRUCT | 15 | near | 0 | match_one MATCH but gate rejected (declaration/TU plumbing) | `.run/backlog_drafts/func_8015FAAC.c` | -| 177 | func_801577C8 | 1 | plumbing | 16 | near | 0 | none — MATCH expected (scalar global store + two sequential calls, param preserved across first call) | `.run/backlog_drafts/func_801577C8.c` | -| 178 | func_80178B70 | 1 | struct | 18 | near | 0 | none — MATCH; local ptr p=&D_8018A458 used for store AND (int)p-0xC arg forces $s0-base reuse across call1, param_1 into $s1 | `.run/backlog_drafts/func_80178B70.c` | -| 179 | func_8013373C | 1 | regalloc-order | 18 | near | 0 | none — MATCH (indexed-global int-array %lo-fold + (short)param*4 fuses sll16/sra14; loaded value pinned to $a0/$4 to reuse the param reg instead of $v0) | `.run/backlog_drafts/func_8013373C.c` | -| 180 | func_8017F240 | 1 | regalloc-order | 20 | near | 0 | none — MATCH (base &D_801270D0 pinned to $s0 holds across call; one lui/addiu reused for load+store) | `.run/backlog_drafts/func_8017F240.c` | -| 181 | func_80157D20 | 1 | plumbing | 21 | near | 0 | none — MATCH expected (call, indexed u16-global load as 2nd arg, then call; param_1 saved across all three calls) | `.run/backlog_drafts/func_80157D20.c` | -| 182 | func_80163408 | 1 | struct | 21 | near | 0 | local 8-byte struct copied from D_801D8BB0, © passed as 5th arg (s32) | `.run/backlog_drafts/func_80163408.c` | -| 183 | func_80175184 | 1 | struct | 21 | near | 0 | none — MATCH (fnptr-array %lo-fold dispatch; idx = *(u16*)(a0+2) < 2 ? D_8018A1A4[idx]() : func_80175268()) | `.run/backlog_drafts/func_80175184.c` | -| 184 | func_8012F8C8 | 1 | plumbing | 21 | near | 0 | none — MATCH (pending verify) | `.run/backlog_drafts/func_8012F8C8.c` | -| 185 | func_8014FBC0 | 1 | schedule | 22 | near | 0 | none — MATCH (22 ins). Stack-switch primitive: register $sp var, manual save/switch/restore around the call. | `.run/backlog_drafts/func_8014FBC0.c` | -| 186 | func_80178B18 | 1 | other | 22 | near | 0 | none — MATCH | `.run/backlog_drafts/func_80178B18.c` | -| 187 | func_8017B8E8 | 1 | plumbing | 22 | near | 0 | none — MATCH (two inlined unaligned 8-byte memcpy blocks: src[0..7]->D_801DA794, src[8..15]->D_801DA78C) | `.run/backlog_drafts/func_8017B8E8.c` | -| 188 | func_80182988 | 1 | plumbing | 22 | near | 0 | none — MATCH (u16 store of 0xAA10 forces ori, not sign-extended addiu) | `.run/backlog_drafts/func_80182988.c` | -| 189 | func_801320D8 | 1 | schedule | 27 | near | 0 | none — MATCH (27 ins, relocation-masked) | `.run/backlog_drafts/func_801320D8.c` | -| 190 | func_80132144 | 1 | other | 27 | near | 0 | none — MATCH | `.run/backlog_drafts/func_80132144.c` | -| 191 | func_801321B0 | 1 | other | 27 | near | 0 | none — MATCH (match_one 27/27, relocation-masked) | `.run/backlog_drafts/func_801321B0.c` | -| 192 | func_8013221C | 1 | other | 27 | near | 0 | none — MATCH (expected); straight scheduling, one call-crossing local -> $s0 naturally | `.run/backlog_drafts/func_8013221C.c` | -| 193 | func_801609B8 | 1 | struct | 28 | near | 0 | none — MATCH (pending byte-gate); function-pointer table %lo-fold via extern array | `.run/backlog_drafts/func_801609B8.c` | -| 194 | func_801312D0 | 1 | struct | 28 | near | 0 | none — MATCH (unaligned 8-byte memcpy from global; if/else branch layout) | `.run/backlog_drafts/func_801312D0.c` | -| 195 | func_80136C90 | 1 | other | 28 | near | 0 | local char[10] string-literal init -> rodata-template block move (lwl/lwr + swl/swr + lb/sb), 9+1 split | `.run/backlog_drafts/func_80136C90.c` | -| 196 | func_8017E224 | 1 | struct | 29 | near | 0 | none — MATCH (unaligned 8-byte memcpy of global onto stack + cond byte incr) | `.run/backlog_drafts/func_8017E224.c` | -| 197 | func_80165140 | 1 | regalloc-order | 30 | near | 0 | none — MATCH (pin i=$v1/eight=$a0/p=$a2; DON'T pin param — let it self-copy to $a3 first; memcpy 8/4 unaligned) | `.run/backlog_drafts/func_80165140.c` | -| 198 | func_801549F8 | 1 | iv-combine | 31 | near | 0 | none — MATCH (31 ins). Re-tie barrier on the index defeats gcc's pointer-giv | `.run/backlog_drafts/func_801549F8.c` | -| 199 | func_8015E698 | 1 | struct | 31 | near | 0 | none — MATCH (clean -O2 reconstruction; table-of-fnptr indexed by param_1[0]) | `.run/backlog_drafts/func_8015E698.c` | -| 200 | func_8017D98C | 1 | plumbing | 31 | near | 0 | none — MATCH (expected): straight global stores + tail call; const 0x140 reused for two halves | `.run/backlog_drafts/func_8017D98C.c` | -| 201 | func_80182268 | 1 | struct | 31 | near | 0 | none — MATCH (jump-table switch over sign-extended high byte of *(u16*)(a0+0x70); case4 decrements D_801270CC then falls into case3/7's func_8012C218; no default) | `.run/backlog_drafts/func_80182268.c` | -| 202 | func_801602A4 | 1 | struct | 34 | near | 0 | none — MATCH (template = matched twin func_801601E4; lhu+0x8000 == compare, fnptr-table dispatch D_801891B8[*(u16*)a0]() no-arg, then 3-call setup in target order; func_80161208 in else) | `.run/backlog_drafts/func_801602A4.c` | -| 203 | func_801734BC | 1 | struct | 34 | near | 0 | none — MATCH (pending byte-gate); switch-jtbl with no default, 3 short stores + fnptr call | `.run/backlog_drafts/func_801734BC.c` | -| 204 | func_8017D900 | 1 | plumbing | 35 | near | 0 | none — expect MATCH (STUB: ordered global stores + single tail call, sibling of func_8017D840) | `.run/backlog_drafts/func_8017D900.c` | -| 205 | func_8016BEA0 | 1 | other | 37 | near | 0 | none — MATCH (expected) | `.run/backlog_drafts/func_8016BEA0.c` | -| 206 | func_801754A8 | 1 | regalloc-order | 37 | near | 0 | none — MATCH (37 ins, relocation-masked proxy) | `.run/backlog_drafts/func_801754A8.c` | -| 207 | func_80160920 | 1 | struct | 38 | near | 0 | none — MATCH (function-pointer table folds %lo via extern array indexed by halfword) | `.run/backlog_drafts/func_80160920.c` | -| 208 | func_80183BAC | 1 | struct | 41 | near | 0 | switch jump-table dispatch (jtbl_801D9420); verifying case grouping 0,1,2,5,6/3,7/4 emits the target table + tail | `.run/backlog_drafts/func_80183BAC.c` | -| 209 | func_80183C50 | 1 | struct | 41 | near | 0 | none — MATCH (cross-jump exploit §cookbook L1543: dup func_8012C218 into case3/7 + case4 → merged jal;nop) | `.run/backlog_drafts/func_80183C50.c` | -| 210 | func_8015DF34 | 1 | struct | 44 | near | 0 | none — MATCH (clean structural; fn-ptr table via array index folds %lo) | `.run/backlog_drafts/func_8015DF34.c` | -| 211 | func_8015FE70 | 1 | struct | 44 | near | 0 | none — MATCH expected (fn-ptr-table dispatch + ushort struct fields) | `.run/backlog_drafts/func_8015FE70.c` | -| 212 | func_8014358C | 1 | regalloc-order | 45 | near | 0 | none — MATCH (relocation-masked match_one) | `.run/backlog_drafts/func_8014358C.c` | -| 213 | func_80183AF0 | 1 | regalloc-order | 47 | near | 0 | none — MATCH (mask pinned $a1/$5 + p pinned $v0/$2; switch w/ distributed func_8012C218 tail via dup calls + cross-jump merge) | `.run/backlog_drafts/func_80183AF0.c` | -| 214 | func_80178BF8 | 1 | plumbing | 49 | near | 0 | none — MATCH (pure scalar-store + two pointer-decrement do-while loops) | `.run/backlog_drafts/func_80178BF8.c` | -| 215 | func_8015E344 | 1 | struct | 50 | near | 0 | none — MATCH (pending whole-binary gate); fn-ptr table folds %lo via extern array, 0x234 single word store | `.run/backlog_drafts/func_8015E344.c` | -| 216 | func_8017EC7C | 1 | struct | 52 | near | 0 | none — MATCH (52 ins, relocation-masked) | `.run/backlog_drafts/func_8017EC7C.c` | -| 217 | func_80183CF4 | 1 | struct | 57 | near | 0 | none — MATCH (clean switch + jtbl; orchestrator owns jtbl/rodata migration) | `.run/backlog_drafts/func_80183CF4.c` | -| 218 | func_8015D01C | 1 | regalloc-order | 58 | near | 0 | none — MATCH | `.run/backlog_drafts/func_8015D01C.c` | -| 219 | func_8016D688 | 1 | struct | 60 | near | 0 | none — MATCH (byte array D_801D9C20[] folds the &D_801D9C21 base/-1 offsets; emit p+0xE store BEFORE the param+2 increment so the lhu fills the load-delay slot in $v1) | `.run/backlog_drafts/func_8016D688.c` | -| 220 | func_801842C8 | 1 | plumbing | 62 | near | 0 | none — MATCH | `.run/backlog_drafts/func_801842C8.c` | -| 221 | func_80165240 | 1 | regalloc-order | 63 | near | 0 | none — MATCH (63 ins). buf pinned to $s2 (register __asm__("$18")) so it stays in a callee-saved reg; param_3 then naturally lands in $s3. memcpy(buf+0x30,param_3,4) -> lwl/lwr+swl/swr unaligned 4B copy (cookbook §1 mem->mem). array-of-u8 buf with explicit *(T*)(buf+off) stores; mtx[0x20] declared 2nd so it lands at sp+0x50, buf_ at sp+0x10. | `.run/backlog_drafts/func_80165240.c` | -| 222 | func_8017BB34 | 1 | struct | 65 | near | 0 | none — MATCH (65 ins). Keys: (1) align-1 {s8 b[8]} struct so the two 8-byte copies emit lwl/lwr; (2) stack-local declaration order = target frame order (svin@0x10, buf@0x18, out@0x38, local8@0x40, rt_in@0x48, rt_out@0x50) — reordering the locals to ascending offset fixed all 23 offset-only diffs. | `.run/backlog_drafts/func_8017BB34.c` | -| 223 | func_8016BD78 | 1 | regalloc-order | 74 | near | 0 | none — MATCH (lazy pointer locals pa=&BC4, pb=&BC8 assigned at first use → $a1/$a2 held thru middle code as final call args; middle bytes BC5/BC6/BC9/BCA direct global) | `.run/backlog_drafts/func_8016BD78.c` | -| 224 | func_8016E7C8 | 1 | regalloc-order | 74 | near | 0 | none — MATCH (match_one 74/74; pins $18=&prim, $19=param_3 fixed s2/s3 alloc order; Work struct sized to 0x20) | `.run/backlog_drafts/func_8016E7C8.c` | -| 225 | func_8018281C | 1 | struct | 76 | near | 0 | none — MATCH (76 ins). jtbl forced via explicit case 4/6 (count>=5 over MIPS tablejump threshold); case-5 block placed between if-block and default via goto so the if-block emits j default w/ e2=0 in the delay slot | `.run/backlog_drafts/func_8018281C.c` | -| 226 | func_8016AE5C | 1 | regalloc-order | 85 | near | 0 | none — MATCH (85 ins, match_one). switch/jtbl STRUCT fn. The tail's | `.run/backlog_drafts/func_8016AE5C.c` | -| 227 | func_80182E7C | 1 | struct | 85 | near | 0 | none — MATCH (85 ins, relocation-masked). Two switch-codegen levers: | `.run/backlog_drafts/func_80182E7C.c` | -| 228 | func_8015C7E4 | 1 | struct | 88 | near | 0 | none — MATCH (match_one 88/88); fn-ptr-array dispatch, top-level if/else needed branch-polarity invert (small block falls through, big block at L854) | `.run/backlog_drafts/func_8015C7E4.c` | -| 229 | func_8015CA28 | 1 | schedule | 91 | near | 0 | none — MATCH (goto forces the func_80161240 block to the function tail; bnez-to-end layout vs early-return fall-through) | `.run/backlog_drafts/func_8015CA28.c` | -| 230 | func_801820DC | 1 | struct | 94 | near | 0 | none — MATCH (switch on entity state at 0x34, inner jtbl on (s8)(u70>>8)) | `.run/backlog_drafts/func_801820DC.c` | -| 231 | func_80184D50 | 1 | schedule | 98 | near | 0 | none — MATCH (98 ins, relocation-masked) | `.run/backlog_drafts/func_80184D50.c` | -| 232 | func_80161D20 | 1 | struct | 14 | near | 1 | none — MATCH (array-of-u16 %lo-fold, §18) | `.run/backlog_drafts/func_80161D20.c` | -| 233 | func_8017F714 | 1 | plumbing | 27 | near | 1 | none — MATCH (27/27 ins, match_one verified) | `.run/backlog_drafts/func_8017F714.c` | -| 234 | func_80142A10 | 1 | struct | 28 | near | 1 | none — MATCH (pending byte-gate) | `.run/backlog_drafts/func_80142A10.c` | -| 235 | func_80161C24 | 1 | struct | 29 | near | 1 | none — MATCH (array-of-struct %lo-fold; even/odd u16 fields at off 0/2, stride 4) | `.run/backlog_drafts/func_80161C24.c` | -| 236 | func_80184C0C | 1 | struct | 48 | near | 1 | none — MATCH (array-of-struct %lo-fold for &D_8018AEB8[idx], stride 0x34) | `.run/backlog_drafts/func_80184C0C.c` | -| 237 | func_8016B4F8 | 1 | regalloc-order | 50 | near | 1 | none — MATCH | `.run/backlog_drafts/func_8016B4F8.c` | -| 238 | func_801803B0 | 1 | other | 51 | near | 1 | none — MATCH expected; simple if/else, no call-crossing locals beyond param in $s0 | `.run/backlog_drafts/func_801803B0.c` | -| 239 | func_8015FBE0 | 1 | schedule | 58 | near | 1 | none — MATCH | `.run/backlog_drafts/func_8015FBE0.c` | -| 240 | func_8017F114 | 1 | regalloc-order | 75 | near | 1 | none — MATCH | `.run/backlog_drafts/func_8017F114.c` | -| 241 | func_8017F290 | 1 | regalloc-order | 86 | near | 2 | none — MATCH. Two levers: (1) hold &D_801270CC in a `int *state` local so its | `.run/backlog_drafts/func_8017F290.c` | -| 242 | func_8016EC0C | 1 | schedule | 88 | near | 2 | none — MATCH (88 ins). Sparse switch(uVar2) = gcc's beq-pivot+slti comparison | `.run/backlog_drafts/func_8016EC0C.c` | -| 243 | func_80171B4C | 1 | schedule | 70 | near | 3 | 3-off in the tail only (body+prologue MATCH via $s1 pin on arg1). gcc fills the | `.run/backlog_drafts/func_80171B4C.c` | -| 244 | func_80140E6C | 1 | schedule | 37 | near | 4 | 4 ins — each save-across-call copy (move s1,v0 / move s0,v0) should fill the NEXT jal's delay slot (target) but gcc-2.7.2 sched ties the copy with the next call's arg-setup at priority 2 and the LUID tie-break (rank_for_schedule) keeps the copy first, so reorg fills the slot with the arg-setup instead; no C reshape found that flips the LUID/priority order without breaking the OR-chain regalloc. | `.run/backlog_drafts/func_80140E6C.c` | -| 245 | func_8017EF50 | 1 | schedule | 53 | near | 5 | 5 ins — gcc-2.7.2 instr-scheduler load-order tie-breaks. Branch region + cross-jump-break (t14 pin to $3) + 0x34/0x30 hoist (c34 pin $5, c2c pin $3) all MATCH. Residual: (a) header 0x10-load vs 0x2c-load order swap; (b) compare loads 0x36-before-0xA and puts 0xA in $a1 not $a2 (slt operand reg differs). Both clusters resist source steering — every fix to one perturbs the pinned header schedule. | `.run/backlog_drafts/func_8017EF50.c` | -| 246 | func_8014D3E0 | 1 | other | 22 | near | 6 | none — MATCH | `.run/backlog_drafts/func_8014D3E0.c` | -| 247 | func_8013CF68 | 1 | schedule | 63 | near | 6 | blocks 2&3 delay-slot fill — gcc picks dead-reg $v1(b0,0x10/0x20) store for the jal delay slot; target picks arg-reg $a3(0x12/0x22). 6 ins (2 rotations); not flippable by source store-order/interleave/barrier (all tested); permuter/scheduler-internal lever needed. Prologue, $s0 fold, regalloc, block-1 all exact. | `.run/backlog_drafts/func_8013CF68.c` | -| 248 | func_8017B940 | 1 | struct | 63 | near | 6 | none — MATCH | `.run/backlog_drafts/func_8017B940.c` | -| 249 | func_8017B238 | 1 | regalloc-order | 76 | near | 6 | 6 ins — gcc coalesces param_2 into callee-saved $s0 and hoists `move $s0,$a1` | `.run/backlog_drafts/func_8017B238.c` | -| 250 | func_8017B614 | 1 | regalloc-order | 101 | near | 6 | 6 ins — param_2 lands in callee-saved $s0 (entry `move s0,a1`, sltiu/sll read s0) vs target's $a1; gcc prefers s0 (saved anyway for the late p794/p78C copies) over caller-saved $a1. Body+schedule otherwise byte-exact (101/101 ins); the late-part `__asm__("")` barrier is load-bearing (fixes the const-store schedule, 21->6). | `.run/backlog_drafts/func_8017B614.c` | -| 251 | func_801345F8 | 1 | schedule | 106 | near | 7 | 7 ins, all pure scheduling order — maskedp copy not sunk into bnez delay slot | `.run/backlog_drafts/func_801345F8.c` | -| 252 | func_80164E40 | 1 | struct | 25 | near | 8 | none — MATCH expected; byte 0 keeps base $v1 (reused by final lw word), bytes 1/2 standalone | `.run/backlog_drafts/func_80164E40.c` | -| 253 | func_8016E9EC | 1 | schedule | 53 | near | 11 | 11 left — all GNU scheduler/canon tie-breaks (regs all match via pins): (a) prologue hoists `addiu a1,0x1C` into the save block; (b) first lbu reads $a0 not $s1 (incoming-arg still live); (c) iCopy copy `addu s4,s0` lands early (scheduler) vs target's func_800D2CA8 delay-slot; (d) `addu a2,s2,s3` vs target `s3,s2` commutative-canon (unflippable w/o breaking load order). Permuter can't run (register __asm__ pins rejected, cookbook §5a). | `.run/backlog_drafts/func_8016E9EC.c` | -| 254 | func_80156044 | 1 | struct | 74 | near | 12 | none — MATCH (74 ins, relocation-masked); $s2-pin for u16-return + def-mask + 3-arg cast on func_80156848 | `.run/backlog_drafts/func_80156044.c` | -| 255 | func_80161CD0 | 1 | regalloc-order | 20 | near | 14 | param_2 must survive the call in $s0; try plain C first then pin to $16 | `.run/backlog_drafts/func_80161CD0.c` | -| 256 | func_80158FA4 | 1 | schedule | 51 | near | 17 | target keeps a DEAD `sra $a1,$v0,16` before `beqz $a1` (sign-extend of func_80159464's | `.run/backlog_drafts/func_80158FA4.c` | -| 257 | func_80182338 | 1 | PINS | 26 | near | 24 | PINS: 24 mismatch | `.run/backlog_drafts/func_80182338.c` | -| 258 | func_8018301C | 1 | plumbing | 28 | near | 24 | none — MATCH (straight-line, statement-order; verify with match_one) | `.run/backlog_drafts/func_8018301C.c` | -| 259 | func_8016BBE0 | 1 | other | 56 | near | 24 | none — straightforward; expect MATCH (mirror Ghidra-C order, synth_mult ×0x555) | `.run/backlog_drafts/func_8016BBE0.c` | -| 260 | func_8016E95C | 1 | regalloc-order | 36 | near | 25 | none — MATCH (pending byte-gate) | `.run/backlog_drafts/func_8016E95C.c` | -| 261 | func_80139BE0 | 1 | loose-typing | 39 | near | 32 | target has redundant andi a1,v0,0xff (uchar zero-extend) gcc proves away; else identical | `.run/backlog_drafts/func_80139BE0.c` | -| 262 | func_80148E54 | 1 | regalloc-order | 67 | near | 40 | 67/67 ins, structure+branches+block-order+body-reload all match; residual is pure register-allocation order (permuter-eligible, no register-pins). (1) masked first-angle folds andi->$s1; target keeps it in $a0 then copies addu $s1,$a0 lazily into the beq delay-slot (the s1-copy schedules 1 slot later). (2) the 0x80 const is CSE-held in $a2 across both test+body; target re-materializes 0x80 in $v0 per block (it gets clobbered by `srl v0,v1,8`), which both renames the compare regs ($v0 not $a2) AND fills the body's reload load-delay slot (mine emits a nop there). (3) single-exit ret funnels $v1->$v0 (move v0,v1) where target writes $v0 directly. All three are gcc regalloc/value-prop tie-breaks no C reshape steered (tried: $v0 pin, temp-split, low-mask-reuse compare, memory-clobber-vs-volatile reload) — leave for the permuter. | `.run/backlog_drafts/func_80148E54.c` | -| 263 | func_8017B0E4 | 1 | other | 61 | near | 51 | none — MATCH (expected; clean six-call sign-extend-store pattern) | `.run/backlog_drafts/func_8017B0E4.c` | -| 264 | func_80166F58 | 1 | schedule | 69 | near | 55 | regs/loop/logic/%lo-fold all match (pinned $s0-$s6); residual is reorg.c delay-slot fill — target replicates `addiu $v0,$s2,1` into the 3 skip-branch delay slots + commits `addu $s2,$v0,0` at merge (my codegen emits in-place `addiu $s2,$s2,1` w/ nop slots, -1 ins); plus prologue short-arg promote-then-move not fusing (`sra $a1;addu $s4,$a1,0` vs my fused `sra $s4,$a1`). Not source-steerable (pins block permuter). | `.run/backlog_drafts/func_80166F58.c` | -| 265 | func_80177DA8 | 1 | remat | 63 | near | 58 | gcc narrows `&0xfffffeff` on a 16-bit (lhu) value to `andi 0xfeff` (inline), but target hoisted -0x101 into $t4 (and-reg) in the loop preheader — a gcc-2.7.2 LICM-before-combine pass-ordering quirk unsteerable from C; that 1-ins gap cascades the constant-reg numbering + tail reassoc. Secondary: single-IV loop ptr anchors at +0xA (short, 2 accesses) not +0xC (byte) like target. | `.run/backlog_drafts/func_80177DA8.c` | -| 266 | func_80141A60 | 1 | other | 76 | near | 63 | none — MATCH (76 ins, relocation-masked). Body byte-identical; target reserves an 8-byte | `.run/backlog_drafts/func_80141A60.c` | -| 267 | func_801457A4 | 1 | other | 79 | near | 74 | MATCH at -O0 (79 ins, reloc-masked, real -O0 flags). BANKING BLOCKER: this -O0 fn lives in the -O2 main ov_SC01_077.c; needs its own §18 -O0 split at 0x801457A4 (existing _o0.c covers 0x8013B568..0x8013C98C only). match_one is -O2 -> WRONG here. | `.run/backlog_drafts/func_801457A4.c` | -| 268 | func_8016B6BC | 1 | schedule | 94 | near | 80 | 12-off, all in the last 12 ins (tail). First 82 ins byte-match. Target materializes | `.run/backlog_drafts/func_8016B6BC.c` | -| 269 | func_80134A74 | 1 | regalloc-order | 107 | near | 84 | structure + all 8 callee-saved regs (s0..s7) + block layout MATCH; residual is caller-saved-temp | `.run/backlog_drafts/func_80134A74.c` | -| 270 | func_8013EE10 | 1 | struct | 94 | near | 86 | none — MATCH (94 ins). array-of-struct %lo-fold (E[]) for the 5-elt loops; | `.run/backlog_drafts/func_8013EE10.c` | -| 271 | func_80185E68 | 1 | STRUCT | 132 | near | 131 | STRUCT: 131 mismatch | `.run/backlog_drafts/func_80185E68.c` | -| 272 | func_801824D0 | 1 | WAVE | 181 | near | 180 | WAVE: 180 mismatch | `.run/backlog_drafts/func_801824D0.c` | -| 273 | func_80184A68 | 1 | regalloc-order | 33 | failed | | none — MATCH | `.run/backlog_drafts/func_80184A68.c` | -| 274 | func_8015E018 | 1 | loose-typing | 47 | failed | | none — MATCH (signed char forces lbu+sll24/sra24 sign-extend; default char is unsigned in this toolchain) | `.run/backlog_drafts/func_8015E018.c` | -| 275 | func_80159A20 | 1 | struct | 58 | failed | | none — MATCH. Key lever: block tail-MERGE (gcc shared `bne ...,$L1` cross-jump) by making the two return-tests STRUCTURALLY DIFFERENT — positive `if(==){goto mask;} return;` per branch (not `if(!=) return;`), so neither tail can merge. Then fix block ORDER by inverting the outer test (`if(d!=1)` makes the ==4/return path the inline fall-through, the d==1/p[2] path the forward `beq`-target block — matching the target layout). | `.run/backlog_drafts/func_80159A20.c` | -| 276 | func_8013E958 | 1 | schedule | 63 | failed | | 2 ins swapped — cc1 emits `andi 0x7f; andi 0xff; beqz`(tests doubly-masked) but target wants `andi 0x7f; beqz; andi 0xff`(andi 0xff in the first beqz delay slot). Loop fully byte-matches; struct/ptr fold idioms nailed (D_80115110.q[0x16] hoists base+0x58 disp, Cell D_80115188[i].v folds %lo). func_800D0488 takes (m&0xFF) arg. s16 m -> 2 mism (right ins count); s32 m fixes order but merges andi+arg-move (62 ins, 1 short). | `.run/backlog_drafts/func_8013E958.c` | -| 277 | func_8013E83C | 1 | plumbing | 71 | failed | | none — MATCH (scalar global stores + 2 conditional calls; §3-T4 branch-polarity invert on the &0xFF test) | `.run/backlog_drafts/func_8013E83C.c` | -| 278 | func_8017B368 | 1 | schedule | 74 | failed | | dead table-path off by 1 ins — target keeps src*16 live in $s0 & computes 2nd arg src16+(base+8) in call1 delay slot; every C form either folds to e+8 (73 ins) or CSEs base into an extra saved reg $s2 (75 ins). All live code (prologue, sltiu dispatch, copy path, 4 struct-copy stores, tail) matches; only the unreachable func_8012F214 path scheduling diverges. | `.run/backlog_drafts/func_8017B368.c` | -| 279 | func_80180B64 | 1 | struct | 75 | failed | | none — MATCH (75 ins, relocation-masked) | `.run/backlog_drafts/func_80180B64.c` | -| 280 | func_80180F10 | 1 | schedule | 75 | failed | | none — MATCH (aggregate-initializer form schedules const setup after the prologue saves) | `.run/backlog_drafts/func_80180F10.c` | -| 281 | func_8016C188 | 1 | schedule | 79 | failed | | none — MATCH (79 ins, match_one). Levers: invert if to if(iVar1!=0){big}else{small} | `.run/backlog_drafts/func_8016C188.c` | -| 282 | func_80164930 | 1 | regalloc-order | 81 | failed | | none — MATCH (81 ins, relocation-masked) | `.run/backlog_drafts/func_80164930.c` | -| 283 | func_801418F8 | 1 | loose-typing | 90 | failed | | none — MATCH (90 ins). Keys: D_8011511A is `volatile u16` (store-2-then-read must NOT const-fold), read ONCE into a `u16` local t (an `unsigned int` local adds a stray andi 0xffff; reusing t feeds the single lhu to both sltiu and t-3), and the lone D_80115158 store after the if yields the delay-slot-fill-from-target dup of `addiu 0x106`. | `.run/backlog_drafts/func_801418F8.c` | -| 284 | func_801789AC | 1 | struct | 91 | failed | | none — MATCH (91 ins, relocation-masked) | `.run/backlog_drafts/func_801789AC.c` | -| 285 | func_80183DE0 | 1 | regalloc-order | 91 | failed | | testing if(!=1) layout + counter-before-pointer init order | `.run/backlog_drafts/func_80183DE0.c` | -| 286 | func_80185428 | 1 | struct | 94 | failed | | none — MATCH (94 ins, relocation-masked) | `.run/backlog_drafts/func_80185428.c` | -| 287 | func_801506A4 | 1 | loose-typing | 95 | failed | | none — MATCH (95 ins). switch var must be int not u16 (u16 adds andi 0xffff promotion mask) | `.run/backlog_drafts/func_801506A4.c` | -| 288 | func_8016BFD0 | 1 | struct | 95 | failed | | none — MATCH (95 ins). memcpy(d,s,4) -> lwl/lwr/swl/swr; MATRIX work buf as s32[16] (0x40, fills 0x10-0x4f, t[] = buf[5..7]); two SVECTOR locals at 0x50/0x58; natural saved-reg order s0=param_5/s1=param_4/s2=iVar5 | `.run/backlog_drafts/func_8016BFD0.c` | -| 289 | func_801596F0 | 1 | struct | 97 | failed | | none — MATCH (97 ins). Loop 1 = struct-ptr for-loop (E38, flag@+4) -> -4 guard / +4 test via gcc biv-elim. Loop 2 needed an EXPLICIT if-guard + do-while with the FIELD pointer as the loop var (so the giv init emits FIRST in the preheader, before the &D invariant block), a non-volatile re-tie barrier on d=&D_800AFAE8 (keeps &D BARE so +4/+0x88 add off it = +1 ins vs the folded %lo, matching target), an explicit u32 mask hoisted first (fills the guard's delay slot), and a separate range check fp=d+0x88. | `.run/backlog_drafts/func_801596F0.c` | -| 290 | func_8017B490 | 1 | schedule | 97 | failed | | none — MATCH (97 ins). Keys: (1) inverted if so the SV4 block-copy else is fallthrough and block A is bnez-far (cond = (u32)&D_801DA73C >= 0xB, a relocated-symbol compare gcc can't fold); (2) SV4{s16 a,b,c,d} align-2 8-byte copy -> lwl/lwr/swl/swr, locals at sp+0x10/0x18; (3) the DEAD block-A index = (s32)&D_801DA73C into D_8018A45C[] (WAVE16=two SV4) needs BOTH source addrs (&[idx].v0,&[idx].v1) in EXPLICIT TEMPS before call1 so base (&D_8018A45C) dies pre-call -> temp $v0 (not callee-saved), forcing the natural 2-reg alloc idx=$s0/param_1=$s1 + src2 into call1's delay slot; (4) tail: D_801DA794/D_801DA78C are SV4, re-read .a/.b/.c via lh sign-extended to s32 stores. | `.run/backlog_drafts/func_8017B490.c` | -| 291 | func_80182C9C | 1 | schedule | 101 | failed | | none — MATCH (101 ins). Inner-switch break-to-shared-tail must be written as | `.run/backlog_drafts/func_80182C9C.c` | -| 292 | func_80183FB8 | 1 | loose-typing | 101 | failed | | none — MATCH (relocation-masked match_one, 101/101 ins) | `.run/backlog_drafts/func_80183FB8.c` | -| 293 | func_8013EF88 | 1 | struct | 108 | failed | | none — MATCH (108 ins). Keys: (1) §18 array-of-struct E4{s32 v} for | `.run/backlog_drafts/func_8013EF88.c` | +| 120 | func_801705C0 | 134 | WAVE | 14 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801705C0.c` | +| 121 | func_8016B91C | 134 | WAVE | 18 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8016B91C.c` | +| 122 | func_80156600 | 134 | other | 18 | failed | | none — MATCH (simple counted scan, do-while form per Ghidra-C) | `.run/backlog_drafts/func_80156600.c` | +| 123 | func_801718AC | 134 | WAVE | 22 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801718AC.c` | +| 124 | func_80168B70 | 134 | WAVE | 27 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80168B70.c` | +| 125 | func_8016BA68 | 134 | plumbing | 29 | failed | | none — MATCH (29 ins, straight-line; lh narrow loads at call site) | `.run/backlog_drafts/func_8016BA68.c` | +| 126 | func_801494CC | 134 | WAVE | 30 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801494CC.c` | +| 127 | func_801708B0 | 134 | WAVE | 30 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801708B0.c` | +| 128 | func_80170CF0 | 134 | schedule | 30 | failed | | 4-ins PROLOGUE-ORDER residual (body insns 4-29 byte-identical). My cc1 hoists the funcptr lui/lw ABOVE the frame setup (lui,lw,addiu sp,sw s0); target keeps frame setup first (addiu sp,sw s0,lui,lw). Same prologue-order class as func_80177F84 (cookbook L1332) — no C lever found (intermediate var/cast/void*-vs-funcptr/pin/early-ptr all reproduce the hoist; barriers/empty-asm/volatile-local regress). KEY WIN: `case 0: break;` forces emit_case_nodes' slti<2;bnez→default lower-bound prune, exactly matching the target dispatch tree (a bare 2-case switch omits it). | `.run/backlog_drafts/func_80170CF0.c` | +| 129 | func_80149450 | 134 | WAVE | 31 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80149450.c` | +| 130 | func_80149F2C | 134 | WAVE | 31 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80149F2C.c` | +| 131 | func_80161A90 | 134 | other | 34 | failed | | none — MATCH (34 ins) at the overlay's STANDARD -O2 (match_one reports MATCH). NO -O1 split needed. | `.run/backlog_drafts/func_80161A90.c` | +| 132 | func_80152C80 | 134 | plumbing | 41 | failed | | none — MATCH expected (linear call/store sequence, no regalloc tension) | `.run/backlog_drafts/func_80152C80.c` | +| 133 | func_80173BC0 | 134 | plumbing | 41 | failed | | none — MATCH. Keys: invert mask branch (else-block = 80174650 path so func_8013E588 | `.run/backlog_drafts/func_80173BC0.c` | +| 134 | func_80130A18 | 134 | struct | 43 | failed | | none — MATCH (two separate Vec3s locals give the 8-byte-spaced sp+0x10/sp+0x18 blocks) | `.run/backlog_drafts/func_80130A18.c` | +| 135 | func_8014C1C8 | 134 | regalloc-order | 44 | failed | | none — MATCH (match_one 44/44 ins, relocation-masked) | `.run/backlog_drafts/func_8014C1C8.c` | +| 136 | func_80146750 | 134 | regalloc-order | 47 | failed | | none — MATCH (match_one 47/47; psVar4->$a3 / psVar3->$v1 pins forced the init order) | `.run/backlog_drafts/func_80146750.c` | +| 137 | func_8014680C | 134 | struct | 47 | failed | | none — MATCH (47 ins, relocation-masked) | `.run/backlog_drafts/func_8014680C.c` | +| 138 | func_8014C4AC | 134 | other | 47 | failed | | none — MATCH (shared-ret0 goto §16 flips final branch polarity + schedules ret=0 into delay slot; memcpy(t0+0x7C,a3,8) inlines the lwl/lwr/swl/swr 8-byte block §21; param_1 = unsigned short* for the lhu reads) | `.run/backlog_drafts/func_8014C4AC.c` | +| 139 | func_80151B98 | 134 | regalloc-order | 47 | failed | | none — MATCH | `.run/backlog_drafts/func_80151B98.c` | +| 140 | func_80147F78 | 134 | schedule | 48 | failed | | TWO residuals remain. (1) FRAME: target frame is 0x60 = exactly 64 bytes (16 words) of LIVE local vars on top of the 4 saved regs (s0,s1,s2,ra) + 0x10 arg area; my body has no locals so frame is 0x20. Reproducing 64B of live local needs an address-escaped local buffer, but the target has only the 3 visible jals (no 4th call to receive &buf), so I cannot make a 16-word local survive -O2 dead-store-elim without emitting an extra instruction. (2) RELOAD SCHEDULE: target reloads D_80127090/94/98 from memory (folded lui%hi;lw%lo) with the FIRST reload HOISTED up between store90 and store94 (free non-volatile scheduling); a "memory" clobber barrier (below) forces the folded reloads but pins them strictly AFTER all three stores. The natural source is almost certainly a 16-word local buffer that ALIASES the globals (non-volatile reloads, freely scheduled) — same construct that also explains the 0x60 frame. Closest faithful body kept below; folded reload bytes are correct, frame + hoist are the gap. | `.run/backlog_drafts/func_80147F78.c` | +| 141 | func_80151C54 | 134 | plumbing | 52 | failed | | none — MATCH (52 ins). Branch-polarity §3-T4: BD60 arm is fall-through (if !=1 && ==0x11), BC44 is else. | `.run/backlog_drafts/func_80151C54.c` | +| 142 | func_8017129C | 134 | struct | 58 | failed | | none — MATCH (58 ins); three aligned 16-byte block-copies via struct assignment (cookbook §21) | `.run/backlog_drafts/func_8017129C.c` | +| 143 | func_80173A60 | 134 | regalloc-order | 59 | failed | | none — MATCH (59 ins) | `.run/backlog_drafts/func_80173A60.c` | +| 144 | func_80130650 | 134 | plumbing | 60 | failed | | none — MATCH (60 ins). ((void (*)(void))func_801319E0)() called with NO arg in the >=0x10 branch (target jal+nop, no a0 setup) → no-proto extern (K&R), promotion-safe vs canonical void ((void (*)(void))func_801319E0)(s32). func_8012CBF4 returns s32 here vs canonical void → cast_call_sites handles it. | `.run/backlog_drafts/func_80130650.c` | +| 145 | func_8014A738 | 134 | regalloc-order | 62 | failed | | none — MATCH | `.run/backlog_drafts/func_8014A738.c` | +| 146 | func_80175308 | 134 | struct | 67 | failed | | none — MATCH (67 ins, relocation-masked) | `.run/backlog_drafts/func_80175308.c` | +| 147 | func_80132F40 | 134 | regalloc-order | 72 | failed | | gcc gives src (sp+0x10) a 5th saved reg ($s3, frame 0x38 not 0x40); target rematerializes | `.run/backlog_drafts/func_80132F40.c` | +| 148 | func_8014D610 | 134 | plumbing | 74 | failed | | none — MATCH (74 ins). for-loop + continue, single IV pointer p; gcc derives the $s0 = p+0x75 second induction var. Template: DEFINE_func_80163950 (sibling, same D_801202A0 loop + func_80135A4C). | `.run/backlog_drafts/func_8014D610.c` | +| 149 | func_80163534 | 134 | schedule | 76 | failed | | mismatch=13, a single 1-position scheduling tie. Instrs 1-30 byte-perfect; all registers correct | `.run/backlog_drafts/func_80163534.c` | +| 150 | func_8014CF04 | 134 | struct | 82 | failed | | none — MATCH (82 ins; array-of-struct scan, for-loop over Ent D_801202A0[96], stride 0x10C) | `.run/backlog_drafts/func_8014CF04.c` | +| 151 | func_80156670 | 134 | schedule | 83 | failed | | none — MATCH (83 ins). Key: hoist `iVar1 = uVar3*4;` as its OWN statement before the if so gcc schedules `sll v1,s1,2` into the bnez delay slot (computed unconditionally) and reuses v1 index-first (`iVar1 + (s32)&D_801150E0` → `addu v0,v1,v0`). 13-arg call to func_80157158 (a0-a3 + 9 stack args at 0x10..0x30); param_2/param_3 cast (u16) → andi; param_6 incoming as lhu(u16). Address args = integer math `iVar2 + (s32)&D_x` (index-first → lui;addiu;addu, index added first). | `.run/backlog_drafts/func_80156670.c` | +| 152 | func_8014D4C0 | 134 | schedule | 84 | failed | | none — MATCH (goto forces if-body out-of-line/last; `>=` fixes slt operand order) | `.run/backlog_drafts/func_8014D4C0.c` | +| 153 | func_8016A73C | 134 | struct | 85 | failed | | none — MATCH (85 ins, relocation-masked) | `.run/backlog_drafts/func_8016A73C.c` | +| 154 | func_80173CB4 | 134 | schedule | 90 | failed | | none — MATCH (switch form keeps cases unmerged; final block: reuse one temp for the D_8012750C test + the func_8013767C result -> $a0 alloc; invert if to !=0 for branch polarity + store order) | `.run/backlog_drafts/func_80173CB4.c` | +| 155 | func_8014C6F4 | 134 | regalloc-order | 91 | failed | | 19-off loop tie-break — target compiles the search as a while/for (pre-guard sltu;beqz present) with the found pointer snapshotted to $v0 split from the IV in $a0 and the +4 sunk into both call-arg delay slots; do-while is instruction-count-exact (91=91) but lacks the pre-guard, while every for/while form costs +4 ins (merge stays in $a0). §10 schedule/regalloc residual. | `.run/backlog_drafts/func_8014C6F4.c` | +| 156 | func_8014D12C | 134 | schedule | 93 | failed | | none — MATCH (93 ins). Block-order lever: success-continuation (return 1) | `.run/backlog_drafts/func_8014D12C.c` | +| 157 | func_801502EC | 134 | schedule | 93 | failed | | none — MATCH (93 ins). 8-byte block copy via alignment-1 struct (Blk8{u8 b[8]}) assignment reproduces the lwl/lwr/swl/swr; ret=0 hoisted before the block copy to fix the s3-vs-ra prologue save order. | `.run/backlog_drafts/func_801502EC.c` | +| 158 | func_80150170 | 134 | struct | 95 | failed | | none — MATCH (95/95). Keys: (1) two parallel 3-halfword groups via chained assign `sp10.x = sp18.x = v` (sp18 inner so 0x18 stores first); (2) align-1 blk8 struct copy for the lwl/lwr/swl/swr 8-byte copy into actor+0x80 (src = sp buf from func_801502EC, or u8[] D_801152A8); (3) f0/f2 = u16 (lhu), f1 = s16 (lh for the slt); (4) `(iVar5/iVar6)!=0` single-OR test + branch-polarity invert (not-both-zero is fall-through); (5) both-zero tail register pins: 0x7fff -> $v1 (`register s32 __asm__("$3")`), sp10.f0/f2 -> reused $a0 (`register u32 __asm__("$4")` written twice) to force gcc's hoist-load + reg reuse schedule. | `.run/backlog_drafts/func_80150170.c` | +| 159 | func_8014CD80 | 134 | regalloc-order | 97 | failed | | none — MATCH (97 ins). iVar3 pinned to $v1 (register __asm__("$3")) so | `.run/backlog_drafts/func_8014CD80.c` | +| 160 | func_8014E284 | 134 | WAVE | 108 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8014E284.c` | +| 161 | func_80167540 | 134 | WAVE | 117 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80167540.c` | +| 162 | func_8014F4C0 | 134 | WAVE | 141 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8014F4C0.c` | +| 163 | func_8014E048 | 134 | WAVE | 143 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8014E048.c` | +| 164 | func_80155800 | 134 | WAVE | 145 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80155800.c` | +| 165 | func_80138ED0 | 134 | GIANT | 159 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 166 | func_8012EC04 | 134 | GIANT | 178 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 167 | func_801392FC | 134 | GIANT | 182 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 168 | func_8013AF20 | 134 | GIANT | 185 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 169 | func_8012D098 | 134 | GIANT | 189 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 170 | func_80129CF8 | 134 | GIANT | 191 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 171 | func_8013A530 | 134 | GIANT | 204 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 172 | func_801372B0 | 134 | GIANT | 207 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 173 | func_80144B9C | 134 | other | 770 | failed | | -O0 cluster fn (prologue 21F0A003, fp-frame, all locals spilled+reloaded, load-delay nops). match_one compiles -O2 so it CANNOT match this; needs its own per-file -O0 split (Makefile CC1FLAGS:=-O0), like ov_SC01_077_o0.c. Body below is the faithful -O0 source; gate via whole-binary -O0 build only. | `.run/backlog_drafts/func_80144B9C.c` | +| 174 | func_80151944 | 4 | struct | 15 | near | 0 | none — MATCH (fn-pointer table dispatch; array-of-ptr indexing folds %lo) | `.run/backlog_drafts/func_80151944.c` | +| 175 | func_8016039C | 2 | STRUCT | 15 | near | 0 | match_one MATCH but gate rejected (declaration/TU plumbing) | `.run/backlog_drafts/func_8016039C.c` | +| 176 | func_8015DAF8 | 1 | struct | 15 | near | 0 | none — MATCH (proxy); identical idiom to matched func_8016901C in same overlay | `.run/backlog_drafts/func_8015DAF8.c` | +| 177 | func_8015FAAC | 1 | STRUCT | 15 | near | 0 | match_one MATCH but gate rejected (declaration/TU plumbing) | `.run/backlog_drafts/func_8015FAAC.c` | +| 178 | func_801577C8 | 1 | plumbing | 16 | near | 0 | none — MATCH expected (scalar global store + two sequential calls, param preserved across first call) | `.run/backlog_drafts/func_801577C8.c` | +| 179 | func_80178B70 | 1 | struct | 18 | near | 0 | none — MATCH; local ptr p=&D_8018A458 used for store AND (int)p-0xC arg forces $s0-base reuse across call1, param_1 into $s1 | `.run/backlog_drafts/func_80178B70.c` | +| 180 | func_8013373C | 1 | regalloc-order | 18 | near | 0 | none — MATCH (indexed-global int-array %lo-fold + (short)param*4 fuses sll16/sra14; loaded value pinned to $a0/$4 to reuse the param reg instead of $v0) | `.run/backlog_drafts/func_8013373C.c` | +| 181 | func_8017F240 | 1 | regalloc-order | 20 | near | 0 | none — MATCH (base &D_801270D0 pinned to $s0 holds across call; one lui/addiu reused for load+store) | `.run/backlog_drafts/func_8017F240.c` | +| 182 | func_80157D20 | 1 | plumbing | 21 | near | 0 | none — MATCH expected (call, indexed u16-global load as 2nd arg, then call; param_1 saved across all three calls) | `.run/backlog_drafts/func_80157D20.c` | +| 183 | func_80163408 | 1 | struct | 21 | near | 0 | local 8-byte struct copied from D_801D8BB0, © passed as 5th arg (s32) | `.run/backlog_drafts/func_80163408.c` | +| 184 | func_80175184 | 1 | struct | 21 | near | 0 | none — MATCH (fnptr-array %lo-fold dispatch; idx = *(u16*)(a0+2) < 2 ? D_8018A1A4[idx]() : func_80175268()) | `.run/backlog_drafts/func_80175184.c` | +| 185 | func_8012F8C8 | 1 | plumbing | 21 | near | 0 | none — MATCH (pending verify) | `.run/backlog_drafts/func_8012F8C8.c` | +| 186 | func_8014FBC0 | 1 | schedule | 22 | near | 0 | none — MATCH (22 ins). Stack-switch primitive: register $sp var, manual save/switch/restore around the call. | `.run/backlog_drafts/func_8014FBC0.c` | +| 187 | func_80178B18 | 1 | other | 22 | near | 0 | none — MATCH | `.run/backlog_drafts/func_80178B18.c` | +| 188 | func_8017B8E8 | 1 | plumbing | 22 | near | 0 | none — MATCH (two inlined unaligned 8-byte memcpy blocks: src[0..7]->D_801DA794, src[8..15]->D_801DA78C) | `.run/backlog_drafts/func_8017B8E8.c` | +| 189 | func_80182988 | 1 | plumbing | 22 | near | 0 | none — MATCH (u16 store of 0xAA10 forces ori, not sign-extended addiu) | `.run/backlog_drafts/func_80182988.c` | +| 190 | func_801320D8 | 1 | schedule | 27 | near | 0 | none — MATCH (27 ins, relocation-masked) | `.run/backlog_drafts/func_801320D8.c` | +| 191 | func_80132144 | 1 | other | 27 | near | 0 | none — MATCH | `.run/backlog_drafts/func_80132144.c` | +| 192 | func_801321B0 | 1 | other | 27 | near | 0 | none — MATCH (match_one 27/27, relocation-masked) | `.run/backlog_drafts/func_801321B0.c` | +| 193 | func_8013221C | 1 | other | 27 | near | 0 | none — MATCH (expected); straight scheduling, one call-crossing local -> $s0 naturally | `.run/backlog_drafts/func_8013221C.c` | +| 194 | func_801609B8 | 1 | struct | 28 | near | 0 | none — MATCH (pending byte-gate); function-pointer table %lo-fold via extern array | `.run/backlog_drafts/func_801609B8.c` | +| 195 | func_801312D0 | 1 | struct | 28 | near | 0 | none — MATCH (unaligned 8-byte memcpy from global; if/else branch layout) | `.run/backlog_drafts/func_801312D0.c` | +| 196 | func_80136C90 | 1 | other | 28 | near | 0 | local char[10] string-literal init -> rodata-template block move (lwl/lwr + swl/swr + lb/sb), 9+1 split | `.run/backlog_drafts/func_80136C90.c` | +| 197 | func_8017E224 | 1 | struct | 29 | near | 0 | none — MATCH (unaligned 8-byte memcpy of global onto stack + cond byte incr) | `.run/backlog_drafts/func_8017E224.c` | +| 198 | func_80165140 | 1 | regalloc-order | 30 | near | 0 | none — MATCH (pin i=$v1/eight=$a0/p=$a2; DON'T pin param — let it self-copy to $a3 first; memcpy 8/4 unaligned) | `.run/backlog_drafts/func_80165140.c` | +| 199 | func_801549F8 | 1 | iv-combine | 31 | near | 0 | none — MATCH (31 ins). Re-tie barrier on the index defeats gcc's pointer-giv | `.run/backlog_drafts/func_801549F8.c` | +| 200 | func_8015E698 | 1 | struct | 31 | near | 0 | none — MATCH (clean -O2 reconstruction; table-of-fnptr indexed by param_1[0]) | `.run/backlog_drafts/func_8015E698.c` | +| 201 | func_8017D98C | 1 | plumbing | 31 | near | 0 | none — MATCH (expected): straight global stores + tail call; const 0x140 reused for two halves | `.run/backlog_drafts/func_8017D98C.c` | +| 202 | func_80182268 | 1 | struct | 31 | near | 0 | none — MATCH (jump-table switch over sign-extended high byte of *(u16*)(a0+0x70); case4 decrements D_801270CC then falls into case3/7's func_8012C218; no default) | `.run/backlog_drafts/func_80182268.c` | +| 203 | func_801602A4 | 1 | struct | 34 | near | 0 | none — MATCH (template = matched twin func_801601E4; lhu+0x8000 == compare, fnptr-table dispatch D_801891B8[*(u16*)a0]() no-arg, then 3-call setup in target order; func_80161208 in else) | `.run/backlog_drafts/func_801602A4.c` | +| 204 | func_801734BC | 1 | struct | 34 | near | 0 | none — MATCH (pending byte-gate); switch-jtbl with no default, 3 short stores + fnptr call | `.run/backlog_drafts/func_801734BC.c` | +| 205 | func_8017D900 | 1 | plumbing | 35 | near | 0 | none — expect MATCH (STUB: ordered global stores + single tail call, sibling of func_8017D840) | `.run/backlog_drafts/func_8017D900.c` | +| 206 | func_8016BEA0 | 1 | other | 37 | near | 0 | none — MATCH (expected) | `.run/backlog_drafts/func_8016BEA0.c` | +| 207 | func_801754A8 | 1 | regalloc-order | 37 | near | 0 | none — MATCH (37 ins, relocation-masked proxy) | `.run/backlog_drafts/func_801754A8.c` | +| 208 | func_80160920 | 1 | struct | 38 | near | 0 | none — MATCH (function-pointer table folds %lo via extern array indexed by halfword) | `.run/backlog_drafts/func_80160920.c` | +| 209 | func_80183BAC | 1 | struct | 41 | near | 0 | switch jump-table dispatch (jtbl_801D9420); verifying case grouping 0,1,2,5,6/3,7/4 emits the target table + tail | `.run/backlog_drafts/func_80183BAC.c` | +| 210 | func_80183C50 | 1 | struct | 41 | near | 0 | none — MATCH (cross-jump exploit §cookbook L1543: dup func_8012C218 into case3/7 + case4 → merged jal;nop) | `.run/backlog_drafts/func_80183C50.c` | +| 211 | func_8015DF34 | 1 | struct | 44 | near | 0 | none — MATCH (clean structural; fn-ptr table via array index folds %lo) | `.run/backlog_drafts/func_8015DF34.c` | +| 212 | func_8015FE70 | 1 | struct | 44 | near | 0 | none — MATCH expected (fn-ptr-table dispatch + ushort struct fields) | `.run/backlog_drafts/func_8015FE70.c` | +| 213 | func_8014358C | 1 | regalloc-order | 45 | near | 0 | none — MATCH (relocation-masked match_one) | `.run/backlog_drafts/func_8014358C.c` | +| 214 | func_80183AF0 | 1 | regalloc-order | 47 | near | 0 | none — MATCH (mask pinned $a1/$5 + p pinned $v0/$2; switch w/ distributed func_8012C218 tail via dup calls + cross-jump merge) | `.run/backlog_drafts/func_80183AF0.c` | +| 215 | func_80178BF8 | 1 | plumbing | 49 | near | 0 | none — MATCH (pure scalar-store + two pointer-decrement do-while loops) | `.run/backlog_drafts/func_80178BF8.c` | +| 216 | func_8015E344 | 1 | struct | 50 | near | 0 | none — MATCH (pending whole-binary gate); fn-ptr table folds %lo via extern array, 0x234 single word store | `.run/backlog_drafts/func_8015E344.c` | +| 217 | func_8017EC7C | 1 | struct | 52 | near | 0 | none — MATCH (52 ins, relocation-masked) | `.run/backlog_drafts/func_8017EC7C.c` | +| 218 | func_80183CF4 | 1 | struct | 57 | near | 0 | none — MATCH (clean switch + jtbl; orchestrator owns jtbl/rodata migration) | `.run/backlog_drafts/func_80183CF4.c` | +| 219 | func_8015D01C | 1 | regalloc-order | 58 | near | 0 | none — MATCH | `.run/backlog_drafts/func_8015D01C.c` | +| 220 | func_8016D688 | 1 | struct | 60 | near | 0 | none — MATCH (byte array D_801D9C20[] folds the &D_801D9C21 base/-1 offsets; emit p+0xE store BEFORE the param+2 increment so the lhu fills the load-delay slot in $v1) | `.run/backlog_drafts/func_8016D688.c` | +| 221 | func_801842C8 | 1 | plumbing | 62 | near | 0 | none — MATCH | `.run/backlog_drafts/func_801842C8.c` | +| 222 | func_80165240 | 1 | regalloc-order | 63 | near | 0 | none — MATCH (63 ins). buf pinned to $s2 (register __asm__("$18")) so it stays in a callee-saved reg; param_3 then naturally lands in $s3. memcpy(buf+0x30,param_3,4) -> lwl/lwr+swl/swr unaligned 4B copy (cookbook §1 mem->mem). array-of-u8 buf with explicit *(T*)(buf+off) stores; mtx[0x20] declared 2nd so it lands at sp+0x50, buf_ at sp+0x10. | `.run/backlog_drafts/func_80165240.c` | +| 223 | func_8017BB34 | 1 | struct | 65 | near | 0 | none — MATCH (65 ins). Keys: (1) align-1 {s8 b[8]} struct so the two 8-byte copies emit lwl/lwr; (2) stack-local declaration order = target frame order (svin@0x10, buf@0x18, out@0x38, local8@0x40, rt_in@0x48, rt_out@0x50) — reordering the locals to ascending offset fixed all 23 offset-only diffs. | `.run/backlog_drafts/func_8017BB34.c` | +| 224 | func_8016BD78 | 1 | regalloc-order | 74 | near | 0 | none — MATCH (lazy pointer locals pa=&BC4, pb=&BC8 assigned at first use → $a1/$a2 held thru middle code as final call args; middle bytes BC5/BC6/BC9/BCA direct global) | `.run/backlog_drafts/func_8016BD78.c` | +| 225 | func_8016E7C8 | 1 | regalloc-order | 74 | near | 0 | none — MATCH (match_one 74/74; pins $18=&prim, $19=param_3 fixed s2/s3 alloc order; Work struct sized to 0x20) | `.run/backlog_drafts/func_8016E7C8.c` | +| 226 | func_8018281C | 1 | struct | 76 | near | 0 | none — MATCH (76 ins). jtbl forced via explicit case 4/6 (count>=5 over MIPS tablejump threshold); case-5 block placed between if-block and default via goto so the if-block emits j default w/ e2=0 in the delay slot | `.run/backlog_drafts/func_8018281C.c` | +| 227 | func_8016AE5C | 1 | regalloc-order | 85 | near | 0 | none — MATCH (85 ins, match_one). switch/jtbl STRUCT fn. The tail's | `.run/backlog_drafts/func_8016AE5C.c` | +| 228 | func_80182E7C | 1 | struct | 85 | near | 0 | none — MATCH (85 ins, relocation-masked). Two switch-codegen levers: | `.run/backlog_drafts/func_80182E7C.c` | +| 229 | func_8015C7E4 | 1 | struct | 88 | near | 0 | none — MATCH (match_one 88/88); fn-ptr-array dispatch, top-level if/else needed branch-polarity invert (small block falls through, big block at L854) | `.run/backlog_drafts/func_8015C7E4.c` | +| 230 | func_8015CA28 | 1 | schedule | 91 | near | 0 | none — MATCH (goto forces the func_80161240 block to the function tail; bnez-to-end layout vs early-return fall-through) | `.run/backlog_drafts/func_8015CA28.c` | +| 231 | func_801820DC | 1 | struct | 94 | near | 0 | none — MATCH (switch on entity state at 0x34, inner jtbl on (s8)(u70>>8)) | `.run/backlog_drafts/func_801820DC.c` | +| 232 | func_80184D50 | 1 | schedule | 98 | near | 0 | none — MATCH (98 ins, relocation-masked) | `.run/backlog_drafts/func_80184D50.c` | +| 233 | func_80161D20 | 1 | struct | 14 | near | 1 | none — MATCH (array-of-u16 %lo-fold, §18) | `.run/backlog_drafts/func_80161D20.c` | +| 234 | func_8017F714 | 1 | plumbing | 27 | near | 1 | none — MATCH (27/27 ins, match_one verified) | `.run/backlog_drafts/func_8017F714.c` | +| 235 | func_80142A10 | 1 | struct | 28 | near | 1 | none — MATCH (pending byte-gate) | `.run/backlog_drafts/func_80142A10.c` | +| 236 | func_80161C24 | 1 | struct | 29 | near | 1 | none — MATCH (array-of-struct %lo-fold; even/odd u16 fields at off 0/2, stride 4) | `.run/backlog_drafts/func_80161C24.c` | +| 237 | func_80184C0C | 1 | struct | 48 | near | 1 | none — MATCH (array-of-struct %lo-fold for &D_8018AEB8[idx], stride 0x34) | `.run/backlog_drafts/func_80184C0C.c` | +| 238 | func_8016B4F8 | 1 | regalloc-order | 50 | near | 1 | none — MATCH | `.run/backlog_drafts/func_8016B4F8.c` | +| 239 | func_801803B0 | 1 | other | 51 | near | 1 | none — MATCH expected; simple if/else, no call-crossing locals beyond param in $s0 | `.run/backlog_drafts/func_801803B0.c` | +| 240 | func_8015FBE0 | 1 | schedule | 58 | near | 1 | none — MATCH | `.run/backlog_drafts/func_8015FBE0.c` | +| 241 | func_8017F114 | 1 | regalloc-order | 75 | near | 1 | none — MATCH | `.run/backlog_drafts/func_8017F114.c` | +| 242 | func_8017F290 | 1 | regalloc-order | 86 | near | 2 | none — MATCH. Two levers: (1) hold &D_801270CC in a `int *state` local so its | `.run/backlog_drafts/func_8017F290.c` | +| 243 | func_8016EC0C | 1 | schedule | 88 | near | 2 | none — MATCH (88 ins). Sparse switch(uVar2) = gcc's beq-pivot+slti comparison | `.run/backlog_drafts/func_8016EC0C.c` | +| 244 | func_80171B4C | 1 | schedule | 70 | near | 3 | 3-off in the tail only (body+prologue MATCH via $s1 pin on arg1). gcc fills the | `.run/backlog_drafts/func_80171B4C.c` | +| 245 | func_80140E6C | 1 | schedule | 37 | near | 4 | 4 ins — each save-across-call copy (move s1,v0 / move s0,v0) should fill the NEXT jal's delay slot (target) but gcc-2.7.2 sched ties the copy with the next call's arg-setup at priority 2 and the LUID tie-break (rank_for_schedule) keeps the copy first, so reorg fills the slot with the arg-setup instead; no C reshape found that flips the LUID/priority order without breaking the OR-chain regalloc. | `.run/backlog_drafts/func_80140E6C.c` | +| 246 | func_8017EF50 | 1 | schedule | 53 | near | 5 | 5 ins — gcc-2.7.2 instr-scheduler load-order tie-breaks. Branch region + cross-jump-break (t14 pin to $3) + 0x34/0x30 hoist (c34 pin $5, c2c pin $3) all MATCH. Residual: (a) header 0x10-load vs 0x2c-load order swap; (b) compare loads 0x36-before-0xA and puts 0xA in $a1 not $a2 (slt operand reg differs). Both clusters resist source steering — every fix to one perturbs the pinned header schedule. | `.run/backlog_drafts/func_8017EF50.c` | +| 247 | func_8014D3E0 | 1 | other | 22 | near | 6 | none — MATCH | `.run/backlog_drafts/func_8014D3E0.c` | +| 248 | func_8013CF68 | 1 | schedule | 63 | near | 6 | blocks 2&3 delay-slot fill — gcc picks dead-reg $v1(b0,0x10/0x20) store for the jal delay slot; target picks arg-reg $a3(0x12/0x22). 6 ins (2 rotations); not flippable by source store-order/interleave/barrier (all tested); permuter/scheduler-internal lever needed. Prologue, $s0 fold, regalloc, block-1 all exact. | `.run/backlog_drafts/func_8013CF68.c` | +| 249 | func_8017B940 | 1 | struct | 63 | near | 6 | none — MATCH | `.run/backlog_drafts/func_8017B940.c` | +| 250 | func_8017B238 | 1 | regalloc-order | 76 | near | 6 | 6 ins — gcc coalesces param_2 into callee-saved $s0 and hoists `move $s0,$a1` | `.run/backlog_drafts/func_8017B238.c` | +| 251 | func_8017B614 | 1 | regalloc-order | 101 | near | 6 | 6 ins — param_2 lands in callee-saved $s0 (entry `move s0,a1`, sltiu/sll read s0) vs target's $a1; gcc prefers s0 (saved anyway for the late p794/p78C copies) over caller-saved $a1. Body+schedule otherwise byte-exact (101/101 ins); the late-part `__asm__("")` barrier is load-bearing (fixes the const-store schedule, 21->6). | `.run/backlog_drafts/func_8017B614.c` | +| 252 | func_801345F8 | 1 | schedule | 106 | near | 7 | 7 ins, all pure scheduling order — maskedp copy not sunk into bnez delay slot | `.run/backlog_drafts/func_801345F8.c` | +| 253 | func_80164E40 | 1 | struct | 25 | near | 8 | none — MATCH expected; byte 0 keeps base $v1 (reused by final lw word), bytes 1/2 standalone | `.run/backlog_drafts/func_80164E40.c` | +| 254 | func_8012A018 | None | | None | near | 9 | residual: 9 mismatch | `.run/backlog_drafts/func_8012A018.c` | +| 255 | func_8014C8C8 | None | | None | near | 10 | residual: 10 mismatch | `.run/backlog_drafts/func_8014C8C8.c` | +| 256 | func_8016E9EC | 1 | schedule | 53 | near | 11 | 11 left — all GNU scheduler/canon tie-breaks (regs all match via pins): (a) prologue hoists `addiu a1,0x1C` into the save block; (b) first lbu reads $a0 not $s1 (incoming-arg still live); (c) iCopy copy `addu s4,s0` lands early (scheduler) vs target's func_800D2CA8 delay-slot; (d) `addu a2,s2,s3` vs target `s3,s2` commutative-canon (unflippable w/o breaking load order). Permuter can't run (register __asm__ pins rejected, cookbook §5a). | `.run/backlog_drafts/func_8016E9EC.c` | +| 257 | func_80156044 | 1 | struct | 74 | near | 12 | none — MATCH (74 ins, relocation-masked); $s2-pin for u16-return + def-mask + 3-arg cast on func_80156848 | `.run/backlog_drafts/func_80156044.c` | +| 258 | func_80161CD0 | 1 | regalloc-order | 20 | near | 14 | param_2 must survive the call in $s0; try plain C first then pin to $16 | `.run/backlog_drafts/func_80161CD0.c` | +| 259 | func_80158FA4 | 1 | schedule | 51 | near | 17 | target keeps a DEAD `sra $a1,$v0,16` before `beqz $a1` (sign-extend of func_80159464's | `.run/backlog_drafts/func_80158FA4.c` | +| 260 | func_80182338 | 1 | PINS | 26 | near | 24 | PINS: 24 mismatch | `.run/backlog_drafts/func_80182338.c` | +| 261 | func_8018301C | 1 | plumbing | 28 | near | 24 | none — MATCH (straight-line, statement-order; verify with match_one) | `.run/backlog_drafts/func_8018301C.c` | +| 262 | func_8016BBE0 | 1 | other | 56 | near | 24 | none — straightforward; expect MATCH (mirror Ghidra-C order, synth_mult ×0x555) | `.run/backlog_drafts/func_8016BBE0.c` | +| 263 | func_8016E95C | 1 | regalloc-order | 36 | near | 25 | none — MATCH (pending byte-gate) | `.run/backlog_drafts/func_8016E95C.c` | +| 264 | func_80139BE0 | 1 | loose-typing | 39 | near | 32 | target has redundant andi a1,v0,0xff (uchar zero-extend) gcc proves away; else identical | `.run/backlog_drafts/func_80139BE0.c` | +| 265 | func_80148E54 | 1 | regalloc-order | 67 | near | 40 | 67/67 ins, structure+branches+block-order+body-reload all match; residual is pure register-allocation order (permuter-eligible, no register-pins). (1) masked first-angle folds andi->$s1; target keeps it in $a0 then copies addu $s1,$a0 lazily into the beq delay-slot (the s1-copy schedules 1 slot later). (2) the 0x80 const is CSE-held in $a2 across both test+body; target re-materializes 0x80 in $v0 per block (it gets clobbered by `srl v0,v1,8`), which both renames the compare regs ($v0 not $a2) AND fills the body's reload load-delay slot (mine emits a nop there). (3) single-exit ret funnels $v1->$v0 (move v0,v1) where target writes $v0 directly. All three are gcc regalloc/value-prop tie-breaks no C reshape steered (tried: $v0 pin, temp-split, low-mask-reuse compare, memory-clobber-vs-volatile reload) — leave for the permuter. | `.run/backlog_drafts/func_80148E54.c` | +| 266 | func_8017B0E4 | 1 | other | 61 | near | 51 | none — MATCH (expected; clean six-call sign-extend-store pattern) | `.run/backlog_drafts/func_8017B0E4.c` | +| 267 | func_80166F58 | 1 | schedule | 69 | near | 55 | regs/loop/logic/%lo-fold all match (pinned $s0-$s6); residual is reorg.c delay-slot fill — target replicates `addiu $v0,$s2,1` into the 3 skip-branch delay slots + commits `addu $s2,$v0,0` at merge (my codegen emits in-place `addiu $s2,$s2,1` w/ nop slots, -1 ins); plus prologue short-arg promote-then-move not fusing (`sra $a1;addu $s4,$a1,0` vs my fused `sra $s4,$a1`). Not source-steerable (pins block permuter). | `.run/backlog_drafts/func_80166F58.c` | +| 268 | func_80177DA8 | 1 | remat | 63 | near | 58 | gcc narrows `&0xfffffeff` on a 16-bit (lhu) value to `andi 0xfeff` (inline), but target hoisted -0x101 into $t4 (and-reg) in the loop preheader — a gcc-2.7.2 LICM-before-combine pass-ordering quirk unsteerable from C; that 1-ins gap cascades the constant-reg numbering + tail reassoc. Secondary: single-IV loop ptr anchors at +0xA (short, 2 accesses) not +0xC (byte) like target. | `.run/backlog_drafts/func_80177DA8.c` | +| 269 | func_80141A60 | 1 | other | 76 | near | 63 | none — MATCH (76 ins, relocation-masked). Body byte-identical; target reserves an 8-byte | `.run/backlog_drafts/func_80141A60.c` | +| 270 | func_801457A4 | 1 | other | 79 | near | 74 | MATCH at -O0 (79 ins, reloc-masked, real -O0 flags). BANKING BLOCKER: this -O0 fn lives in the -O2 main ov_SC01_077.c; needs its own §18 -O0 split at 0x801457A4 (existing _o0.c covers 0x8013B568..0x8013C98C only). match_one is -O2 -> WRONG here. | `.run/backlog_drafts/func_801457A4.c` | +| 271 | func_8016B6BC | 1 | schedule | 94 | near | 80 | 12-off, all in the last 12 ins (tail). First 82 ins byte-match. Target materializes | `.run/backlog_drafts/func_8016B6BC.c` | +| 272 | func_80134A74 | 1 | regalloc-order | 107 | near | 84 | structure + all 8 callee-saved regs (s0..s7) + block layout MATCH; residual is caller-saved-temp | `.run/backlog_drafts/func_80134A74.c` | +| 273 | func_8013EE10 | 1 | struct | 94 | near | 86 | none — MATCH (94 ins). array-of-struct %lo-fold (E[]) for the 5-elt loops; | `.run/backlog_drafts/func_8013EE10.c` | +| 274 | func_80185E68 | 1 | STRUCT | 132 | near | 131 | STRUCT: 131 mismatch | `.run/backlog_drafts/func_80185E68.c` | +| 275 | func_801824D0 | 1 | WAVE | 181 | near | 180 | WAVE: 180 mismatch | `.run/backlog_drafts/func_801824D0.c` | +| 276 | func_80184A68 | 1 | regalloc-order | 33 | failed | | none — MATCH | `.run/backlog_drafts/func_80184A68.c` | +| 277 | func_8015E018 | 1 | loose-typing | 47 | failed | | none — MATCH (signed char forces lbu+sll24/sra24 sign-extend; default char is unsigned in this toolchain) | `.run/backlog_drafts/func_8015E018.c` | +| 278 | func_80159A20 | 1 | struct | 58 | failed | | none — MATCH. Key lever: block tail-MERGE (gcc shared `bne ...,$L1` cross-jump) by making the two return-tests STRUCTURALLY DIFFERENT — positive `if(==){goto mask;} return;` per branch (not `if(!=) return;`), so neither tail can merge. Then fix block ORDER by inverting the outer test (`if(d!=1)` makes the ==4/return path the inline fall-through, the d==1/p[2] path the forward `beq`-target block — matching the target layout). | `.run/backlog_drafts/func_80159A20.c` | +| 279 | func_8013E958 | 1 | schedule | 63 | failed | | 2 ins swapped — cc1 emits `andi 0x7f; andi 0xff; beqz`(tests doubly-masked) but target wants `andi 0x7f; beqz; andi 0xff`(andi 0xff in the first beqz delay slot). Loop fully byte-matches; struct/ptr fold idioms nailed (D_80115110.q[0x16] hoists base+0x58 disp, Cell D_80115188[i].v folds %lo). func_800D0488 takes (m&0xFF) arg. s16 m -> 2 mism (right ins count); s32 m fixes order but merges andi+arg-move (62 ins, 1 short). | `.run/backlog_drafts/func_8013E958.c` | +| 280 | func_8013E83C | 1 | plumbing | 71 | failed | | none — MATCH (scalar global stores + 2 conditional calls; §3-T4 branch-polarity invert on the &0xFF test) | `.run/backlog_drafts/func_8013E83C.c` | +| 281 | func_8017B368 | 1 | schedule | 74 | failed | | dead table-path off by 1 ins — target keeps src*16 live in $s0 & computes 2nd arg src16+(base+8) in call1 delay slot; every C form either folds to e+8 (73 ins) or CSEs base into an extra saved reg $s2 (75 ins). All live code (prologue, sltiu dispatch, copy path, 4 struct-copy stores, tail) matches; only the unreachable func_8012F214 path scheduling diverges. | `.run/backlog_drafts/func_8017B368.c` | +| 282 | func_80180B64 | 1 | struct | 75 | failed | | none — MATCH (75 ins, relocation-masked) | `.run/backlog_drafts/func_80180B64.c` | +| 283 | func_80180F10 | 1 | schedule | 75 | failed | | none — MATCH (aggregate-initializer form schedules const setup after the prologue saves) | `.run/backlog_drafts/func_80180F10.c` | +| 284 | func_8016C188 | 1 | schedule | 79 | failed | | none — MATCH (79 ins, match_one). Levers: invert if to if(iVar1!=0){big}else{small} | `.run/backlog_drafts/func_8016C188.c` | +| 285 | func_80164930 | 1 | regalloc-order | 81 | failed | | none — MATCH (81 ins, relocation-masked) | `.run/backlog_drafts/func_80164930.c` | +| 286 | func_801418F8 | 1 | loose-typing | 90 | failed | | none — MATCH (90 ins). Keys: D_8011511A is `volatile u16` (store-2-then-read must NOT const-fold), read ONCE into a `u16` local t (an `unsigned int` local adds a stray andi 0xffff; reusing t feeds the single lhu to both sltiu and t-3), and the lone D_80115158 store after the if yields the delay-slot-fill-from-target dup of `addiu 0x106`. | `.run/backlog_drafts/func_801418F8.c` | +| 287 | func_801789AC | 1 | struct | 91 | failed | | none — MATCH (91 ins, relocation-masked) | `.run/backlog_drafts/func_801789AC.c` | +| 288 | func_80183DE0 | 1 | regalloc-order | 91 | failed | | testing if(!=1) layout + counter-before-pointer init order | `.run/backlog_drafts/func_80183DE0.c` | +| 289 | func_80185428 | 1 | struct | 94 | failed | | none — MATCH (94 ins, relocation-masked) | `.run/backlog_drafts/func_80185428.c` | +| 290 | func_801506A4 | 1 | loose-typing | 95 | failed | | none — MATCH (95 ins). switch var must be int not u16 (u16 adds andi 0xffff promotion mask) | `.run/backlog_drafts/func_801506A4.c` | +| 291 | func_8016BFD0 | 1 | struct | 95 | failed | | none — MATCH (95 ins). memcpy(d,s,4) -> lwl/lwr/swl/swr; MATRIX work buf as s32[16] (0x40, fills 0x10-0x4f, t[] = buf[5..7]); two SVECTOR locals at 0x50/0x58; natural saved-reg order s0=param_5/s1=param_4/s2=iVar5 | `.run/backlog_drafts/func_8016BFD0.c` | +| 292 | func_801596F0 | 1 | struct | 97 | failed | | none — MATCH (97 ins). Loop 1 = struct-ptr for-loop (E38, flag@+4) -> -4 guard / +4 test via gcc biv-elim. Loop 2 needed an EXPLICIT if-guard + do-while with the FIELD pointer as the loop var (so the giv init emits FIRST in the preheader, before the &D invariant block), a non-volatile re-tie barrier on d=&D_800AFAE8 (keeps &D BARE so +4/+0x88 add off it = +1 ins vs the folded %lo, matching target), an explicit u32 mask hoisted first (fills the guard's delay slot), and a separate range check fp=d+0x88. | `.run/backlog_drafts/func_801596F0.c` | +| 293 | func_8017B490 | 1 | schedule | 97 | failed | | none — MATCH (97 ins). Keys: (1) inverted if so the SV4 block-copy else is fallthrough and block A is bnez-far (cond = (u32)&D_801DA73C >= 0xB, a relocated-symbol compare gcc can't fold); (2) SV4{s16 a,b,c,d} align-2 8-byte copy -> lwl/lwr/swl/swr, locals at sp+0x10/0x18; (3) the DEAD block-A index = (s32)&D_801DA73C into D_8018A45C[] (WAVE16=two SV4) needs BOTH source addrs (&[idx].v0,&[idx].v1) in EXPLICIT TEMPS before call1 so base (&D_8018A45C) dies pre-call -> temp $v0 (not callee-saved), forcing the natural 2-reg alloc idx=$s0/param_1=$s1 + src2 into call1's delay slot; (4) tail: D_801DA794/D_801DA78C are SV4, re-read .a/.b/.c via lh sign-extended to s32 stores. | `.run/backlog_drafts/func_8017B490.c` | +| 294 | func_80182C9C | 1 | schedule | 101 | failed | | none — MATCH (101 ins). Inner-switch break-to-shared-tail must be written as | `.run/backlog_drafts/func_80182C9C.c` | +| 295 | func_80183FB8 | 1 | loose-typing | 101 | failed | | none — MATCH (relocation-masked match_one, 101/101 ins) | `.run/backlog_drafts/func_80183FB8.c` | +| 296 | func_8013EF88 | 1 | struct | 108 | failed | | none — MATCH (108 ins). Keys: (1) §18 array-of-struct E4{s32 v} for | `.run/backlog_drafts/func_8013EF88.c` | diff --git a/docs/gen2-mips-matching-model.md b/docs/gen2-mips-matching-model.md index dd094d4f0..c2d6cf414 100644 --- a/docs/gen2-mips-matching-model.md +++ b/docs/gen2-mips-matching-model.md @@ -170,6 +170,36 @@ field — so the permuter can't gate a *non-077* near-miss today. That two-part resolution + a backlog `binary` field) is the next concrete step to turn the reach-134 close=1 fuel into ×134 banks. The reach oracle + `--min-reach` are reusable for that and for a corpus-v3 retrain. +### Grinder per-binary fix — built (5 layers); the reach≥2 close=1 fuel is semantic-misses + propagation-capped (2026-06-30) + +To grind the reach≥2 close=1 fuel via the permuter, the grinder needed the same binary-agnostic +treatment T7 gave `lora_grind` — and it ran **five layers deep** (the whole grinder/backlog pipeline +was ov_SC01_077-hardcoded): (1) `gate_stage` records the source `binary`; (2) `backlog.FIELDS` keeps it; +(3) `backlog.load_best`/`_open_stubs` is **fleet-aware** (a 077-matched-but-stuck-local fn now surfaces +via its overlay record instead of being dropped as "matched"); (4) `p16_permute.setup` takes the target +binary's asm-subdir; (5) `grinder` resolves per-binary asm + gates **grouped by binary** + allows unknown +`nins`. Validated end-to-end: the 3 fresh reach-134 close=1 ov_SC01_000 fns now surface, resolve to +ov_SC01_000's asm, and gate via ov_SC01_000. Backward-compatible (legacy records → 077). + +**Two byte-evidenced findings redirected the fuel strategy:** +- **The reach≥2 close=1 fuel is largely MODEL semantic-misses, not permuter fuel.** Diagnosed by the + byte: `func_8012E27C`'s target is literally `return 1` (2 ins), but the 7B drafted `void f(void){}` + (the corpus's overfit empty-leaf pattern); `func_8012BF4C`/`func_8012AD64` are trivial `sw`/`sh` setters + also drafted empty. The permuter (regalloc/schedule only) can't add a missing return/store — but a + **corrected draft** does: banked all 3 byte-identical via the fixed per-binary gate (the concrete + non-077-banking proof, fleet +3). So this fuel's lever is **a better draft (corpus-v3 leaf variety), + not the permuter.** +- **×reach is propagation-capped for the stuck-local class.** These 3 are already inline-matched in + `ov_SC01_077_a.c` (matched in 077, never propagated — the §19/20 cap), so `dedup_propagate --auto-from` + reports "nothing to propagate" (it can't auto-collapse an already-inline-matched fn into a shared + macro). They banked **×1** (ov_SC01_000 only). Realizing ×reach needs the **dedup-collapse** of the + inline copies into one `engine_core.h` macro — the existing Phase-19/20 lever. + +Net: the grinder/gate pipeline is now **fully binary-agnostic** (capability unlocked + validated), but the +reach-134 ×134 payoff routes through **corpus-v3** (better leaf drafts for the semantic-miss fuel) + the +**dedup-collapse** (for stuck-local inline matches) — NOT the permuter, which the bytes show isn't the +closer for this fuel. + ## Open questions / notes - **Corpus quality > size.** ~1,700 verified pairs is plenty for LoRA; dedup near-identical reach diff --git a/docs/progress.fleet.md b/docs/progress.fleet.md index 4e95392d8..4946a63b0 100644 --- a/docs/progress.fleet.md +++ b/docs/progress.fleet.md @@ -3,18 +3,18 @@ # source-derived (committed src/*.c + config/dedup.us.yaml). Live byte gate: `make check-all`; # cross-binary collapsible-byte leverage: docs/duplicates.cross.md. -FLEET REAL substantive : 217972 (of which dedup-shared 217219 via 1634 groups / 217270 instances) +FLEET REAL substantive : 217975 (of which dedup-shared 217219 via 1634 groups / 217270 instances) FLEET LINKED PsyQ objs : 959 -FLEET byte-identical : 219619 / 344941 = 63.67% (REAL+LINKED+empties) +FLEET byte-identical : 219622 / 344941 = 63.67% (REAL+LINKED+empties) FLEET NON_MATCHING : 7 (0 in any default build — G4) -FLEET INCLUDE_ASM stubs : 125315 +FLEET INCLUDE_ASM stubs : 125312 FLEET matchable : 344941 | binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % | |---|---:|---:|---:|---:|---:|---:| | main | 54 | 2 | 959 | 1055 | 2096 | 50.3% | | resident | 123 | 0 | 0 | 125 | 146 | 85.6% | -| ov_SC01_000 | 1632 | 1626 | 0 | 1632 | 2410 | 67.7% | +| ov_SC01_000 | 1635 | 1626 | 0 | 1635 | 2410 | 67.8% | | ov_SC01_001 | 1626 | 1626 | 0 | 1628 | 2474 | 65.8% | | ov_SC01_004 | 1617 | 1617 | 0 | 1618 | 2423 | 66.8% | | ov_SC01_005 | 1624 | 1624 | 0 | 1631 | 2511 | 65.0% | diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 7c822adc7..df4cd38bf 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -34,7 +34,7 @@ D. Periodically: `export_pairs → format_finetune → train_lora → redeploy` ## ▶ RESUME HERE (fresh session) **State:** Phase 23 in progress (NOT a phase end). Phase 22 closed (`PhaseEnd_Phase22.md`, uncommitted — Drew's gate-2 commit+push). The fine-tuned model **`bfm-match-7b-v2`** (Qwen2.5-Coder-7B QLoRA on corpus-v2) is built; **served by LM Studio** at `http://192.168.1.113:1234/v1` (model id `bfm-match-7b-v2`; GGUF at `models/bfm-match-7b_gguf/`). Corpus `datasets/match_pairs/` + training stack `.venv-train` (gitignored). **T7 FIXED** — the gate banks fleet-wide now (ov_SC01_000 7/15 byte-identical, +1 reach-2 propagated; @commit:0322 + the T7 checkpoint commit). The 0/222 was two harness bugs (good_sha format + src/asm/out 077-default), not the model. -**NEXT TASK — the grinder per-binary fix (to realize the reach≥2 ×134 synergy).** T7 (gate) and T9 reach≥2 targeting (`lora_grind --min-reach`) are DONE. The reach≥2 mass-run's verdict: the model banks **~0 on shared functions directly** (0/15 on ov_SC01_000's reach≥2 batch vs 7/15 reach-1), because the corpus skipped the shared `DEFINE_func` bodies and these are the harder regalloc tail — BUT it generated **3 close=1 reach-134 near-misses** (`func_8012E27C/BF4C/AD64`) = high-value permuter fuel (×134 each). The **permuter grinder** is the tool that closes close=1 regalloc/schedule near-misses — but `grinder.py` has the **same per-binary bug T7 fixed** (`run_gate` with no `binary` → ov_SC01_077; the backlog stores no `binary` field), so it can't gate a non-077 near-miss. Fix = (1) add a `binary` field to the backlog record in `gate_stage`, (2) thread it through `grinder.py`'s `run_gate` call; then run the grinder on the reach-134 close=1 fuel → ×134 banks. **SECOND lever:** corpus-v3 (struct types) to lift the model's DIRECT reach≥2 bank rate (the 2/15 compile-fails + the 0-direct-bank gap). +**NEXT TASK — corpus-v3 (better leaf drafts) + the dedup-collapse (stuck-local ×reach).** T7 (gate), T9 (reach targeting), and the grinder **per-binary fix (5-layer, validated)** are DONE. The grinder fix re-characterized the reach≥2 close=1 fuel (byte-evidenced): it's **MODEL semantic-misses, not permuter fuel** — the 7B drafts `void f(void){}` for functions that are literally `return 1` / trivial `sw`/`sh` setters (the corpus's overfit empty-leaf pattern); a **corrected draft** banks them (did: +3 byte-identical via the fixed per-binary gate, @commit:0326) — the permuter can't. AND ×reach is **propagation-capped**: the 3 are inline-matched in `ov_SC01_077_a.c` (the §19/20 stuck-local cap), so `dedup_propagate --auto-from` reports "nothing to propagate" → they banked ×1. So the two levers to the reach-134 ×134 payoff: (1) **corpus-v3** — fix the empty-leaf overfit (leaf variety: return-const + setters) so the model drafts these right + emit struct types for the compile-fails → retest free on the 7B; (2) **dedup-collapse** — collapse the inline-matched-in-077 stuck-local fns into shared `engine_core.h` macros so they propagate ×reach. The grinder is now wired for whatever genuinely-permuter-amenable (regalloc/schedule) near-misses future runs surface. **Run a bounded mass-run (when Drew says go):** ``` @@ -66,3 +66,4 @@ The **whole-binary byte-gate** (`gate_stage`/`harvest_verify`, G3/P9) is the sol - 2026-06-29: **Phase opened at PhaseEnd_Phase22 close (Drew).** Built across this session: cheap-tier A/B (T1, Haiku 4.8×/$), stock-local floor (T2, 0), the LoRA pipeline (T3) + corpus-v2 extern-fix (T4, 6–15 ins 0%→85%), first 4 real open-stub banks (T5, @commit:0320), the `lora_grind` mass-run driver (T6). Calibration run (T7) launched (500 fns) — **18% on ov_SC01_077 but 0/222 broad rotation → #1 debug.** gate_stage commit tag made phase-agnostic. The whole arc + measured numbers: `docs/gen2-mips-matching-model.md`; memory `cheap-tier-ab-validated`. NEXT: T7 debug, then bounded mass-runs + corpus-v3. - 2026-06-30: **T7 DEBUGGED + FIXED.** 3 Explore scouts (tooling / run-evidence / corpus) + a direct code read (R14 — which resolved a flat contradiction between two scouts) found **two independent bugs** in `lora_grind`'s gate path: **(A)** `good_sha()` passed `" "` vs harvest_verify's bare `sha1()` → 0 banks for ALL binaries incl. 077 (so 077's "0/12" was a bug artifact); **(B)** `src/asm/out` defaulted to ov_SC01_077 → non-077 drafts dropped at the 077 stub-filter, silently. Fixed `gate_stage.run_gate` (binary-agnostic resolution + bare-hash normalize + a loud negative-control guard) + `lora_grind.good_sha`; byte-neutral (check-all 136/136). ov_SC01_000 spot-run **banked 7/15 (47%) byte-identical** (@commit:0322) → reach-2 `func_8017CE24` propagated ×2. **ROI:** 6/7 reach-1 → broad rotation is high bank-rate / low fleet-% ROI; the fleet lever is **reach≥2 targeting** + corpus-v3. Backlog now correctly classified (4× close=1 = grinder fuel). NEXT: **T8 corpus-v3** (struct types) + **T9 reach≥2 selection** + concurrent grinder. - 2026-06-30 (cont.): **T9 reach≥2 targeting built + measured.** Added `lora_grind --min-reach N` (lazy sig-based reach oracle == `dedup_propagate`, validated 0-mismatch/60 + the func_8017CE24=2 ground truth; `--min-reach 2` ranks high-reach-first, naturally restricts to overlays). Bounded reach≥2 mass-run: ov_SC01_000's 15 reach≥2 (shared) stubs banked **0/15** (vs the reach-1 spot-run's 7/15) — the model is **weakest on shared code** (corpus skipped the `DEFINE_func` bodies + it's the regalloc/schedule tail). But **5/15 are close≤3 reach-134 near-misses** (3× close=1 = func_8012E27C/BF4C/AD64) → high-value permuter fuel (×134 each). **FINDING: reach≥2 model-only ≠ a fleet lever; the lever is reach≥2-draft → grinder-close (×134)**, which needs `grinder.py`'s per-binary fix (same class as T7) + a backlog `binary` field. (A foreground mass-run hit the 10-min Bash cap mid-2nd-batch; tree recovered clean via `git checkout`, check-all 136/136.) Details: `docs/gen2-mips-matching-model.md` "T9 RESULT". NEXT: the grinder per-binary fix (realize the reach-134 ×134 fuel), then corpus-v3. +- 2026-06-30 (cont.): **Grinder per-binary fix (5-layer) — built + validated; reach≥2 fuel re-characterized.** The grinder/backlog were ov_SC01_077-hardcoded **5 layers deep** — fixed all: `gate_stage` records `binary`, `backlog.FIELDS` keeps it, `backlog.load_best`/`_open_stubs` fleet-aware (stuck-local fns surface via their overlay record), `p16_permute.setup` takes asm-subdir, `grinder` per-binary resolution + grouped gating + None-`nins` allow. Validated: the 3 fresh reach-134 close=1 ov_SC01_000 fns now surface + resolve + gate per-000. **FINDINGS (byte-evidenced):** (a) the reach≥2 close=1 fuel is **MODEL semantic-misses** (7B drafts empty `void f(void){}` for trivial `return 1`/setters), NOT permuter fuel — a corrected draft banks them (**+3 byte-identical** via the fixed gate, @commit:0326); (b) ×reach is **propagation-capped** (inline-matched in `ov_SC01_077_a.c` → dedup "nothing to propagate" → banked ×1). So the reach-134 ×134 payoff routes through **corpus-v3** (leaf variety) + the **dedup-collapse**, NOT the permuter. check-all 136/136 throughout. Details: `docs/gen2-mips-matching-model.md` (grinder fix). NEXT: corpus-v3 + dedup-collapse. diff --git a/tools/backlog.py b/tools/backlog.py index 0008c5db2..45110881e 100644 --- a/tools/backlog.py +++ b/tools/backlog.py @@ -37,7 +37,7 @@ DRAFTS = os.path.join(REPO, ".run/backlog_drafts") SRC_GLOB = os.path.join(REPO, "src/ov_SC01_077/ov_SC01_077*.c") STUB_RE = re.compile(r"INCLUDE_ASM\([^,]+,\s*(\w+)\)") FIELDS = ("ts", "addr", "name", "reach", "klass", "nins", "status", - "closeness", "where_stuck", "best_draft", "source") + "closeness", "where_stuck", "best_draft", "binary", "source") def append_record(rec): @@ -61,19 +61,29 @@ def save_draft(name, text): return os.path.relpath(p, REPO) -def _matched_now(): - """Set of func names that are NO LONGER INCLUDE_ASM stubs (i.e. banked) — dropped from the table.""" - stubs = set() - for p in glob.glob(SRC_GLOB): - stubs |= set(STUB_RE.findall(open(p).read())) - return stubs # a name in `stubs` is still OPEN; not in `stubs` => matched/gone +_STUB_CACHE = {} + + +def _open_stubs(binary): + """INCLUDE_ASM stub names still OPEN in 's source (main + any _a/_o0 split). Fleet-aware: + a fn matched in ov_SC01_077 but propagation-stuck stays OPEN in the other overlays (the Phase-19/20 + cap), so the grinder must judge open-ness against the record's OWN binary, not just 077.""" + if binary not in _STUB_CACHE: + s = set() + for p in glob.glob(os.path.join(REPO, f"src/{binary}/{binary}*.c")): + s |= set(STUB_RE.findall(open(p).read())) + _STUB_CACHE[binary] = s + return _STUB_CACHE[binary] def load_best(): - """Best (lowest closeness, latest ts) record per addr, restricted to still-open (unmatched) fns.""" + """Best (lowest closeness, latest ts) record per addr, restricted to fns still OPEN in their OWN + binary (rec['binary']; legacy records default ov_SC01_077). Fleet-aware so a 077-matched-but- + stuck-local fn surfaces via its overlay record — the grinder must SEE it to grind it (P9 honesty: + a fn banked in its own binary since logged is dropped).""" if not os.path.exists(JSONL): return [] - open_stubs = _matched_now() + _STUB_CACHE.clear() best = {} for line in open(JSONL): line = line.strip() @@ -81,7 +91,8 @@ def load_best(): continue r = json.loads(line) nm = r.get("name") - if nm and nm not in open_stubs: # banked since logged -> drop (P9 honesty) + binary = r.get("binary") or "ov_SC01_077" + if nm and nm not in _open_stubs(binary): # banked in ITS binary since logged -> drop (P9) continue key = r.get("addr") or nm cur = best.get(key) diff --git a/tools/gate_stage.py b/tools/gate_stage.py index 149583e88..b649df384 100644 --- a/tools/gate_stage.py +++ b/tools/gate_stage.py @@ -213,7 +213,7 @@ def _run_gate_locked(drafts, binary, src, asm, out, good_sha, propagate, source_ backlog.append_record({"addr": meta.get("addr"), "name": fn, "reach": meta.get("reach"), "klass": rclass or meta.get("class"), "nins": meta.get("nins"), "status": status, "closeness": close, "where_stuck": where, "best_draft": draft_path, - "source": source_tag}) + "binary": binary, "source": source_tag}) # binary: lets the grinder gate non-077 near-misses backlog.render() fp = None diff --git a/tools/grinder.py b/tools/grinder.py index 59639f62f..0d860997d 100644 --- a/tools/grinder.py +++ b/tools/grinder.py @@ -47,6 +47,12 @@ def log(m): print(f"[{time.strftime('%H:%M:%S')}] grinder: {m}", flush=True) +def asm_subdir_for(binary, fn): + """the asm subdir holding binary's .s (main or _a/_o0 split); None if absent.""" + g = glob.glob(os.path.join(REPO, f"asm/{binary}/nonmatchings/*/{fn}.s")) + return os.path.dirname(os.path.relpath(g[0], REPO)) if g else None + + def heartbeat(state, current=None, banked=0, fp=None): os.makedirs(os.path.join(REPO, AUTODIR), exist_ok=True) json.dump({"ts": time.strftime("%Y-%m-%d %H:%M:%S"), "state": state, "current": current, @@ -68,7 +74,7 @@ def candidates(max_nins, max_close, tried, attempts, blacklist): c = r.get("closeness") if c is None or c > max_close: # permuter closes small regalloc/sched gaps, not large rewrites continue - if (r.get("nins") or 999) > max_nins: + if r.get("nins") is not None and r["nins"] > max_nins: # known-too-big; None (off-077 manifest) = allow continue if not os.path.exists(os.path.join(REPO, r["best_draft"])): continue @@ -116,36 +122,46 @@ def main(): if os.path.exists(os.path.join(REPO, DRAFTS)): shutil.rmtree(os.path.join(REPO, DRAFTS)) os.makedirs(os.path.join(REPO, DRAFTS), exist_ok=True) - won_fns = [] + won = [] # (fn, binary): gate grouped by binary (harvest_verify filters) for r in cand: if stop_requested(): break fn = r["name"]; tried[fn] = tried.get(fn, 0) + 1 + binary = r.get("binary") or "ov_SC01_077" # legacy records: the canonical site (a 077-stub fn still gates) + asm_sub = asm_subdir_for(binary, fn) heartbeat("permuting", fn, banked, fp) try: + if not asm_sub: + log(f"{fn}: no .s under {binary} — skip"); continue draft = open(os.path.join(REPO, r["best_draft"])).read() - pd = p16_permute.setup(fn, draft) + pd = p16_permute.setup(fn, draft, asm_sub) if not pd: continue win = p16_permute.run_permuter(pd, a.permute_secs, a.j) if win: open(os.path.join(REPO, DRAFTS, fn + ".c"), "w").write( p16_permute.winner_to_draft(open(win).read())) - won_fns.append(fn); log(f"permuter WON {fn} (close was {r.get('closeness')})") + won.append((fn, binary)); log(f"permuter WON {fn} @ {binary} (close was {r.get('closeness')})") except Exception as e: log(f"{fn}: {e}") - if won_fns: + if won: heartbeat("gating", None, banked, fp) - s = gate_stage.run_gate(DRAFTS, source_tag="grinder", commit=True) - banked += s.get("banked", 0); fp = s.get("fleet_pct", fp) + import collections + by_bin = collections.defaultdict(list) + for fn, binary in won: + by_bin[binary].append(fn) + verified = set() + for binary, fns in sorted(by_bin.items()): # one gate per source binary; propagate stamps × reach + s = gate_stage.run_gate(DRAFTS, binary=binary, source_tag="grinder", commit=True) + banked += s.get("banked", 0); fp = s.get("fleet_pct", fp) + verified |= set(s.get("verified", [])) + log(f"gate {binary}: banked {s.get('banked')} (+{s.get('propagated')} prop); total {banked}; fleet {fp}%") # A permuter win the whole-binary gate STILL rejects is plumbing-bound (not regalloc/sched) — - # re-permuting can never bank it. Blacklist it so the grinder stops churning it (the §20 trap). - verified = set(s.get("verified", [])) - rejected = [f for f in won_fns if f not in verified] + # re-permuting can never bank it. Blacklist so the grinder stops churning it (the §20 trap). + rejected = [f for f, _b in won if f not in verified] if rejected: blacklist.update(rejected); save_blacklist(blacklist) log(f"blacklisted {len(rejected)} permuter-won/gate-rejected (plumbing): {', '.join(rejected)}") - log(f"gate: banked {s.get('banked')} (+{s.get('propagated')} prop); total {banked}; fleet {fp}%") heartbeat("running", None, banked, fp) if a.once: log(f"once done — banked {banked}."); heartbeat("done", None, banked, fp); return diff --git a/tools/p16_permute.py b/tools/p16_permute.py index 9c420d4ca..b8b43ee1b 100644 --- a/tools/p16_permute.py +++ b/tools/p16_permute.py @@ -98,13 +98,13 @@ def winner_to_draft(winner_c): return drop_preproc_and_scalar_typedefs(winner_c) -def setup(fn, draft_c): +def setup(fn, draft_c, asm_subdir=ASM): pd = os.path.join(REPO, ".run/permuter", fn) if os.path.exists(pd): shutil.rmtree(pd) os.makedirs(pd) open(f"{pd}/base.c", "w").write(make_base_c(draft_c)) - s = os.path.join(REPO, ASM, fn + ".s") + s = os.path.join(REPO, asm_subdir, fn + ".s") tgt = f"{pd}/target.s" with open(tgt, "w") as f: f.write('.set noat\n.set noreorder\n.include "macro.inc"\n.section .text\n\n')