diff --git a/.run/P32/t3/opus/func_8001BC6C_s83.c b/.run/P32/t3/opus/func_8001BC6C_s83.c new file mode 100644 index 0000000000..cdc1b4d58c --- /dev/null +++ b/.run/P32/t3/opus/func_8001BC6C_s83.c @@ -0,0 +1,71 @@ +/* addPrim-style sprite emitter (S83 MATCH — 28 -> 6 by the §500-C levers, 6 -> 0 by the two permuter_ils levers below): builds a 0x18-byte SPRT-with-tpage packet at the + * D_800A5E60 prim-buffer cursor and addPrim()s it onto word [1] of the frame's + * ordering table (D_800A6610 + D_800B9A02 * 0x4000). Same idiom as the -O0 + * func_8001212C in src/boot.c. */ +typedef struct { u32 addr : 24; u32 len : 8; } PTag_8001BC6C; + +extern u16 D_800B9A02; +extern u8 D_800A6610[]; +extern u8 *D_800A5E60; + +void func_8001BC6C(s32 a0, s32 a1) +{ + short *p1 = (short *)a0; + u8 *p; + u32 *ot; + register u32 color __asm__("$5"); + register short f0 __asm__("$2"); + u32 tag; + u32 c; + u32 c2; + u32 k; + u32 idx; + u32 code; + unsigned short f1; + short f2; + unsigned short f3; + unsigned short x1; + unsigned short y1; + short t0; + + code = 0x100; + /* §47 live-length lever (S83, found by permuter_ils then re-spelled well-defined): birthing `tag` + * (and `k`) HERE lengthens their pseudos' live ranges so local-alloc's qty_compare ranks the OT + * index above the base — the $v0/$v1 swap across the six OT-chain insns disappears. The value is + * recomputed below; the early statement exists only for the allocator. Paired with `idx` computed + * AFTER `color` (the second lever). Every well-defined alternative birth (tag = a1 << 8, tag = 0, + * k first) measured 8–20 mismatches. */ + k = 0; + tag = (a1 << 8) | k; + c = a1 << 16; + k = 0x64000000; + f0 = p1[0]; + f1 = p1[1]; + f2 = p1[2]; + f3 = p1[3]; + p = D_800A5E60; + x1 = f0 - 0xA0; + y1 = f1 - 0x78; + t0 = f0; + tag = (a1 << 8) | k; + c2 = c | tag; + color = c2 | a1; + idx = D_800B9A02 << 14; + ot = (u32 *)(idx + (u32)D_800A6610); + + if (t0 >= 0x80) { + t0 -= 0x80; + code = 0x102; + } + + *(u8 *)(p + 3) = 5; + *(u32 *)(p + 4) = code | 0xE1000000; + *(u8 *)(p + 0xB) = 100; + *(u32 *)(p + 0xC) = ((u32)y1 << 16) | (u32)x1; + *(u32 *)(p + 0x10) = (u32)(((s32)((u32)f1 << 16) >> 8) | (s32)t0); + *(u32 *)(p + 8) = color; + *(u32 *)(p + 0x14) = ((u32)f3 << 16) | (u32)f2; + ((PTag_8001BC6C *)p)->addr = ((PTag_8001BC6C *)(ot + 1))->addr; + D_800A5E60 = p + 0x18; + ((PTag_8001BC6C *)(ot + 1))->addr = (u32)p; +} diff --git a/.run/P32/t3/verdicts.jsonl b/.run/P32/t3/verdicts.jsonl index 57d2a38133..6c5f49dc66 100644 --- a/.run/P32/t3/verdicts.jsonl +++ b/.run/P32/t3/verdicts.jsonl @@ -46,3 +46,4 @@ {"fn": "func_801CBB80", "binary": "md_SC03_056", "arm": "haiku", "status": "MATCH", "closeness": null, "compiles": true, "draft_path": ".run/P32/t3/haiku/func_801CBB80.c", "note": "if-then pattern with conditional function calls (twin ov_SC06_025:0x8017ded8 route). All symbols matched from target asm relocs.", "session": "491895ad"} {"fn": "func_800CD4C8", "binary": "md_MAIN_009", "arm": "haiku", "status": "MATCH", "closeness": null, "compiles": true, "draft_path": ".run/P32/t3/haiku/func_800CD4C8.c", "note": "Immediate MATCH - simple global reference-count pattern with decrement and conditional branch", "session": "491895ad"} {"fn": "func_800CD520", "binary": "md_MAIN_009", "arm": "haiku", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t3/haiku/func_800CD520.c", "note": "Self-defining rodata at file scope (§304); wrapper calling func_8001AD38 with D_800CD364, stores 0 to D_800CDD34, calls func_800116A0 (twin ov_SC03_011:0x8017dbd8 route)", "session": "491895ad"} +{"fn": "func_8001BC6C", "binary": "main", "arm": "permuter_ils+coordinator", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t3/opus/func_8001BC6C_s83.c", "note": "permuter_ils 8x150s on the Opus seed (6) reached masked 1 via three mutations; the &0xFF load-narrowing was semantically wrong (R63) and dropped; the two sound levers (idx computed AFTER color; tag/k birthed early) reproduce 69/69; re-spelled well-defined as `k = 0; tag = (a1 << 8) | k;` (I1) — all other early-birth spellings 8-20 off; gate_main BANKED 143dbb89", "session": "491895ad"} diff --git a/.run/P32/t3s3/gate/gate_main3.log b/.run/P32/t3s3/gate/gate_main3.log new file mode 100644 index 0000000000..47655537f0 --- /dev/null +++ b/.run/P32/t3s3/gate/gate_main3.log @@ -0,0 +1,47 @@ +slate 1 -> 1 compatible, 0 dropped for in-TU decl conflict + +BUILD FAILED (no binary produced). Error lines from the build: + make: *** No rule to make target 'build/src/.masked_diff_probe.3973390.o', needed by 'build/us/SLUS_007.26'. Stop. + make: *** Waiting for unfinished jobs.... + src/800_c.c:2855: warning: type mismatch with previous implicit declaration + src/800_c.c:2544: warning: previous implicit declaration of `func_80038908' + src/800_c.c:2855: warning: `func_80038908' was previously implicitly declared to return `int' + src/800.c:630: warning: type mismatch with previous implicit declaration + src/800.c:625: warning: previous implicit declaration of `func_80012E0C' + src/800.c:686: warning: type mismatch with previous implicit declaration + src/800.c:683: warning: previous implicit declaration of `func_80013028' + src/800.c:1739: warning: type mismatch with previous implicit declaration + src/800.c:1659: warning: previous implicit declaration of `func_800143AC' + src/800.c:1739: warning: `func_800143AC' was previously implicitly declared to return `int' + src/800.c:1783: warning: type mismatch with previous implicit declaration + src/800.c:1660: warning: previous implicit declaration of `func_80014444' + src/800.c:1783: warning: `func_80014444' was previously implicitly declared to return `int' + src/800.c:1850: warning: type mismatch with previous implicit declaration + src/800.c:1662: warning: previous implicit declaration of `func_80014588' + src/800.c:1850: warning: `func_80014588' was previously implicitly declared to return `int' + src/800.c:2013: warning: type mismatch with previous implicit declaration + src/800.c:1654: warning: previous implicit declaration of `func_80014928' + src/800.c:2013: warning: `func_80014928' was previously implicitly declared to return `int' + src/800.c:2576: warning: type mismatch with previous implicit declaration + src/800.c:1663: warning: previous implicit declaration of `func_80015310' + src/800.c:2576: warning: `func_80015310' was previously implicitly declared to return `int' + src/800.c:2601: warning: type mismatch with previous implicit declaration + src/800.c:2597: warning: previous implicit declaration of `func_800153A4' + src/800.c:2601: warning: `func_800153A4' was previously implicitly declared to return `int' + src/800.c:2619: warning: type mismatch with previous implicit declaration + src/800.c:2615: warning: previous implicit declaration of `func_80015424' + src/800.c:2619: warning: `func_80015424' was previously implicitly declared to return `int' + src/800.c:4141: warning: type mismatch with previous implicit declaration + src/800.c:4108: warning: previous implicit declaration of `func_80016A7C' + src/800.c:4141: warning: `func_80016A7C' was previously implicitly declared to return `int' + src/800.c:4572: warning: type mismatch with previous implicit declaration + src/800.c:4470: warning: previous implicit declaration of `func_80016F18' + src/800.c:4572: warning: `func_80016F18' was previously implicitly declared to return `int' + src/800.c:4755: warning: type mismatch with previous implicit declaration + src/800.c:4706: warning: previous implicit declaration of `func_80017294' + src/800.c:4755: warning: `func_80017294' was previously implicitly declared to return `int' + src/800.c:4844: warning: type mismatch with previous implicit declaration + +batch FAILED (sha None); bisecting + +BANKED 1 of 1 after bisection in 1 rebuild(s) -- 143dbb89f34491258bbc27810d0a12ec8b43a8dd BYTE-IDENTICAL diff --git a/.run/P32/t3s3/gate/slate_main3.json b/.run/P32/t3s3/gate/slate_main3.json new file mode 100644 index 0000000000..98c04a9d24 --- /dev/null +++ b/.run/P32/t3s3/gate/slate_main3.json @@ -0,0 +1 @@ +[{"fn":"func_8001BC6C","draft":"/home/musashi/bfm-decomp/.run/P32/t3/opus/func_8001BC6C_s83.c"}] diff --git a/.run/P32/t3s3/ils_func_8001BC6C.log b/.run/P32/t3s3/ils_func_8001BC6C.log index b450510e67..c8ffdaab4e 100644 --- a/.run/P32/t3s3/ils_func_8001BC6C.log +++ b/.run/P32/t3s3/ils_func_8001BC6C.log @@ -1 +1,11 @@ ILS func_8001BC6C: 8 cycles x 150s @ -j3, klass=REGALLOC + cycle 1: no waypoint (no improvement over base yet) + cycle 2: no waypoint (no improvement over base yet) + cycle 3: no waypoint (no improvement over base yet) + cycle 4: no waypoint (no improvement over base yet) + cycle 5: no waypoint (no improvement over base yet) + cycle 6: best score = 6 [output-6-1] + cycle 7: best score = 5 [output-5-1] + cycle 8: best score = 1 [output-1-1] +ILS done: best=1 (no score-0; seed for Fable5 or a longer run) +EXIT=0 diff --git a/.run/P32/t3s3/ils_func_800CD674.log b/.run/P32/t3s3/ils_func_800CD674.log index 8b21d8c1df..cdb929ebe5 100644 --- a/.run/P32/t3s3/ils_func_800CD674.log +++ b/.run/P32/t3s3/ils_func_800CD674.log @@ -1 +1,11 @@ ILS func_800CD674: 8 cycles x 150s @ -j3, klass=REGALLOC + cycle 1: no waypoint (no improvement over base yet) + cycle 2: no waypoint (no improvement over base yet) + cycle 3: no waypoint (no improvement over base yet) + cycle 4: best score = 2 [output-2-1] + cycle 5: best score = 2 (unchanged) [output-2-1] + cycle 6: best score = 2 (unchanged) [output-2-1] + cycle 7: best score = 2 (unchanged) [output-2-1] + cycle 8: best score = 2 (unchanged) [output-2-1] +ILS done: best=2 (no score-0; seed for Fable5 or a longer run) +EXIT=0 diff --git a/.run/backlog.jsonl b/.run/backlog.jsonl index 7c388219cd..0a1e8ada54 100644 --- a/.run/backlog.jsonl +++ b/.run/backlog.jsonl @@ -18,3 +18,4 @@ {"ts": "2026-09-05 10:57:05", "addr": "0x8017dc80", "name": "func_8017DC80", "reach": null, "klass": "FRAME", "nins": 346, "status": "near", "closeness": 46, "where_stuck": "the historic -33 LENGTH wall CLOSED (GTE macros must be REAL macros \u2014 the TU house block; the splat Handwritten tag is wrong): 346/346, exact 0x70 frame + 9 callee-saved. Residual: reload-slot frame + the la $a0 slot; cse1 unifies OT index and n<4 across func_80010A08(8) (\u00a7500-D2 zero-byte asm retire)", "best_draft": ".run/P32/t3/opus/func_8017DC80.c", "binary": "ov_SC07_002", "source": "P32-T3 one Opus agent 30-70min; \u00a7500-C; report .run/P32/t3/reports/", "residual": null, "passes_tried": null} {"ts": "2026-09-05 10:57:05", "addr": "0x800cf408", "name": "func_800CF408", "reach": null, "klass": "SCHED", "nins": 178, "status": "near", "closeness": 49, "where_stuck": "[permuter] 3 hunks: two prologue sched2 slots, an mlo/mhi allocno tie, a 3-insn block-2 head hoist. Two LENGTH-bearing pins found (tp $17 shared by 0xE1000087/97 = the 6th callee-saved; ob $10 fixes the $t1/$t2/$t3 rotation, 56->49). \u00a7351 family (func_8001212C -O0 / func_8017DD04 -O2 exemplars)", "best_draft": ".run/P32/t3/opus/func_800CF408.c", "binary": "md_MAIN_007", "source": "P32-T3 one Opus agent 30-70min; \u00a7500-C; report .run/P32/t3/reports/", "residual": null, "passes_tried": null} {"ts": "2026-09-05 10:57:06", "addr": "0x800cf6d0", "name": "func_800CF6D0", "reach": null, "klass": "SCHED", "nins": 249, "status": "near", "closeness": 137, "where_stuck": "sched1 rank_for_schedule last-insn-CLASS tie (every store priority 2, equal refs; QImode stores grouped, loads floated, HImode after \u2014 5 of 6 blocks) + $t1<->$t3 local-alloc swap of the two masks. 249/249 exact length only with tpage-before-len field order (19 swept). Inert at 137: pins on tpage constants/masks, asm re-ties, volatile/memory fences, /s-denial on any store subset, *0x4000 vs <<14, p++ vs p+0x18, | swap. decomp-permuter 122 was semantically wrong (R63)", "best_draft": ".run/P32/t3/opus/func_800CF6D0.c", "binary": "md_MAIN_007", "source": "P32-T3 one Opus agent 30-70min; \u00a7500-C; report .run/P32/t3/reports/", "residual": null, "passes_tried": null} +{"ts": "2026-09-05 11:31:53", "addr": "0x800cd674", "name": "func_800CD674", "reach": null, "klass": "REGALLOC-PERM", "nins": 174, "status": "near", "closeness": 2, "where_stuck": "S83 permuter_ils 8 cycles x 150 s: best waypoint output-2-1 = the SAME 2-row $a3<->$t1 REGALLOC-LOCAL pair (and 156/or 164), no semantic drift; the pinned seed is a genuine local-alloc tie the permuter cannot cross. Prior: one shared local can be only one of $a3/$t1; splitting = +1 pseudo (31). NEXT: only a NEW idiom (a way to give prim 3 and prim 4 different masked-p lifetimes without a new pseudo) reopens it", "best_draft": ".run/P32/t3/opus/func_800CD674.c", "binary": "md_MAIN_009", "source": "P32-T3 S83 permuter_ils 8x150s -j3 (klass REGALLOC): plateau, 0 tokens, ~20 min compute", "residual": null, "passes_tried": null} diff --git a/docs/backlog.md b/docs/backlog.md index 57a7145c93..0f3591a941 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:** 15 · by status {'near': 14, 'failed': 1} · by class {None: 6, 'REGALLOC-PERM': 2, 'SCHED': 4, 'REGALLOC': 1, 'ALIAS': 1, 'FRAME': 1} +**Open near-misses:** 14 · by status {'near': 13, 'failed': 1} · by class {None: 6, 'REGALLOC-PERM': 1, 'SCHED': 4, 'REGALLOC': 1, 'ALIAS': 1, 'FRAME': 1} | # | addr | reach | class | nins | status | closeness | where it stuck | best draft | |--:|------|------:|-------|-----:|--------|----------:|----------------|------------| @@ -12,12 +12,11 @@ | 4 | func_80039DEC | None | | None | near | 2 | S80 permuter_ils best 2 (seed 9); 74/74 exact length match, OPCODE-MIXED. Key levers that moved the residual from the seed's 74-vs-72-length structural failure down to 9: (1) K&R old-style definition for a2 (s16 a2 in the identifier-declaration form) reproduces the target's in-place sll/sra-16 arg-register cast + its addu $a3,$a2,zero raw-preserve, which no ANSI (s16)-cast or s32-typed spelling ever produced; (2) forward-goto bloc | `/home/musashi/bfm-decomp/.run/S79w/sonnet/func_80039DEC.c` | | 5 | func_8017DF28 | None | | None | near | 2 | S80 permuter_ils 8x150s: waypoint '1' replaced the addiu $s2,$sp,0x10 with sw zero,48(sp) (semantically divergent, R14) -> closeness stays 2; 119/119; single SCHEDULE residual: addiu $s2,sp,0x10 sits in the jal's delay slot vs the target's bnez slot — expand_block_move's copy_addr_to_reg pseudo for mtx=D_800AE620 is cse-reused for both later &mtx args (gcc-2.7.2-map cse_expr.md [A23-2]/§H). Field-wise copy regresses to 117 (a real loop); the §H diamond cse-reset is a byte-identical no-op (no 2-predecessor merge to exploit). Fifth RTL-ve | `.run/S79w/sonnet/func_8017DF28.c` | | 6 | func_800391D4 | None | | None | near | 3 | 75/75 instructions (exact length), only residual is a 3-insn SCHEDULE-REORDER (off=0 vs arg1's sll/sra pair rotated) classified bucket=permuter. Cracked the 4-prior-attempt wall (best prior closeness 64, LENGTH-DRIFT+1) via register-pin i=$7 to kill combine_givs on D_80073140[i], a 2D-array decl D_80073140[][1] (cookbook SS164-26) to stop move_movables hoisting the address instead of folding it in | `/home/musashi/bfm-decomp/.run/S79w/sonnet/func_800391D4.c` | -| 7 | func_8001BC6C | None | REGALLOC-PERM | 69 | near | 6 | $v0<->$v1 swap across the six OT-chain insns: local-alloc qty_compare priority one span unit (base 2/2=1.0 > index 8/9=0.889); needs one fewer insn between the lhu and addu at sched1; color must stay pinned $5 (-18 without). 28->6 via P_TAG bitfield RMW + named inner term + emitted-order statements. NEXT: permuter_ils on the pinned seed (§494) | `.run/P32/t3/opus/func_8001BC6C.c` | -| 8 | func_800CD92C | None | SCHED | 247 | near | 15 | map §S7 prologue WEAVE: the {sw,lui,ori} groups for 0xE100008D/8F land after the 9-insn li block instead of before — the §17 pins reproduce the ALLOCATION but the hoist happens in sched2. Same SPRT family as func_800CD674 (§364 mirror levers applied) | `.run/P32/t3/opus/func_800CD92C.c` | -| 9 | func_80039308 | None | REGALLOC | 518 | near | 17 | sched2 + cross-block regalloc: preheader 49/50 swap, un-spellable addu $a2,$a0,$zero (every p=r form cse-propagated), a temp on $t0 vs $s7, and 11 insns of one alias fact (2nd D_80073140[j] load cannot schedule above the D_800C7D20 store from C; /s unlock costs the address allocation, net 20-24). 34->17 via s16 b4 widening copy + dead-local identity sweep (.run/P32/t3/restored/sweep_func_80039308.py) + $2 pin. permuter_ils --klass REGALLOC 2x150s: no gain | `.run/P32/t3/opus/func_80039308.c` | -| 10 | func_800CF3E8 | None | ALIAS | 469 | near | 27 | ONE cause: the pinned-base alias basin (§500-D1) in the p5/p6 tail; blocks 1-2 byte-exact (idx 0-361). 54->27 via blk2 constant birth order + birthing-boost local w60 + §194-A fence relocation. Inert: all 9 pins load-bearing (+5..+1409), asm position x7, h6 hoist 32x2, tag reshape, P_TAG ADDPRIM, array p6 stores, ~92k annealed variants. Untested: an unpinned alias of p6 for the tag load alone (ONE Opus second look allowed) | `.run/P32/t3/opus/func_800CF3E8.c` | -| 11 | func_80185810 | None | SCHED | 489 | near | 35 | [permuter] 4 emission windows (see report .run/P32/t3/reports/func_80185810__opus__*.md); exact length, rtu-clean | `.run/P32/t3/opus/func_80185810.c` | -| 12 | func_8017DC80 | None | FRAME | 346 | near | 46 | the historic -33 LENGTH wall CLOSED (GTE macros must be REAL macros — the TU house block; the splat Handwritten tag is wrong): 346/346, exact 0x70 frame + 9 callee-saved. Residual: reload-slot frame + the la $a0 slot; cse1 unifies OT index and n<4 across func_80010A08(8) (§500-D2 zero-byte asm retire) | `.run/P32/t3/opus/func_8017DC80.c` | -| 13 | func_800CF408 | None | SCHED | 178 | near | 49 | [permuter] 3 hunks: two prologue sched2 slots, an mlo/mhi allocno tie, a 3-insn block-2 head hoist. Two LENGTH-bearing pins found (tp $17 shared by 0xE1000087/97 = the 6th callee-saved; ob $10 fixes the $t1/$t2/$t3 rotation, 56->49). §351 family (func_8001212C -O0 / func_8017DD04 -O2 exemplars) | `.run/P32/t3/opus/func_800CF408.c` | -| 14 | func_800CF6D0 | None | SCHED | 249 | near | 137 | sched1 rank_for_schedule last-insn-CLASS tie (every store priority 2, equal refs; QImode stores grouped, loads floated, HImode after — 5 of 6 blocks) + $t1<->$t3 local-alloc swap of the two masks. 249/249 exact length only with tpage-before-len field order (19 swept). Inert at 137: pins on tpage constants/masks, asm re-ties, volatile/memory fences, /s-denial on any store subset, *0x4000 vs <<14, p++ vs p+0x18, / swap. decomp-permuter 122 was semantically wrong (R63) | `.run/P32/t3/opus/func_800CF6D0.c` | -| 15 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | +| 7 | func_800CD92C | None | SCHED | 247 | near | 15 | map §S7 prologue WEAVE: the {sw,lui,ori} groups for 0xE100008D/8F land after the 9-insn li block instead of before — the §17 pins reproduce the ALLOCATION but the hoist happens in sched2. Same SPRT family as func_800CD674 (§364 mirror levers applied) | `.run/P32/t3/opus/func_800CD92C.c` | +| 8 | func_80039308 | None | REGALLOC | 518 | near | 17 | sched2 + cross-block regalloc: preheader 49/50 swap, un-spellable addu $a2,$a0,$zero (every p=r form cse-propagated), a temp on $t0 vs $s7, and 11 insns of one alias fact (2nd D_80073140[j] load cannot schedule above the D_800C7D20 store from C; /s unlock costs the address allocation, net 20-24). 34->17 via s16 b4 widening copy + dead-local identity sweep (.run/P32/t3/restored/sweep_func_80039308.py) + $2 pin. permuter_ils --klass REGALLOC 2x150s: no gain | `.run/P32/t3/opus/func_80039308.c` | +| 9 | func_800CF3E8 | None | ALIAS | 469 | near | 27 | ONE cause: the pinned-base alias basin (§500-D1) in the p5/p6 tail; blocks 1-2 byte-exact (idx 0-361). 54->27 via blk2 constant birth order + birthing-boost local w60 + §194-A fence relocation. Inert: all 9 pins load-bearing (+5..+1409), asm position x7, h6 hoist 32x2, tag reshape, P_TAG ADDPRIM, array p6 stores, ~92k annealed variants. Untested: an unpinned alias of p6 for the tag load alone (ONE Opus second look allowed) | `.run/P32/t3/opus/func_800CF3E8.c` | +| 10 | func_80185810 | None | SCHED | 489 | near | 35 | [permuter] 4 emission windows (see report .run/P32/t3/reports/func_80185810__opus__*.md); exact length, rtu-clean | `.run/P32/t3/opus/func_80185810.c` | +| 11 | func_8017DC80 | None | FRAME | 346 | near | 46 | the historic -33 LENGTH wall CLOSED (GTE macros must be REAL macros — the TU house block; the splat Handwritten tag is wrong): 346/346, exact 0x70 frame + 9 callee-saved. Residual: reload-slot frame + the la $a0 slot; cse1 unifies OT index and n<4 across func_80010A08(8) (§500-D2 zero-byte asm retire) | `.run/P32/t3/opus/func_8017DC80.c` | +| 12 | func_800CF408 | None | SCHED | 178 | near | 49 | [permuter] 3 hunks: two prologue sched2 slots, an mlo/mhi allocno tie, a 3-insn block-2 head hoist. Two LENGTH-bearing pins found (tp $17 shared by 0xE1000087/97 = the 6th callee-saved; ob $10 fixes the $t1/$t2/$t3 rotation, 56->49). §351 family (func_8001212C -O0 / func_8017DD04 -O2 exemplars) | `.run/P32/t3/opus/func_800CF408.c` | +| 13 | func_800CF6D0 | None | SCHED | 249 | near | 137 | sched1 rank_for_schedule last-insn-CLASS tie (every store priority 2, equal refs; QImode stores grouped, loads floated, HImode after — 5 of 6 blocks) + $t1<->$t3 local-alloc swap of the two masks. 249/249 exact length only with tpage-before-len field order (19 swept). Inert at 137: pins on tpage constants/masks, asm re-ties, volatile/memory fences, /s-denial on any store subset, *0x4000 vs <<14, p++ vs p+0x18, / swap. decomp-permuter 122 was semantically wrong (R63) | `.run/P32/t3/opus/func_800CF6D0.c` | +| 14 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | diff --git a/src/800.c b/src/800.c index 176bf4e904..2c2a0a7501 100644 --- a/src/800.c +++ b/src/800.c @@ -9147,7 +9147,77 @@ void func_8001BBBC(s32 a0, s32 a1, u8 a2) tbl[1] = tmp; } -INCLUDE_ASM("asm/nonmatchings/800", func_8001BC6C); +/* addPrim-style sprite emitter (S83 MATCH — 28 -> 6 by the §500-C levers, 6 -> 0 by the two permuter_ils levers below): builds a 0x18-byte SPRT-with-tpage packet at the + * D_800A5E60 prim-buffer cursor and addPrim()s it onto word [1] of the frame's + * ordering table (D_800A6610 + D_800B9A02 * 0x4000). Same idiom as the -O0 + * func_8001212C in src/boot.c. */ +typedef struct { u32 addr : 24; u32 len : 8; } PTag_8001BC6C; + +extern u16 D_800B9A02; +extern u8 D_800A6610[]; +extern u8 *D_800A5E60; + +void func_8001BC6C(s32 a0, s32 a1) +{ + short *p1 = (short *)a0; + u8 *p; + u32 *ot; + register u32 color __asm__("$5"); + register short f0 __asm__("$2"); + u32 tag; + u32 c; + u32 c2; + u32 k; + u32 idx; + u32 code; + unsigned short f1; + short f2; + unsigned short f3; + unsigned short x1; + unsigned short y1; + short t0; + + code = 0x100; + /* §47 live-length lever (S83, found by permuter_ils then re-spelled well-defined): birthing `tag` + * (and `k`) HERE lengthens their pseudos' live ranges so local-alloc's qty_compare ranks the OT + * index above the base — the $v0/$v1 swap across the six OT-chain insns disappears. The value is + * recomputed below; the early statement exists only for the allocator. Paired with `idx` computed + * AFTER `color` (the second lever). Every well-defined alternative birth (tag = a1 << 8, tag = 0, + * k first) measured 8–20 mismatches. */ + k = 0; + tag = (a1 << 8) | k; + c = a1 << 16; + k = 0x64000000; + f0 = p1[0]; + f1 = p1[1]; + f2 = p1[2]; + f3 = p1[3]; + p = D_800A5E60; + x1 = f0 - 0xA0; + y1 = f1 - 0x78; + t0 = f0; + tag = (a1 << 8) | k; + c2 = c | tag; + color = c2 | a1; + idx = D_800B9A02 << 14; + ot = (u32 *)(idx + (u32)D_800A6610); + + if (t0 >= 0x80) { + t0 -= 0x80; + code = 0x102; + } + + *(u8 *)(p + 3) = 5; + *(u32 *)(p + 4) = code | 0xE1000000; + *(u8 *)(p + 0xB) = 100; + *(u32 *)(p + 0xC) = ((u32)y1 << 16) | (u32)x1; + *(u32 *)(p + 0x10) = (u32)(((s32)((u32)f1 << 16) >> 8) | (s32)t0); + *(u32 *)(p + 8) = color; + *(u32 *)(p + 0x14) = ((u32)f3 << 16) | (u32)f2; + ((PTag_8001BC6C *)p)->addr = ((PTag_8001BC6C *)(ot + 1))->addr; + D_800A5E60 = p + 0x18; + ((PTag_8001BC6C *)(ot + 1))->addr = (u32)p; +} extern s32 CdQueueBusy(void);