feat(phase-21): sched-idiom gate — +1 fns x0 propagated (fleet 63.17%)

This commit is contained in:
Drew T
2026-06-25 01:06:36 -06:00
parent e5ae5958d5
commit 1ca0faef29
+50 -1
View File
@@ -210,7 +210,56 @@ DEFINE_func_80128DB4() /* dedup: shared engine-core @0x80128DB4 (src/shared) */
DEFINE_func_80128EA8() /* dedup: shared engine-core @0x80128EA8 (src/shared) */
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_a", func_80128ED8);
// LOAD-BEARING register pins (cookbook §17 + §25): the residual here was NOT scheduling but
// gcc-2.7.2 COPY-COALESCING — gcc folded the index-preserve copy (idc) into the multiply operand
// (`sll $v0,$a3,3` on the copy) instead of multiplying $v1 directly. Pinning idc to its target
// reg ($a3) forces the multiply onto $v1 and emits the copy separately AFTER it; routing idc+1
// through the dead $v0-pinned `cnt` lands it in $v0 (target's scratch), not back in $a3.
// Do NOT "simplify" the pins or the cnt reuse — each is byte-load-bearing (byte-gated).
#include "common.h"
s32 func_80128ED8(s32 param_1, s32 *param_2) {
register s32 iVar4 __asm__("$8"); /* base ptr, lives whole fn in $t0 */
register s32 cnt __asm__("$2"); /* decremented count in $v0 */
register s32 cc __asm__("$3"); /* preserved count copy in $v1 (forces the bne-delay-slot copy) */
register s32 idx __asm__("$3"); /* offset-4 index, loaded into $v1 */
register s32 idc __asm__("$7"); /* $a3: preserved idx copy, forced SEPARATE from the multiply */
u32 uVar3;
s32 frame_pad[4]; /* phantom 0x10 frame the target reserves (induce via clobber anchor) */
__asm__ __volatile__("" : : "r"(&frame_pad) : "memory");
iVar4 = *param_2;
cnt = *(s16 *)((s32)param_2 + 6);
if (cnt == 0) {
return 1;
}
cc = cnt;
__asm__ __volatile__("" : "=r"(cc) : "0"(cc)); /* force the count-preserve copy ($v1=$v0) */
cnt = cc - 1;
*(s16 *)((s32)param_2 + 6) = (s16)cnt;
if (cnt * 0x10000 < 1) {
idx = *(s16 *)((s32)param_2 + 4);
__asm__ __volatile__("" : "=r"(idx) : "0"(idx)); /* pin the index into $v1 */
uVar3 = *(u32 *)(idx * 8 + iVar4 + 4);
idc = idx;
if ((uVar3 & 0xc0) == 0xc0) {
*(s16 *)((s32)param_2 + 6) = 0;
return 1;
}
if ((uVar3 & 0x80) != 0) {
*(s16 *)((s32)param_2 + 4) = 0;
} else {
cnt = idc + 1; /* reuse the dead $v0 pin so idc+1 lands in $v0, not $a3 */
*(s16 *)((s32)param_2 + 4) = cnt;
}
*(u16 *)((s32)param_2 + 6) =
(u16)(*(u32 *)((s16)param_2[1] * 8 + iVar4 + 4) & 0x3f);
*(u16 *)(param_1 + 0x28) = *(u16 *)((s16)param_2[1] * 8 + iVar4);
*(u16 *)(param_1 + 0x2a) = *(u16 *)((s16)param_2[1] * 8 + iVar4 + 2);
}
return 0;
}
M2C_UNK func_8001534C(M2C_UNK, M2C_UNK *, M2C_UNK, M2C_UNK, s32, s32); /* extern */
M2C_UNK func_800153CC(M2C_UNK, u16, M2C_UNK, M2C_UNK, s32, s32); /* extern */