mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
docs(phase-32): T4b (5) ledger — func_80020DA4 unpinned (3 walls remain), backlog 11 open, the Fable draft + report + verdict kept; resume queue (3-at-a-time) tracked
This commit is contained in:
@@ -309,3 +309,4 @@ unsloth_compiled_cache/
|
||||
/.run/P32/t5x/reports/*
|
||||
!/.run/P32/t5x/reports/*.md
|
||||
!/.run/P32/t5x/verdicts.jsonl
|
||||
!/.run/P32/t5x/resume_queue.txt
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[ OK ] build/md_MAIN_009/md_MAIN_009
|
||||
sha1 d270f695b793b5c03db159b7aabcc066daa87eda == config/check.md_MAIN_009.sha (BYTE-IDENTICAL)
|
||||
@@ -0,0 +1,5 @@
|
||||
CC build/src/md_MAIN_009/md_MAIN_009.o
|
||||
LD build/md_MAIN_009/md_MAIN_009.elf
|
||||
OBJCOPY build/md_MAIN_009/md_MAIN_009
|
||||
[ OK ] build/md_MAIN_009/md_MAIN_009
|
||||
sha1 d270f695b793b5c03db159b7aabcc066daa87eda == config/check.md_MAIN_009.sha (BYTE-IDENTICAL)
|
||||
@@ -0,0 +1,97 @@
|
||||
CC build/src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.o
|
||||
In file included from src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:2:
|
||||
src/ov_SC06_022/../shared/engine_core.h:161199: warning: "DEFINE_func_8013FFD8" redefined
|
||||
161199 | #define DEFINE_func_8013FFD8() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:32633: note: this is the location of the previous definition
|
||||
32633 | #define DEFINE_func_8013FFD8() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:169456: warning: "DEFINE_func_8013F350" redefined
|
||||
169456 | #define DEFINE_func_8013F350() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:40890: note: this is the location of the previous definition
|
||||
40890 | #define DEFINE_func_8013F350() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:185848: warning: "DEFINE_func_80181538" redefined
|
||||
185848 | #define DEFINE_func_80181538() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:57282: note: this is the location of the previous definition
|
||||
57282 | #define DEFINE_func_80181538() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:190943: warning: "DEFINE_func_801808C4" redefined
|
||||
190943 | #define DEFINE_func_801808C4() \
|
||||
|
|
||||
src/ov_SC06_022/../shared/engine_core.h:62377: note: this is the location of the previous definition
|
||||
62377 | #define DEFINE_func_801808C4() \
|
||||
|
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:1525: warning: conflicting types for built-in function `memcpy'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4131:61: warning: "/*" within comment [-Wcomment]
|
||||
4131 | * family, all identical wherever declared — src/ov_SC06_022/*.c and the
|
||||
|
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017D454':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3489: warning: passing arg 1 of `func_8012A018' makes integer from pointer without a cast
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017D518':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3526: warning: passing arg 1 of `func_8012A018' makes integer from pointer without a cast
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017D5D8':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3545: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3437: warning: previous external decl of `D_80126940'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017D6E0':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3590: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3437: warning: previous external decl of `D_80126940'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017D7CC':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3631: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3437: warning: previous external decl of `D_80126940'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017D8D4':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3674: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3437: warning: previous external decl of `D_80126940'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: At top level:
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3722: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3578: warning: previous external decl of `func_8017D9C0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3722: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3704: warning: previous implicit declaration of `func_8017D9C0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3722: warning: `func_8017D9C0' was previously implicitly declared to return `int'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3755: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3579: warning: previous external decl of `func_8017DB58'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3755: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3665: warning: previous implicit declaration of `func_8017DB58'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3755: warning: `func_8017DB58' was previously implicitly declared to return `int'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017DB58':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3760: warning: assignment from incompatible pointer type
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017DC0C':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3803: warning: passing arg 3 of `func_80128D60' from incompatible pointer type
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: At top level:
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4038: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3985: warning: previous external decl of `func_8017E2B0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4038: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4015: warning: previous implicit declaration of `func_8017E2B0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4038: warning: `func_8017E2B0' was previously implicitly declared to return `int'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4142: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3844: warning: previous external decl of `func_8012B0B4'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4142: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3855: warning: previous implicit declaration of `func_8012B0B4'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4142: warning: `func_8012B0B4' was previously implicitly declared to return `int'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: In function `func_8017EA6C':
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4353: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3818: warning: previous external decl of `func_8017EFE0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4353: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3818: warning: previous implicit declaration of `func_8017EFE0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4355: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3823: warning: previous external decl of `func_8012E9C0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4355: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3823: warning: previous implicit declaration of `func_8012E9C0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c: At top level:
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4546: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3818: warning: previous external decl of `func_8017EFE0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4546: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:3818: warning: previous implicit declaration of `func_8017EFE0'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:4546: warning: `func_8017EFE0' was previously implicitly declared to return `int'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:5483: warning: type mismatch with previous external decl
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:5466: warning: previous external decl of `func_80180700'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:5483: warning: type mismatch with previous implicit declaration
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:5466: warning: previous implicit declaration of `func_80180700'
|
||||
src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c:5483: warning: `func_80180700' was previously implicitly declared to return `int'
|
||||
LD build/ov_SC06_022/ov_SC06_022.elf
|
||||
OBJCOPY build/ov_SC06_022/ov_SC06_022
|
||||
TRIM build/ov_SC06_022/ov_SC06_022 (-1 B linker end-align pad)
|
||||
[ OK ] build/ov_SC06_022/ov_SC06_022
|
||||
sha1 2a7d7d4e2fe2f87a83a065686731c7942b3c70ef == config/check.ov_SC06_022.sha (BYTE-IDENTICAL)
|
||||
@@ -0,0 +1,111 @@
|
||||
/* func_80020DA4 (0x80020DA4): builds a 3x3 Q12 rotation matrix from three angle-table lookups.
|
||||
* decl_prior (src/800.c:12196): extern void func_80020DA4(s32 a0, s32 a1); -- callers cast pointers to s32.
|
||||
* a0 -> u16[3] angle indices (a0[0],a0[1],a0[2], each &0xFFF); a1 -> MTX_80020248-shaped s16[9]
|
||||
* output (m[0][0..2],m[1][0..2],m[2][0..2], offsets 0x0-0x10). D_800636D4 is a GLOBAL POINTER
|
||||
* (loaded via lw, not lui/addiu) to a table of packed {lo:s16, hi:s16} Q12 entries, 4B each.
|
||||
* Semantics hand-verified against every mult/mflo/sra/store in the target .s (identical Euler
|
||||
* composition to the banked twin ov_SC02_011/func_8018B76C, just Q12 not Q15 and a packed-word
|
||||
* table instead of two lookup calls).
|
||||
*
|
||||
* MATCH STATUS: MATCH (match_one 100/100 AND rtu_match MATCH in the real TU src/800.c, P32 T5x,
|
||||
* 2026-09-05, Fable). Sixth-generation draft: 51 -> 20 -> 14 -> 8 -> 2 -> 0. The levers the earlier
|
||||
* sessions found load-bearing are all kept EXCEPT the very first one, which turned out to be the
|
||||
* cause of the final residual:
|
||||
* 1. (REMOVED) `register s32 e0 __asm__("$6")` pin on the idxA table word (51 -> 20 in S76). The pin
|
||||
* put e0 in $a2 the way the target has it, but an explicit hard register is copied into
|
||||
* reload1.c's `regs_explicitly_used` (reload1.c:486) -> `bad_spill_regs` (reload1.c:3651-3660)
|
||||
* -> `forbidden_regs` (reload1.c:709), and that set is the `losers` argument of every
|
||||
* `retry_global_alloc` (reload1.c:3497 -> global.c find_reg). The mult results here are GLOBAL
|
||||
* allocnos (their preferred class is LO_REG, the `=l` output of mulsi3_internal, mips.md:848);
|
||||
* global.c first parks m3/m8/m13 in LO itself, reload then spills LO ("Spilling reg 65") and
|
||||
* RETRIES them -- and the retried m13 (pseudo 102) could not take the freshly-dead $a2 because
|
||||
* $a2 was forbidden by the pin. That is the whole `mflo $t0` vs `mflo $a2` residual (idx 91/92).
|
||||
* Unpinned, m13's retry lands in $a2 ("Register 102 now in 6" in the -dg dump) exactly as the
|
||||
* target's does.
|
||||
* 2. Address computation as plain integer arithmetic `(idx << 2) + tbl` (tbl a plain `s32`, NOT
|
||||
* `s32 *`) instead of `&tbl[idx]` pointer-index sugar (20 -> 14).
|
||||
* 3. Do not give a once-read shifted product (m7) its own named temp; inline it at its single use
|
||||
* (14 -> 8).
|
||||
* 4. `s32 frame_pad[3]; (void)&frame_pad;` -- an address-taken-but-never-stored-through local
|
||||
* array reproduces the target's 16-byte phantom frame (8 -> 2), zero emitted code.
|
||||
* 5. (NEW) Two zero-byte launders `__asm__("" : "=r"(x) : "0"(x))` that steer LOCAL-alloc's
|
||||
* qty_compare priorities (local-alloc.c:1579) so that unpinned first-fit lands e0 in $a2:
|
||||
* - `e1` laundered immediately before `dst[6] = -e1`. Unpinned, e0's tied quantity {e0, e0<<16,
|
||||
* lo0} (10 refs / 38 insns, pri 7894) out-ranked e1's tied quantity {e1, -e1} (5 refs / 15,
|
||||
* pri 6666), so e0 was allocated first and took the free $v1; the target needs e1's quantity
|
||||
* allocated FIRST (it then holds $v1 across e0's range, and e0's first fit falls through
|
||||
* $v0/$v1/$a0/$a1 to $a2). The launder adds two refs to e1's quantity (7 refs / 16 -> 8750)
|
||||
* and sched1 places it at position 40, AFTER lo1's death (the m12 mult), which matters: placed
|
||||
* right after e1's load (pos 27) it lengthens lo1 by one insn and flips the exact
|
||||
* qty_compare tie lo1 (4/32) vs p_ab (3/12) = 2500 both, handing $a0 to p_ab (closeness 15).
|
||||
* - `p1` laundered between its `& 0xFFF` and its `<< 2`. The e1 launder at pos 40 lengthens the
|
||||
* global allocnos m6/m7/m12 (95/96/101: 23 -> 24 insns, allocno pri 869 -> 833) but not m1
|
||||
* (90: 24 insns, 833), collapsing the order 95 96 101 90 into an allocno-number tie won by 90
|
||||
* (closeness 6: the $t8/$t6/$t7 mflo rotation). A second zero-byte insn at sched1 pos 20 --
|
||||
* inside m1's range [15,38], outside lo1's [23,39] and before m2's birth -- restores
|
||||
* len(90) > len(95/96/101) while leaving every local qty_compare order unchanged (hand-checked
|
||||
* for all 30 local quantities; equivalently, laundering `addr1` right after its addu also
|
||||
* matches byte-for-byte).
|
||||
* The order of allocations is exactly the target's now: global "92 97 99 100 102 91 93 94 95 96
|
||||
* 101 90 98"; local e1 {81,124} -> $v1 before e0 {80,120,85} -> $a2, tbl -> $a3, lo1 -> $a0, p_ab/p1v
|
||||
* -> $a3, lo2/hi0/hi2 -> $t0/$t1/$t2, p_ac -> $t3; reload retries m3 -> $a3, m8 -> $s1, m13 -> $a2.
|
||||
* Evidence and the full -dl/-dg readings: .run/P32/t5x/reports/func_80020DA4.md; cookbook §47/§500-G
|
||||
* are the priority-slider precedents, §500-H the launder-of-a-pinned-value precedent.
|
||||
*/
|
||||
extern s32 *D_800636D4;
|
||||
|
||||
void func_80020DA4(s32 a0, s32 a1) {
|
||||
u16 *src = (u16 *)a0;
|
||||
s16 *dst = (s16 *)a1;
|
||||
s32 tbl = (s32)D_800636D4;
|
||||
|
||||
s32 p0, p1, p2;
|
||||
s32 e0;
|
||||
s32 e1;
|
||||
s32 addr1, addr2;
|
||||
s32 hi0, lo0, hi1, lo1, hi2, lo2;
|
||||
s32 m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13;
|
||||
s32 p_ab, p_ac, p1v;
|
||||
s32 frame_pad[3]; (void)&frame_pad;
|
||||
|
||||
p0 = src[0] & 0xFFF;
|
||||
e0 = *(s32 *)((p0 << 2) + tbl);
|
||||
p2 = src[2] & 0xFFF;
|
||||
addr2 = (p2 << 2) + tbl;
|
||||
hi0 = e0 >> 16;
|
||||
lo2 = *(s16 *)addr2;
|
||||
m1 = hi0 * lo2;
|
||||
hi2 = *(s16 *)(addr2 + 2);
|
||||
m2 = hi0 * hi2;
|
||||
p1 = src[1] & 0xFFF;
|
||||
__asm__("" : "=r"(p1) : "0"(p1));
|
||||
addr1 = (p1 << 2) + tbl;
|
||||
lo0 = (s16)e0;
|
||||
lo1 = *(s16 *)addr1;
|
||||
m3 = lo0 * lo1;
|
||||
e1 = *(s32 *)addr1;
|
||||
hi1 = e1 >> 16;
|
||||
m4 = hi2 * hi1;
|
||||
p_ab = m3 >> 12;
|
||||
m5 = p_ab * hi2;
|
||||
p_ac = m2 >> 12;
|
||||
m6 = p_ac * lo1;
|
||||
m7 = lo0 * lo2;
|
||||
m8 = lo2 * hi1;
|
||||
m9 = p_ab * lo2;
|
||||
m10 = hi1 * lo0;
|
||||
m11 = hi1 * hi0;
|
||||
p1v = m1 >> 12;
|
||||
m12 = p1v * lo1;
|
||||
__asm__("" : "=r"(e1) : "0"(e1));
|
||||
dst[6] = -e1;
|
||||
dst[0] = m4 >> 12;
|
||||
dst[3] = m8 >> 12;
|
||||
dst[7] = m10 >> 12;
|
||||
m13 = lo0 * hi2;
|
||||
dst[8] = m11 >> 12;
|
||||
dst[1] = (m5 >> 12) - p1v;
|
||||
dst[2] = (m6 >> 12) + (m7 >> 12);
|
||||
dst[4] = (m9 >> 12) + p_ac;
|
||||
dst[5] = (m12 >> 12) - (m13 >> 12);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
# func_80020DA4 (main / src/800.c, 100 ins) — MATCH (P32 T5x, 2026-09-05, Fable arm)
|
||||
|
||||
**Verdict:** `match_one` MATCH 100/100 and `rtu_match --tu src/800.c` MATCH in the real TU.
|
||||
Draft: `.run/P32/t5x/fable/func_80020DA4.c`. Prior best: `.run/S79w/sonnet/func_80020DA4.c` at closeness 2
|
||||
(idx 91/92: `mflo $t0` vs the target's `mflo $a2` + the dependent `sra`).
|
||||
|
||||
## 1. The residual's mechanism, as read in the compiler (not as guessed)
|
||||
|
||||
The prior five sessions read the `mflo $a2` as local-alloc reusing the multiplier's dying register
|
||||
(`combine_regs` / `qty_phys_sugg`). Both instruments say otherwise:
|
||||
|
||||
1. **The `mflo` is a reload, and the mult results are GLOBAL allocnos.** `mulsi3_internal`
|
||||
(`tools/reference/gcc-2.7.2/config/mips/mips.md:848`) sets operand 0 with constraint `=l` (LO).
|
||||
The `-dl` dump lists every mult result as `pref LO_REG, else GR_REGS` and NONE of pseudos 90–102 appear
|
||||
in local-alloc's `;; Register N in M` list; the `-dg` dump opens with `;; 13 regs to allocate: 92 97 99
|
||||
100 102 91 93 94 95 96 101 90 98` — they are allocated by `global.c`. Reload then emits the
|
||||
`(set (reg N) (reg 65 lo))` output reload that prints as `mflo` (`.greg`: `(insn 228 136 142 (set (reg/v:SI
|
||||
8 t0) (reg:SI 65 lo)) -1 …)` in the pinned draft).
|
||||
2. **global.c parks three mult results in LO itself, and reload RETRIES them.** `find_reg` is first
|
||||
called with the preferred class (`global.c:565-572`); LO_REG contains only reg 65, which is neither fixed
|
||||
(`mips.h:1186` FIXED_REGISTERS) nor in the mult's clobbers (hi=64 and accum=66 are, lo is the dest), so
|
||||
m3 (92), m8 (97) and m13 (102) — mutually non-conflicting — all get LO. Reload needs LO for insn 49's
|
||||
output → `Spilling reg 65.` (and `Spilling reg 16.` for insn 87's GR_REGS input need — that unused
|
||||
`$s0` is why the target saves an `$s0` it never uses) → `spill_hard_reg` calls
|
||||
`retry_global_alloc (i, forbidden_regs)` in pseudo order: `Register 92 now in 7.` / `Register 97 now in
|
||||
17.` / `Register 102 now in 8.` (pinned draft) — the target's m3=$a3, m8=$s1 are these very retries.
|
||||
3. **The pin forbade `$a2` at retry.** `retry_global_alloc` passes `forbidden_regs` as `losers` to `find_reg`
|
||||
(`global.c:904-937`, `IOR_HARD_REG_SET (used1, losers)`). `forbidden_regs` is seeded from `bad_spill_regs`
|
||||
(`reload1.c:709`), which contains every reg in `regs_explicitly_used` (`reload1.c:3651-3660`, the
|
||||
`#ifndef SMALL_REGISTER_CLASSES` branch MIPS takes), and `regs_explicitly_used` is a copy of
|
||||
`regs_ever_live` at reload entry (`reload1.c:486`) — i.e. the hard regs written explicitly in the RTL:
|
||||
parameters, sp, the mult clobbers, and **`register s32 e0 __asm__("$6")`**. At 102's retry its conflicts
|
||||
are `2 3 5 7 11` (dump line `;; 102 conflicts: 94 95 96 98 101 102 2 3 5 7 11 29 64 66`) plus the regs of
|
||||
the already-placed 94/95/96/98/101 (13/14/15/25/**4**); first fit in numeric order is therefore `$a2`(6)
|
||||
— unless `$a2` is forbidden, in which case it is `$t0`(8). The target's source had no pin.
|
||||
|
||||
So the residual was not a variable-reuse, a birth point, or a tie: it was the FIRST lever of the S76
|
||||
session (the pin, 51→20) poisoning the LAST allocation decision.
|
||||
|
||||
## 2. Getting e0 into `$a2` without a pin (local-alloc first-fit)
|
||||
|
||||
Unpinned, the S79 draft regresses to 37: e0 (pseudo 80) goes to `$v1`, tbl to `$a2`. Read from `-dl`:
|
||||
local-alloc ties `{e0, e0<<16, lo0}` into one quantity (each source dies at the next insn, `combine_regs`),
|
||||
10 refs over 38 insns → `qty_compare` (`local-alloc.c:1579`) priority `floor_log2(10)·10/38·10000 = 7894`;
|
||||
e1's quantity `{e1, -e1}` is 5 refs / 15 → 6666. Higher priority allocates first, first fit takes the lowest
|
||||
free register (no `REG_ALLOC_ORDER` on MIPS 2.7.2). With e0 first, `$v1` is free over [12,50] and e0 takes it.
|
||||
The target's allocation requires e1's quantity FIRST (it then occupies `$v1` inside e0's range, so e0
|
||||
falls through `$v0/$v1/$a0/$a1` to `$a2`), and e0 still ahead of tbl (76, 4/15 → 5333) or tbl takes `$a2`.
|
||||
I derived the full constraint set from the target's bytes by inverting first-fit (report §4) — the only
|
||||
inversion needed is e1 > e0.
|
||||
|
||||
**Lever:** a zero-byte launder on e1, `__asm__("" : "=r"(e1) : "0"(e1));`, adds two refs to e1's
|
||||
quantity (7 refs / 16 → 8750). Placement is the whole game:
|
||||
* right after `e1 = *(s32*)addr1` → sched1 puts the asm at position 27 → closeness **15**: it lengthens
|
||||
lo1 (87: 4 refs, [23,39]) by one insn, breaking the EXACT tie lo1 (8/32=2500) vs p_ab (103: 3/12=2500)
|
||||
that the stable qsort had resolved in lo1's favour → p_ab takes `$a0`, lo1 → `$a3`, cascade.
|
||||
* immediately before `dst[6] = -e1` (or after `hi1 = e1 >> 16`) → the asm is placed at position 40, after
|
||||
lo1's death at the m12 mult → closeness **6**, and the whole LOCAL allocation now equals the target's, and
|
||||
`Register 102 now in 6` — the `mflo $a2` residual is gone.
|
||||
|
||||
## 3. The last 3 rows: a global-allocno tie the launder created, and its zero-byte repair
|
||||
|
||||
The pos-40 asm lies inside m6/m7/m12's ranges (95/96/101: 23 → 24 insns, `allocno_compare` pri 869 → 833)
|
||||
but not m1's (90: [15,38], 24 insns, 833). The former strict order `95 96 101 90` becomes a 4-way tie broken
|
||||
by allocno number (`global.c:605-609`) → 90 first → `$t6/$t7/$t8` rotate (idx 17/44/48). Repair: one more
|
||||
zero-byte insn inside m1's range but outside lo1's `[23,39]` and before m2's birth (17), i.e. sched1
|
||||
positions 16–22: `__asm__("" : "=r"(p1) : "0"(p1));` between `p1 = src[1] & 0xFFF` and `addr1 = (p1<<2)+tbl`
|
||||
lands at position 20 (it is glued between the `andi` and the `sll` of the p1 chain). Every local
|
||||
`qty_compare` was recomputed with the +1 (tbl 5333→5000, lo2 4545→4347, hi0/hi2/p_ac shifted alike) — no
|
||||
relative order changes; the global order returns to `92 97 99 100 102 91 93 94 95 96 101 90 98` — and
|
||||
match_one/rtu_match both say MATCH. Laundering `addr1` right after its `addu` (position 22) also matches
|
||||
byte-for-byte (kept as `.run/P32/t5x/work/func_80020DA4/v3c/draft.c`).
|
||||
|
||||
## 4. Measured ladder (this session)
|
||||
| variant | change vs S79 draft | closeness | note |
|
||||
|---|---|---|---|
|
||||
| baseline | — | 2 | `mflo $t0` vs `$a2` |
|
||||
| nopin | pin removed | 37 | e0→$v1, tbl→$a2 (first-fit, e0 pri 7894 > e1 6666) |
|
||||
| v1 | nopin + launder e1 after its load | 15 | asm at pos 27 flips the lo1/p_ab exact tie |
|
||||
| v2 / v2b | nopin + launder e1 before `-e1` / after `hi1` | 6 | asm at pos 40; local alloc == target; `102 now in 6` |
|
||||
| v3a | v2 + launder `src` before p1's load | 101 ins | not zero-byte: emits `move v0,a0` (the param copy is not in place) |
|
||||
| **v3b** | v2 + launder `p1` between andi and sll | **MATCH** | rtu MATCH; the deliverable |
|
||||
| v3c | v2 + launder `addr1` after its addu | **MATCH** | rtu MATCH; alternate |
|
||||
|
||||
Inert/known from prior sessions and NOT repeated: pins on m13/e1p/hi1, statement orderings of m13,
|
||||
`lo0 *= hi2` (101 ins), operand swap, permuter_ils (S80 null).
|
||||
|
||||
## 5. Generalizable lessons (for the cookbook harvest)
|
||||
* **A pinned hard register is FORBIDDEN to every `retry_global_alloc`** (reload1.c:486 → 3651 → 709 →
|
||||
3497). Symptom: a `mflo`/reload destination that first-fit should have given the pinned register's
|
||||
freshly-dead slot lands one register higher. The pin that fixed an early allocation can be the sole cause
|
||||
of a late one; unpin and reproduce the allocation with priority levers instead.
|
||||
* **On MIPS 2.7.2 every `mult` result is a GLOBAL allocno** (pref class LO_REG, `=l`), first parked in LO
|
||||
by `find_reg`'s preferred-class pass, spilled by reload, retried in PSEUDO-NUMBER order with the
|
||||
post-first-pass conflicts. `Spilling reg 16` for the GR input reload is why `$s0` is saved-but-unused
|
||||
in this function (and presumably its siblings).
|
||||
* **Launder placement is a sched1 question, not a source-order one:** an in-place `"0"` launder is placed
|
||||
right after its input's last reader when a consumer needs it early, and right before its consumer when
|
||||
nothing else does; check `-dl` for the position and re-run every `qty_compare` that spans it — one insn
|
||||
splits an exact tie (§47) in either direction.
|
||||
* The `-dg` header (`regs to allocate`, `conflicts`, `Spilling`, `now in`) plus `-dl`'s `used N times across
|
||||
M insns` are sufficient to predict first-fit by hand for a straight-line function; the inversion of the
|
||||
target's bytes into "who was allocated before whom" gave the exact priority window (5333 < e0 < e1).
|
||||
@@ -0,0 +1,10 @@
|
||||
# T4b Fable resume queue (Drew 2026-09-05: "resume agents, but not all at once, just 3 at a time"). Delete a line when resumed.
|
||||
# fn agentId closeness
|
||||
func_80039308 a55fbfb4fb896bd71 17
|
||||
func_800CF3E8 ad27049c8fdf1e816 27
|
||||
func_80185810 a547e70e9a7735c8a 35
|
||||
func_8017DC80 a7c2c1e4865e5590d 46
|
||||
func_800CF408 aac6ce9fdfdcc093c 49
|
||||
func_800CF6D0 a7f7e477e9878acdd 137
|
||||
func_80011380 a60ffea4022b891fc 6 (-O0, §474 PROVED — last)
|
||||
# RUNNING: func_80032A74 a4c05f049efb6491e · func_801834A4 a26f8270f9f82e5fb · func_800CD92C a5587b9d5c7006214 (func_80020DA4 DONE: MATCH)
|
||||
@@ -2,3 +2,4 @@
|
||||
{"fn": "func_80039DEC", "binary": "main", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_80039DEC.c", "note": "natural 3-case switch(a2) with DUPLICATED case tails (cross-jump merges them post-reload) + block-scope u8 *p per case; a2-raw keeps 4 refs (pri 1951) and is allocated first -> $a3 (global.c allocno_compare/find_reg); refutes the argument-position pin theory and the local_reg_n_refs hypothesis; the permuter's 2 was R63-unsound (tmp uninitialised). Coordinator rtu MATCH 74/74; gate_main BANKED 143dbb89", "session": "491895ad"}
|
||||
{"fn": "func_800CD674", "binary": "md_MAIN_009", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_800CD674.c", "note": "prims 3/4 use different masked-p variables (pm3/pm2, single-death each) + a trailing `__asm__ volatile(\"\" : \"=r\"(pm3))` on pm3. Mechanism: a 2-death pseudo is excluded from local_alloc (local-alloc.c:471) -> global -> $a3; the target's $t1 is combine_regs' hard-reg branch (qty_phys_sugg from $9 dying as an input) which wins only for a pseudo BORN at that `and`; a fresh single-SET pseudo for prim 3 regresses to 31 because sched.c adjust_priority (2511-2545) boosts a birthing SET to max priority and glues the and to the or (the old '+1 pseudo displaces constants' was reg_n_sets/sched1, not regalloc); the asm's second set makes pm3 reg_n_sets=2 (no boost) and 2-death (global, $a3 as before). Coordinator rtu MATCH 174/174; bank.sh d270f695", "session": "491895ad"}
|
||||
{"fn": "func_8017DF28", "binary": "ov_SC06_022", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_8017DF28.c", "note": "a second $v0 SET: RotMatrixY called through its real libgte pointer-returning type ((void *(*)(s32, void *))RotMatrixY)(...), TU void decl untouched. Mechanism: with ONE value-returning call reg_n_sets[$v0]==1 (regclass.c:1791) makes the call_insn birthing (sched.c:2469/2507 -> max priority) in sched1's backward list scheduler; tie with the block-move address def (mips.c:2350 copy_addr_to_reg, cse-reused — also in the original) broken by LUID put the addiu ABOVE the jal where reorg's backward search fills the jal slot (reorg.c:2904); with a second $v0 set the call is priority 1, the def lands after the call, reorg's forward search refuses it (mark_set_resources reorg.c:542 marks all call_used regs incl. $sp) and the bnez backward search takes it. Known-true: same-TU twin func_80180700 (3 $v0 sets). Coordinator rtu MATCH 119/119; bank.sh byte-identical", "session": "491895ad"}
|
||||
{"fn": "func_80020DA4", "binary": "main", "arm": "fable", "status": "MATCH", "closeness": 0, "compiles": true, "draft_path": ".run/P32/t5x/fable/func_80020DA4.c", "note": "unpin e0 ($6 pin made $a2 regs_ever_live -> bad_spill_regs -> forbidden at reload's retry_global_alloc, reload1.c:486/3497/3651-3660/709; the LO-parked mult results are retried first-fit) + two zero-byte launders steering local-alloc qty_compare: e1 launder before `dst[6] = -e1` (qty 6666->8750, allocated before e0, holds $v1) and p1 launder between its andi and sll (undoes the global tie). Ladder 2->37->15->6->MATCH. Coordinator rtu MATCH 100/100; gate_main BANKED 143dbb89", "session": "491895ad"}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# regenerated by tools/exclude_audit.py from config/wave_exclude.txt
|
||||
# 4 still-valid of 5; 1 dropped as stale (banked / linked / blocker-since-fixed).
|
||||
# 3 still-valid of 4; 1 dropped as stale (banked / linked / blocker-since-fixed).
|
||||
# An exclude list records what the TOOLING could not do — regenerate it as
|
||||
# part of every tool fix, or it becomes a list of work you decided not to do.
|
||||
ov_SC03_105:func_801834A4 # WALL: loop.c movable ordering, closeness 6 (S71) | T4 S83: re-probed in the real TU (3 stored variants) DIFF 6 — CANDIDATE, unchanged
|
||||
main:func_80032A74 # WALL: candidate: 422/422, frame/offsets/27 symbols exact, sole residual idx 244 `lh` vs `lhu` — extendhisi2 is a force_not_mem EXPAND (an orphan frame slot is minted only at an lh), the target's 8 extra frame bytes are §172 producer 3 (caller-save area, reload1.c:1445); ~200 byte-probes incl. a 100-variant retyping sweep (S79 Opus) + permuter_ils 8x150s null (S80); closeness 1 | T4 S83: the S79w draft was a CC1 FAIL only for PLUMBING (7 header typedefs + 4 decl spellings); synced copy .run/P32/t4/drafts/func_80032A74_tuclean.c re-run in the real TU DIFF 1 (idx 244 lh vs lhu) — CANDIDATE, unchanged
|
||||
main:func_80020DA4 # WALL: candidate: 100/100, phantom 16-byte frame reproduced (address-taken frame_pad[3]); residual = mflo destination $t0 vs $a2 (REGALLOC-PERM), pinning regresses to 79; 5 attempts 51→20→14→8→2 (S7x/S79) + permuter_ils 8x150s null (S80); closeness 2 | T4 S83: re-probed in the real TU DIFF 2 — CANDIDATE, unchanged
|
||||
main:func_80011380 # WALL: §474 PROVED C-level floor (closeness 6) — fold-const.c:882 split_tree merges MULT(MULT(i,2),2); the two escapes each cost one instruction (stupid.c:497 adjacency / expand_decl use-brackets); §388 -O0 colouring oracle. Pinned S79 #8. | T4 S83: re-probed in the real TU (rtu --o0) DIFF 6 — PROVED (§474), unchanged
|
||||
|
||||
+11
-12
@@ -2,19 +2,18 @@
|
||||
|
||||
> 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:** 12 · by status {'near': 11, 'failed': 1} · by class {'WALL-CANDIDATE': 3, 'WALL-PROVED': 1, 'SCHED': 4, 'REGALLOC': 1, 'ALIAS': 1, 'FRAME': 1, None: 1}
|
||||
**Open near-misses:** 11 · by status {'near': 10, 'failed': 1} · by class {'WALL-CANDIDATE': 2, 'WALL-PROVED': 1, 'SCHED': 4, 'REGALLOC': 1, 'ALIAS': 1, 'FRAME': 1, None: 1}
|
||||
|
||||
| # | addr | reach | class | nins | status | closeness | where it stuck | best draft |
|
||||
|--:|------|------:|-------|-----:|--------|----------:|----------------|------------|
|
||||
| 1 | func_80032A74 | None | WALL-CANDIDATE | 422 | near | 1 | WALL candidate CONFIRMED in the real TU (S83): 422/422, sole residual idx 244 `lh v0,0x18(s1)` vs target `lhu` — extendhisi2 is a force_not_mem EXPAND (the orphan frame slot is minted only at an lh; §172 producer 3 caller-save area, reload1.c:1445), so lhu loses the 8 frame bytes; ~200 byte-probes + 100-variant retyping sweep (S79) + permuter_ils 8x150s null (S80). Citation current (§172, reload1.c:1445). Draft synced to the TU (typedefs stripped via cdecl.strip_provided_typedefs; D_80064D44/D_8006A970/func_8003F144/func_800316F8 spelled as the TU) | `.run/P32/t4/drafts/func_80032A74_tuclean.c` |
|
||||
| 2 | func_80020DA4 | None | WALL-CANDIDATE | 100 | near | 2 | WALL candidate CONFIRMED (S83 rtu DIFF 2): 100/100, phantom 16-byte frame reproduced (address-taken frame_pad[3]); residual = mflo destination $t0 vs $a2 (REGALLOC-PERM), pinning regresses to 79; 5 attempts 51->20->14->8->2 + permuter_ils null (S80) | `.run/S79w/sonnet/func_80020DA4.c` |
|
||||
| 3 | func_801834A4 | None | WALL-CANDIDATE | 106 | near | 6 | WALL candidate: loop.c movable ordering, closeness 6 (S71); re-probed S83 in the real TU: DIFF 6 for all three stored variants (unchanged) | `.run/S71_gate14/ov_SC03_105-cn-cast-rc-sd/func_801834A4.c` |
|
||||
| 4 | func_80011380 | None | WALL-PROVED | 192 | near | 6 | §474 PROVED C-level floor (boot -O0): fold-const.c:882 split_tree merges MULT(MULT(i,2),2); the two escapes each cost one instruction (stupid.c:497 adjacency / expand_decl use-brackets); §388 -O0 colouring oracle. Pinned S79 #8; re-probed S83 in the real TU: DIFF 6 (unchanged) | `.run/m3/opus/func_80011380.c` |
|
||||
| 5 | 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` |
|
||||
| 6 | 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` |
|
||||
| 7 | 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` |
|
||||
| 8 | 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` |
|
||||
| 9 | 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` |
|
||||
| 10 | 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` |
|
||||
| 11 | 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` |
|
||||
| 12 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | |
|
||||
| 2 | func_801834A4 | None | WALL-CANDIDATE | 106 | near | 6 | WALL candidate: loop.c movable ordering, closeness 6 (S71); re-probed S83 in the real TU: DIFF 6 for all three stored variants (unchanged) | `.run/S71_gate14/ov_SC03_105-cn-cast-rc-sd/func_801834A4.c` |
|
||||
| 3 | func_80011380 | None | WALL-PROVED | 192 | near | 6 | §474 PROVED C-level floor (boot -O0): fold-const.c:882 split_tree merges MULT(MULT(i,2),2); the two escapes each cost one instruction (stupid.c:497 adjacency / expand_decl use-brackets); §388 -O0 colouring oracle. Pinned S79 #8; re-probed S83 in the real TU: DIFF 6 (unchanged) | `.run/m3/opus/func_80011380.c` |
|
||||
| 4 | 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` |
|
||||
| 5 | 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` |
|
||||
| 6 | 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` |
|
||||
| 7 | 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` |
|
||||
| 8 | 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` |
|
||||
| 9 | 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` |
|
||||
| 10 | 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` |
|
||||
| 11 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | |
|
||||
|
||||
Reference in New Issue
Block a user