feat(phase-30 S48-0b): jtbl family func_80135EB0 — 3/3 blocked-binary siblings banked

This commit is contained in:
Drew T
2026-08-11 15:40:54 -06:00
parent 7e9c6d53a4
commit 44afe27544
10 changed files with 4328 additions and 1885 deletions
+3 -3
View File
@@ -4915,7 +4915,7 @@ ov_MAIN_012_ELF := $(ov_MAIN_012_OUT).elf
ov_MAIN_012_MAPFILE := $(ov_MAIN_012_OUT).map
ov_MAIN_012_LD_SCRIPT := $(ov_MAIN_012_OUT).ld
ov_MAIN_012_SPLAT_YAML := config/splat.ov_MAIN_012.yaml
ov_MAIN_012_JTBL_INTERLEAVE := --order tail.data.o,ov_MAIN_012_jr_80131340.o,tail2.data.o,ov_MAIN_012_jr_801380E0.o,tail3.data.o,ov_MAIN_012_jr_8013F350.o,tail4.data.o,ov_MAIN_012_jr_80159C84.o,tail5.data.o,ov_MAIN_012_jr_8015A3C8.o,tail6.data.o,ov_MAIN_012_jr_801789AC.o,tail7.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_MAIN_012_JTBL_INTERLEAVE := --order tail.data.o,ov_MAIN_012_jr_80131340.o,tail2.data.o,ov_MAIN_012_jr_80135EB0.o,tail3.data.o,ov_MAIN_012_jr_801380E0.o,tail4.data.o,ov_MAIN_012_jr_8013F350.o,tail5.data.o,ov_MAIN_012_jr_80159C84.o,tail6.data.o,ov_MAIN_012_jr_8015A3C8.o,tail7.data.o,ov_MAIN_012_jr_801789AC.o,tail8.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_MAIN_012/ov_MAIN_012_jr_8013F350.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_MAIN_012/ov_MAIN_012_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_MAIN_012/ov_MAIN_012_jr_801789AC.o: JTBL_PADS := 0,0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18,+0x190,+0x220
@@ -4940,7 +4940,7 @@ ov_SC02_037_ELF := $(ov_SC02_037_OUT).elf
ov_SC02_037_MAPFILE := $(ov_SC02_037_OUT).map
ov_SC02_037_LD_SCRIPT := $(ov_SC02_037_OUT).ld
ov_SC02_037_SPLAT_YAML := config/splat.ov_SC02_037.yaml
ov_SC02_037_JTBL_INTERLEAVE := --order tail.data.o,ov_SC02_037_jr_80131340.o,tail2.data.o,ov_SC02_037_jr_801380E0.o,tail3.data.o,ov_SC02_037_jr_8013F350.o,tail4.data.o,ov_SC02_037_jr_80159C84.o,tail5.data.o,ov_SC02_037_jr_8015A3C8.o,tail6.data.o,ov_SC02_037_jr_801789AC.o,tail7.data.o,ov_SC02_037_jr_8017AE2C.o,tail8.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC02_037_JTBL_INTERLEAVE := --order tail.data.o,ov_SC02_037_jr_80131340.o,tail2.data.o,ov_SC02_037_jr_80135EB0.o,tail3.data.o,ov_SC02_037_jr_801380E0.o,tail4.data.o,ov_SC02_037_jr_8013F350.o,tail5.data.o,ov_SC02_037_jr_80159C84.o,tail6.data.o,ov_SC02_037_jr_8015A3C8.o,tail7.data.o,ov_SC02_037_jr_801789AC.o,tail8.data.o,ov_SC02_037_jr_8017AE2C.o,tail9.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC02_037/ov_SC02_037_jr_8013F350.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC02_037/ov_SC02_037_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC02_037/ov_SC02_037_jr_8015A3C8.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
@@ -4966,7 +4966,7 @@ ov_SC03_107_ELF := $(ov_SC03_107_OUT).elf
ov_SC03_107_MAPFILE := $(ov_SC03_107_OUT).map
ov_SC03_107_LD_SCRIPT := $(ov_SC03_107_OUT).ld
ov_SC03_107_SPLAT_YAML := config/splat.ov_SC03_107.yaml
ov_SC03_107_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_107_jr_80131340.o,tail2.data.o,ov_SC03_107_jr_801380E0.o,tail3.data.o,ov_SC03_107_jr_8013F350.o,tail4.data.o,ov_SC03_107_jr_80159C84.o,tail5.data.o,ov_SC03_107_jr_8015A3C8.o,tail6.data.o,ov_SC03_107_jr_801789AC.o,tail7.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC03_107_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_107_jr_80131340.o,tail2.data.o,ov_SC03_107_jr_80135EB0.o,tail3.data.o,ov_SC03_107_jr_801380E0.o,tail4.data.o,ov_SC03_107_jr_8013F350.o,tail5.data.o,ov_SC03_107_jr_80159C84.o,tail6.data.o,ov_SC03_107_jr_8015A3C8.o,tail7.data.o,ov_SC03_107_jr_801789AC.o,tail8.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC03_107/ov_SC03_107_jr_8013F350.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC03_107/ov_SC03_107_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC03_107/ov_SC03_107_jr_801789AC.o: JTBL_PADS := 0,0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18,+0x190,+0x220
+8 -5
View File
@@ -95,6 +95,7 @@ segments:
# - [0x0, rodata, head]
- [0x0, c, ov_MAIN_012]
- [0x91e8, c, ov_MAIN_012_jr_80131340]
- [0xdd58, c, ov_MAIN_012_jr_80135EB0]
- [0xff88, c, ov_MAIN_012_jr_801380E0]
- [0x171f8, c, ov_MAIN_012_jr_8013F350]
- [0x31b2c, c, ov_MAIN_012_jr_80159C84]
@@ -103,16 +104,18 @@ segments:
- [0x561e0, data, tail]
- [0x5ad78, .rodata, ov_MAIN_012_jr_80131340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5ad8c, data, tail2]
- [0x5adec, .rodata, ov_MAIN_012_jr_80135EB0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5ae18, data, tail3]
- [0x5ae24, .rodata, ov_MAIN_012_jr_801380E0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5ae88, data, tail3]
- [0x5ae88, data, tail4]
- [0x5b494, .rodata, ov_MAIN_012_jr_8013F350] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5b4c8, data, tail4]
- [0x5b4c8, data, tail5]
- [0x5b730, .rodata, ov_MAIN_012_jr_80159C84] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5b764, data, tail5]
- [0x5b764, data, tail6]
- [0x5b768, .rodata, ov_MAIN_012_jr_8015A3C8] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5b784, data, tail6]
- [0x5b784, data, tail7]
- [0x5ba40, .rodata, ov_MAIN_012_jr_801789AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5bcec, data, tail7]
- [0x5bcec, data, tail8]
- [0x5DB24, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
- [0x5DB27] # EOF marker = the 0.4.dec byte length
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
+9 -6
View File
@@ -95,6 +95,7 @@ segments:
# - [0x0, rodata, head]
- [0x0, c, ov_SC02_037]
- [0x91e8, c, ov_SC02_037_jr_80131340]
- [0xdd58, c, ov_SC02_037_jr_80135EB0]
- [0xff88, c, ov_SC02_037_jr_801380E0]
- [0x171f8, c, ov_SC02_037_jr_8013F350]
- [0x31b2c, c, ov_SC02_037_jr_80159C84]
@@ -104,18 +105,20 @@ segments:
- [0x5ba68, data, tail]
- [0x9f25c, .rodata, ov_SC02_037_jr_80131340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9f270, data, tail2]
- [0x9f2d0, .rodata, ov_SC02_037_jr_80135EB0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9f2fc, data, tail3]
- [0x9f308, .rodata, ov_SC02_037_jr_801380E0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9f36c, data, tail3]
- [0x9f36c, data, tail4]
- [0x9f978, .rodata, ov_SC02_037_jr_8013F350] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9f9ac, data, tail4]
- [0x9f9ac, data, tail5]
- [0x9fc14, .rodata, ov_SC02_037_jr_80159C84] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9fc48, data, tail5]
- [0x9fc48, data, tail6]
- [0x9fc4c, .rodata, ov_SC02_037_jr_8015A3C8] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9fc88, data, tail6]
- [0x9fc88, data, tail7]
- [0x9ff24, .rodata, ov_SC02_037_jr_801789AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9ff3c, data, tail7]
- [0x9ff3c, data, tail8]
- [0xa01d4, .rodata, ov_SC02_037_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa0238, data, tail8]
- [0xa0238, data, tail9]
- [0xA198C, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
- [0xA198F] # EOF marker = the 0.4.dec byte length
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
+8 -5
View File
@@ -95,6 +95,7 @@ segments:
# - [0x0, rodata, head]
- [0x0, c, ov_SC03_107]
- [0x91e8, c, ov_SC03_107_jr_80131340]
- [0xdd58, c, ov_SC03_107_jr_80135EB0]
- [0xff88, c, ov_SC03_107_jr_801380E0]
- [0x171f8, c, ov_SC03_107_jr_8013F350]
- [0x31b2c, c, ov_SC03_107_jr_80159C84]
@@ -103,16 +104,18 @@ segments:
- [0x5a304, data, tail]
- [0x71590, .rodata, ov_SC03_107_jr_80131340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x715a4, data, tail2]
- [0x71604, .rodata, ov_SC03_107_jr_80135EB0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x71630, data, tail3]
- [0x7163c, .rodata, ov_SC03_107_jr_801380E0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x716a0, data, tail3]
- [0x716a0, data, tail4]
- [0x71cac, .rodata, ov_SC03_107_jr_8013F350] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x71ce0, data, tail4]
- [0x71ce0, data, tail5]
- [0x71f48, .rodata, ov_SC03_107_jr_80159C84] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x71f7c, data, tail5]
- [0x71f7c, data, tail6]
- [0x71f80, .rodata, ov_SC03_107_jr_8015A3C8] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x71f9c, data, tail6]
- [0x71f9c, data, tail7]
- [0x72258, .rodata, ov_SC03_107_jr_801789AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x72504, data, tail7]
- [0x72504, data, tail8]
- [0x73BE4, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
- [0x73BE7] # EOF marker = the 0.4.dec byte length
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
-622
View File
@@ -2617,625 +2617,3 @@ INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_80131340", func_8013588
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_80131340", func_80135A4C);
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_80131340", func_80135D20);
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_80131340", func_80135EB0);
s32 func_80136334(void *arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_8017E910;
extern u8 D_8017E914;
extern s16 *D_8017E918;
extern u8 D_8017E91C;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
register s32 a1v __asm__("$11");
register s32 a2v __asm__("$12");
register s32 n __asm__("$5");
register s16 *b4 __asm__("$7");
s32 d;
s32 dx;
s32 denom;
s32 result;
s32 frame_pad[2];
(void)&frame_pad;
__asm__("" : "=r"(a1v) : "0"(arg1));
a2v = arg2;
if (!(arg1 & 1)) {
dx = (s16) arg2 - (*(s16 **)&D_8017E910)[2];
d = dx;
denom = -(*(s16 **)&D_8017E91C)[2];
} else {
denom = (*(s16 **)&D_8017E91C)[2];
d = (*(s16 **)&D_8017E910)[2] - (s16) arg2;
dx = -d;
}
n = -d;
{
register s16 *b8 __asm__("$6") = *(s16 **)&D_8017E91C;
u16 *ac = *(u16 **)&D_8017E910;
b4 = D_8017E918;
b4[0] = ac[0] + n * b8[0] / denom;
b4[1] = ac[1] + n * b8[1] / denom;
b4[2] = ac[2] + dx;
}
if (b4[0] < M2C_FIELD(arg0, s16 *, 4)) return 0;
if (M2C_FIELD(arg0, s16 *, 6) < b4[0]) return 0;
if (b4[1] < M2C_FIELD(arg0, s16 *, 8)) return 0;
if (M2C_FIELD(arg0, s16 *, 0xA) < b4[1]) return 0;
if (a1v & 0x8000) {
u16 *b0 = *(u16 **)&D_8017E914;
b4[0] = b0[0];
b4[1] = b0[1];
}
D_801152AA = 0;
(*(s16 *)D_801152A8) = 0;
if (a1v & 1) {
D_8017E918[2] = a2v + 2;
__asm__ __volatile__("");
D_801152AC = 0xFFF;
} else {
D_801152AC = -0xFFF;
D_8017E918[2] = a2v - 2;
}
__asm__ __volatile__("" :: "r"(a1v), "r"(a2v));
(*(s16 *)D_80126720) = (M2C_FIELD(arg0, s16 *, 4) + M2C_FIELD(arg0, s16 *, 6)) >> 1;
D_80126722 = (M2C_FIELD(arg0, s16 *, 8) + M2C_FIELD(arg0, s16 *, 0xA)) >> 1;
result = 1;
D_80126724 = (M2C_FIELD(arg0, s16 *, 0xC) + M2C_FIELD(arg0, s16 *, 0xE)) >> 1;
return result;
}
// @class: regalloc-order — F-band exemplar func_801365B8 (x134). Real-TU reconciled (rtu_match).
// D_8017E910/B0/B8 file-scope `extern u8` holding pointers -> read via *(T**)&sym (§42c-2).
// D_8017E918 file-scope `extern s16*` -> use directly. D_80126720 file-scope `extern u8[]`
// -> single store via *(s16*)D_80126720. D_801152A8/AA/AC, D_80126722/24 block-scope externs
// (siblings use block-scope; gcc-2.7.2 does not cross-conflict block-scope externs).
s32 func_801365B8(void *arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_8017E910;
extern u8 D_8017E914;
extern s16 *D_8017E918;
extern u8 D_8017E91C;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
u16 *ac;
s16 *b8;
s16 *b4;
s16 temp_v0;
s16 temp_v1;
s32 var_a3;
s32 temp_a1;
s32 var_a1;
s32 var_v0;
s32 var_v1;
s32 a1c;
s32 a2c;
s32 cond;
register u32 zr __asm__("$0");
__asm__("addu %0,%1,$zero" : "=r"(a1c) : "r"(arg1));
cond = arg1 & 1;
a2c = arg2 + zr;
if (!cond) {
var_v1 = (s16) arg2 - (*(s16 **)&D_8017E910)[0];
var_a1 = var_v1;
var_a3 = -(*(s16 **)&D_8017E91C)[0];
} else {
var_a3 = (*(s16 **)&D_8017E91C)[0];
var_v1 = (*(s16 **)&D_8017E910)[0] - (s16) arg2;
var_a1 = -var_v1;
}
ac = *(u16 **)&D_8017E910;
b4 = D_8017E918;
b8 = *(s16 **)&D_8017E91C;
b4[0] = ac[0] + var_a1;
temp_a1 = -var_v1;
b4[1] = ac[1] + (temp_a1 * b8[1]) / var_a3;
temp_v0 = ac[2] + (temp_a1 * b8[2]) / var_a3;
b4[2] = temp_v0;
var_v0 = 0;
if (temp_v0 < M2C_FIELD(arg0, s16 *, 0xC)) {
return var_v0;
}
if (M2C_FIELD(arg0, s16 *, 0xE) < temp_v0) {
return var_v0;
}
temp_v1 = b4[1];
if (temp_v1 < M2C_FIELD(arg0, s16 *, 8)) {
return var_v0;
}
if (M2C_FIELD(arg0, s16 *, 0xA) < temp_v1) {
return var_v0;
}
__asm__("" :: "r"(a1c));
__asm__("" :: "r"(a1c));
if (a1c & 0x8000) {
b4[1] = (s16) (*(u16 **)&D_8017E914)[1];
b4[2] = (s16) (*(u16 **)&D_8017E914)[2];
}
D_801152AC = 0;
D_801152AA = 0;
if ((a1c & 1) != 0) {
*(s16 *)D_801152A8 = 0xFFF;
M2C_FIELD(D_8017E918, s16 *, 0) = a2c + 2;
} else {
*(s16 *)D_801152A8 = -0xFFF;
M2C_FIELD(D_8017E918, s16 *, 0) = a2c - 2;
}
*(s16 *)D_80126720 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 4) + M2C_FIELD(arg0, s16 *, 6)) >> 1);
D_80126722 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 8) + M2C_FIELD(arg0, s16 *, 0xA)) >> 1);
var_v0 = 1;
D_80126724 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 0xC) + M2C_FIELD(arg0, s16 *, 0xE)) >> 1);
return var_v0;
}
// @class: pointer-type — pointer-vs-array reconcile for func_80136824 (ov_SC01_077_a)
// D_8017E910/B0/B8 are file-scope `extern u8`, D_8017E918 is `extern s32 []`; each HOLDS a
// pointer value that the target loads via lw then derefs. Read as pointer via *(T**)&sym.
// D_8017E918 must be a SCALAR pointer (not s32[]) — as an array it decays and gcc CSEs the
// base address into a held reg (lui;addiu;lw 0(reg)) across the 3 reloads; as a scalar
// pointer it folds %lo (lui;lw %lo). Retype all 3 file-TU occurrences (byte-neutral: the
// siblings read it once via *(u16**)&sym == direct lw either way).
s32 func_80136824(s32 arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_8017E910;
extern u8 D_8017E914;
extern s16 *D_8017E918;
extern u8 D_8017E91C;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
register u16 *ac __asm__("$4");
register s16 *b8 __asm__("$6");
register s16 *b4 __asm__("$9");
register s32 r __asm__("$3");
register s32 pos __asm__("$12");
register s32 a1v __asm__("$5");
s16 temp_v0;
s16 temp_v1;
s32 var_a3;
s16 var_v0_3;
s32 temp_a1;
s32 var_t0;
s32 var_v1;
s16 *b4b;
u16 *p;
__asm__ ("" : "=r"(a1v) : "0"(arg1));
pos = arg2;
if (!(a1v & 1)) {
var_t0 = (s16) arg2 - (*(s16 **)&D_8017E910)[1];
var_v1 = var_t0;
var_a3 = -(*(s16 **)&D_8017E91C)[1];
} else {
var_a3 = (*(s16 **)&D_8017E91C)[1];
var_v1 = (*(s16 **)&D_8017E910)[1] - (s16) arg2;
var_t0 = -var_v1;
}
b8 = (*(s16 **)&D_8017E91C);
ac = (*(u16 **)&D_8017E910);
b4 = D_8017E918;
temp_a1 = -var_v1;
r = (temp_a1 * b8[0]) / var_a3;
b4[0] = ac[0] + r;
b4[1] = ac[1] + var_t0;
r = (temp_a1 * b8[2]) / var_a3;
temp_v0 = ac[2] + r;
b4[2] = temp_v0;
temp_v1 = b4[0];
if (temp_v1 < M2C_FIELD(((void *)arg0), s16 *, 4)) {
return 0;
}
if (M2C_FIELD(((void *)arg0), s16 *, 6) < temp_v1) {
return 0;
}
if (temp_v0 < M2C_FIELD(((void *)arg0), s16 *, 0xC)) {
return 0;
}
if (M2C_FIELD(((void *)arg0), s16 *, 0xE) < temp_v0) {
return 0;
}
if (arg1 & 0x8000) {
p = (*(u16 **)&D_8017E914);
b4[0] = (s16) p[0];
b4[2] = (s16) p[2];
}
D_801152AC = 0;
(*(s16 *)D_801152A8) = 0;
if (arg1 & 1) {
b4b = D_8017E918;
D_801152AA = 0xFFF;
__asm__ __volatile__("");
var_v0_3 = pos + 2;
} else {
b4b = D_8017E918;
D_801152AA = -0xFFF;
__asm__ __volatile__("");
var_v0_3 = pos - 2;
}
b4b[1] = var_v0_3;
__asm__ __volatile__("" :: "r"(pos));
(*(s16 *)D_80126720) = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 4) + M2C_FIELD(((void *)arg0), s16 *, 6)) >> 1);
D_80126722 = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 8) + M2C_FIELD(((void *)arg0), s16 *, 0xA)) >> 1);
D_80126724 = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 0xC) + M2C_FIELD(((void *)arg0), s16 *, 0xE)) >> 1);
return 1;
}
// @class: schedule
// @stuck: none — MATCH (76 ins, relocation-masked). Key lever: the D_80126720/22/24 tail is a
// global-short RMW `+=`. Writing it via a cast `*(u16*)&SYM = *(u16*)&SYM + x` makes gcc CSE
// the address into a base reg (base-reuse) for ALL three — but the target only base-reuses
// D_80126720 (a SCHEDULER artifact: its addr-lui fills the load-delay slot after the pb4[4]
// load, and since $v0 is live it lands in $a0, reused for load+store). D_80126722/24 use the
// plain inline 2-lui form. Fix = DIRECT scalar RMW `SYM = SYM + x` (no &/cast) → inline %hi/%lo;
// the scheduler alone forces base-reuse on #1. Also: `s16 D_80126724 = D_80126724 + int` emits
// LHU (gcc-2.7.2 drops the sign-extend because the sum is truncated to 16b on the sh) — so the
// canonical s16 decl is byte-safe here (no u16 retype needed, keeps the sign-sensitive callers).
s32 func_80136A94(s32 a0, s32 a1, s32 a2, s32 a3) {
extern u8 D_801152A8[];
extern u8 D_80126720[];
extern s16 *D_8017E918; /* holds a pointer value (*(u16**)&D_8017E918) */
extern void ApplyMatrixSV(void*, Svec_801372B0*, Svec_801372B0*);
extern void ApplyRotMatrix(void *v0, void *v1);
extern u16 D_80126722;
extern s16 D_80126724;
extern s16 D_801152AA;
extern s16 D_801152AC;
s32 out[4];
u16 *pb4;
if (a0) {
((void (*)(void *, void *, void *))ApplyMatrixSV)((void *)a3, *(void **)&D_8017E918, *(void **)&D_8017E918);
((void (*)(void *, void *, void *))ApplyMatrixSV)((void *)a3, (void *)D_80126720, (void *)D_80126720);
ApplyRotMatrix((void *)D_801152A8, (void *)out);
*(s16 *)D_801152A8 = out[0];
D_801152AA = out[1];
D_801152AC = out[2];
}
pb4 = *(u16 **)&D_8017E918;
*(s16 *)(a2) = pb4[0] + *(s32 *)(a1 + 0x48);
*(s16 *)(a2 + 2) = pb4[1] + *(s32 *)(a1 + 0x4C);
*(s16 *)(a2 + 4) = pb4[2] + *(s32 *)(a1 + 0x50);
*(u16 *)D_80126720 = *(u16 *)D_80126720 + *(s32 *)(a1 + 0x48);
D_80126722 = D_80126722 + *(s32 *)(a1 + 0x4C);
D_80126724 = D_80126724 + *(s32 *)(a1 + 0x50);
}
DEFINE_func_80136BC4() /* dedup: shared engine-core @0x80136bc4 (src/shared) */
DEFINE_func_80136C1C() /* dedup: shared engine-core @0x80136c1c (src/shared) */
void func_80136C3C(void) {
}
void func_80136C44(void) {
}
void func_80136C4C(void) {
}
void func_80136C54(void)
{
extern unsigned short D_800B99F0;
extern void (*D_8017E92C[])(void);
D_8017E92C[D_800B99F0]();
}
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_80131340", func_80136C90);
void func_80136D00(void) {
}
DEFINE_func_80136D08() /* dedup: shared engine-core @0x80136d08 (src/shared) */
DEFINE_func_80136DFC() /* dedup: shared engine-core @0x80136dfc (src/shared) */
void func_80136EC4(void) {
}
DEFINE_func_80136ECC() /* dedup: shared engine-core @0x80136ecc (src/shared) */
DEFINE_func_80136F3C() /* dedup: shared engine-core @0x80136f3c (src/shared) */
DEFINE_func_80137030() /* dedup: shared engine-core @0x80137030 (src/shared) */
DEFINE_func_80137178() /* dedup: shared engine-core @0x80137178 (src/shared) */
DEFINE_func_801372B0() /* dedup: shared engine-core @0x801372b0 (src/shared) */
DEFINE_func_801375EC() /* dedup: shared engine-core @0x801375ec (src/shared) */
extern void func_801375EC(s32 a0, s16 a1);
// @class: schedule (arg-copy placement) — PIN-FREE
// match_one: MATCH (26 ins). rtu: MATCH (26 ins) with NO //@EDIT and NO header edit.
//
// ---- RECONCILE 2026-08-01 (uc2 -> uc3) ---------------------------------------------------
// GATE ERROR was:
// jr_80135D20.c:1412 conflicting types for func_80137614 || :1362 previous declaration
// :1362 is `DEFINE_func_801375EC()`, whose expansion (src/shared/engine_core.h:2819) carries
// extern void func_80137614(s32 a0, s32 a1, s32 a2);
// and it is instantiated two lines ABOVE this function's INCLUDE_ASM splice point (:1364).
// :1412 is this draft's own definition. So the conflicting symbol is func_80137614 ITSELF
// and the axis is the §73 RETURN type: the shared header says `void`, the target ends
// `addu $v0, $s0, $zero` and callers in other overlays consume the result
// (ov_SC03_099_jr_80178D40.c already declares it `extern s32 func_80137614(s32,s32,s32)`),
// so the definition MUST stay s32. Re-voiding the definition is the decay loop: gcc-2.7.2
// silently drops the $v0 set and you get 25/26 ins, class LENGTH-DRIFT/-1.
//
// ESCAPE USED: §37/§124 ASM-LABEL ALIAS (escape #2). The definition is given a distinct C
// identifier `aF80137614` with __asm__("func_80137614"), so it never collides with the
// header's `extern void func_80137614` while still emitting the canonical symbol. Zero
// header edits, zero TU edits, blast radius 0 — this replaces uc2's //@EDIT §65b de-macroize
// of DEFINE_func_801375EC, which would have had to be repeated at all 138 sweep sites.
// The TU already uses this exact idiom 60-odd lines below
// (`void *aF801376E8(int a0, int a1) __asm__("func_801376E8");`), so it travels to siblings.
// The in-TU call from func_801375EC still binds to the header's extern declaration and
// resolves to the same symbol at link time; func_801375EC's own 10 instructions are unchanged.
//
// ---- CODEGEN (unchanged from uc2 — do not touch) -----------------------------------------
// Residual before the lever: 4 mismatched, the (sw $sN / addu $sN,$aX) prologue PAIRS mirrored —
// target births $s2<-a2 then $s3<-a1; the naive draft births $s3<-a1 then $s2<-a2 (parm order),
// and drags `sw $s3` above `sw $s2` with it. Register ASSIGNMENT was already right in both, so
// this is NOT a regalloc problem. Measured INERT: body statement order, extra plain locals,
// K&R parm-declaration order (incl. declaring a2 before a1 in the K&R decl block).
//
// LEVER — cookbook §67 (arg-copy PLACEMENT). One zero-instruction launder of the a1 parameter
// pins WHERE its entry copy materialises; a2's copy then takes the earlier slot and the register
// saves fall back into ascending order. DIRECTION MATTERS and is the opposite of the intuition:
// laundering a2 (the copy that must move EARLIER) is inert — launder the copy that must land
// LATER. §67 rule 1 respected: the laundered local is NOT pinned. A pinned variant
// (register s32 __asm__("$18") / __asm__("$19") on a2/a1) also MATCHes, but pins are strictly
// worse for the ×138 family sweep (§42e/§86 pin guard), so the pin-free single launder is banked.
//
// Shape copied from the matched next-door sibling DEFINE_func_8013767C() (engine_core.h),
// which is this function minus the 0xD8 mask and the +0x1C halfword store.
extern s32 func_801399A8(void);
extern void func_801377B4(s32 a0, s32 a1, s32 a2);
s32 aF80137614(s32 a0, s32 a1, s32 a2) __asm__("func_80137614");
s32 aF80137614(s32 a0, s32 a1, s32 a2)
{
s32 v1, s0;
__asm__("" : "=r"(v1) : "0"(a1));
s0 = func_801399A8();
if (s0 != 0) {
func_801377B4(a0, a2 & 0xD8, s0);
*(s16 *)(s0 + 0x1C) = v1;
}
return s0;
}
DEFINE_func_8013767C() /* dedup: shared engine-core @0x8013767c (src/shared) */
DEFINE_func_801376C8() /* dedup: shared engine-core @0x801376c8 (src/shared) */
/* @class: plumbing (globals-around-two-calls)
* @stuck: none — MATCH (51 ins).
*
* RECONCILE (§37/§124 ASM-LABEL ALIAS) — no TU / header edit required.
* Gate error: ov_SC01_077_jr_80135D20.c:1415: conflicting types for `func_801376E8'
* || previous declaration at :1368
* :1368 is DEFINE_func_801376C8(), the shared engine-core macro that carries
* `extern void func_801376E8(int a0, int a1);` — a VOID return. The target's last
* pre-epilogue instruction is `addu $v0, $s1, $zero`, i.e. it RETURNS &D_801269F0,
* so the definition MUST be non-void; a `void` definition makes gcc-2.7.2 merely warn
* and DROP the returned value, killing that instruction (LENGTH-DRIFT/-1, 50 ins).
* The conflict is on func_801376E8 ITSELF and is a pure RETURN-type disagreement
* (params already agree: int,int), so the §37/§124 alias applies verbatim:
* define under the C name aF801376E8 with __asm__("func_801376E8") so the C-level
* declaration never collides, while the emitted symbol is still func_801376E8.
* Codegen is untouched — an asm label renames the symbol, nothing else.
* (The earlier draft's `//@EDIT` widening of the shared extern to `void *` is a
* T2 fleet-shared edit; the alias is T0 draft-only. Cookbook §124: fix the reader,
* not the source.)
*
* Byte levers (unchanged from the passing draft):
* - `obj` local holding (s32)&D_801269F0: the address is CSEd ONCE into $s1 and reused
* for both jal args and the return (same idiom as the neighbouring func_80137B80).
* - D_80126A24 is s16 (`lh`) but D_80126A26 is u16 (`lhu`) with an explicit (s16) cast
* at the use site: gcc combines the cast's `sll 16; sra 16` with the `>>1` into
* `sll 16; sra 17`, which is exactly what the target emits. A plain s16 D_80126A26
* would give `lh; sra 1` instead.
* - D_80126A14 as u16[2] (`lhu` loads, `%lo(D_80126A14 + 0x2)` for element 1).
*/
extern void func_801377B4(s32 a0, s32 a1, s32 a2);
extern void func_80139BE0(s32 a0);
void *aF801376E8(int a0, int a1) __asm__("func_801376E8");
void *aF801376E8(int a0, int a1)
{
extern s32 D_801269F0;
extern u8 D_801269FD;
extern u16 D_80126A14[];
extern s16 D_80126A1C;
extern s16 D_80126A20;
extern s16 D_80126A22;
extern s16 D_80126A24;
extern u16 D_80126A26;
u16 *p = (u16 *)a1;
s32 obj = (s32)&D_801269F0;
func_801377B4(a0, 0x6200, obj);
D_80126A1C = 0x1C;
D_801269FD = 0;
if (p != 0) {
D_80126A14[0] = p[0];
D_80126A14[1] = p[1];
}
func_80139BE0(obj);
D_80126A20 = (D_80126A14[0] + 0x28) - ((D_80126A24 + 0x28) >> 1);
D_80126A22 = D_80126A14[1] - ((s16)D_80126A26 >> 1);
return (void *)obj;
}
DEFINE_func_801377B4() /* dedup: shared engine-core @0x801377b4 (src/shared) */
DEFINE_func_80137840() /* dedup: shared engine-core @0x80137840 (src/shared) */
extern void func_80016714(void *a0, s32 a1);
extern void func_8013A860(void);
void func_801378F0(void) {
extern u8 D_80127520[];
extern u8 aD801269F0[] __asm__("D_801269F0"); /* §37 alias: TU canon is `extern int D_801269F0` */
extern u8 D_80126A28[];
extern u8 D_8017E934[];
s32 i;
s32 si;
s32 di;
u8 *p;
func_80016714(D_80127520, 0xBFC);
i = 0;
si = 0;
p = aD801269F0;
di = 0;
do {
func_80016714(p, 0x4C);
*(u16 *)&D_80126A28[di] = *(u16 *)&D_8017E934[si];
*(u16 *)&D_80126A28[di + 2] = *(u16 *)&D_8017E934[si + 2];
*(u16 *)&D_80126A28[di + 4] = *(u16 *)&D_8017E934[si + 4];
*(u16 *)&D_80126A28[di + 6] = *(u16 *)&D_8017E934[si + 6];
p += 0x4C;
i += 1;
si += 8;
di += 0x4C;
} while (i < 3);
func_8013A860();
}
DEFINE_func_801379D8() /* dedup: shared engine-core @0x801379d8 (src/shared) */
DEFINE_func_801379EC() /* dedup: shared engine-core @0x801379ec (src/shared) */
DEFINE_func_801379FC() /* dedup: shared engine-core @0x801379fc (src/shared) */
// @class: remat
// @stuck: target CSEs &D_801269F0 once for load+call arg; force via local pointer
extern void func_80138BE0(int p);
void func_80137B80(void) {
extern s32 D_80127548[];
extern int D_8017E980;
extern int D_801269F0;
int *p = &D_801269F0;
(*(int *)&D_80127548) = 0x24;
if (*p != 0) {
((void (*)(int *))func_80138BE0)(p);
}
D_8017E980 += 1;
}
DEFINE_func_80137BD8() /* dedup: shared engine-core @0x80137bd8 (src/shared) */
// @class: plumbing
// @stuck: none — MATCH (51 ins). Three globals stored/loaded around 3 calls; &D_801269F0 held in $s1, arg1 in $s0 across calls; return reloads global D_800A5E60.
extern void func_801392FC();
extern void func_80137DD4(s32 a0, u8 *a1, u8 *a2);
extern void func_80139680(s32 a0, u8 *a1);
int func_80137D08(int arg0, int arg1, short arg2)
{
extern unsigned char D_80126A0E;
extern short D_80126A0A;
extern s16 D_801269F4;
extern int D_800A5E60;
extern int D_8017E980;
extern int D_801269F0;
unsigned char buf[3];
D_800A5E60 = arg0;
D_80126A0A = arg2;
((void (*)(void *, int, int))func_801392FC)(&D_801269F0, D_80126A0E, arg1);
if ((*(short *)&D_801269F4) == 7) {
buf[0] = 0x39;
buf[1] = 0xFF;
buf[2] = 0x71;
((void (*)(void *, void *, int))func_80137DD4)(&D_801269F0, buf, arg1);
} else if ((*(short *)&D_801269F4) == 3) {
if (D_8017E980 & 4) {
((void (*)(void *, int))func_80139680)(&D_801269F0, arg1);
}
}
return D_800A5E60;
}
DEFINE_func_80137DD4() /* dedup: shared engine-core @0x80137dd4 (src/shared) */
DEFINE_func_80137FD8() /* dedup: shared engine-core @0x80137fd8 (src/shared) */
File diff suppressed because it is too large Load Diff
-622
View File
@@ -2618,625 +2618,3 @@ INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_80131340", func_8013588
INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_80131340", func_80135A4C);
INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_80131340", func_80135D20);
INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_80131340", func_80135EB0);
s32 func_80136334(void *arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_8018419C;
extern u8 D_801841A0;
extern s16 *D_801841A4;
extern u8 D_801841A8;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
register s32 a1v __asm__("$11");
register s32 a2v __asm__("$12");
register s32 n __asm__("$5");
register s16 *b4 __asm__("$7");
s32 d;
s32 dx;
s32 denom;
s32 result;
s32 frame_pad[2];
(void)&frame_pad;
__asm__("" : "=r"(a1v) : "0"(arg1));
a2v = arg2;
if (!(arg1 & 1)) {
dx = (s16) arg2 - (*(s16 **)&D_8018419C)[2];
d = dx;
denom = -(*(s16 **)&D_801841A8)[2];
} else {
denom = (*(s16 **)&D_801841A8)[2];
d = (*(s16 **)&D_8018419C)[2] - (s16) arg2;
dx = -d;
}
n = -d;
{
register s16 *b8 __asm__("$6") = *(s16 **)&D_801841A8;
u16 *ac = *(u16 **)&D_8018419C;
b4 = D_801841A4;
b4[0] = ac[0] + n * b8[0] / denom;
b4[1] = ac[1] + n * b8[1] / denom;
b4[2] = ac[2] + dx;
}
if (b4[0] < M2C_FIELD(arg0, s16 *, 4)) return 0;
if (M2C_FIELD(arg0, s16 *, 6) < b4[0]) return 0;
if (b4[1] < M2C_FIELD(arg0, s16 *, 8)) return 0;
if (M2C_FIELD(arg0, s16 *, 0xA) < b4[1]) return 0;
if (a1v & 0x8000) {
u16 *b0 = *(u16 **)&D_801841A0;
b4[0] = b0[0];
b4[1] = b0[1];
}
D_801152AA = 0;
(*(s16 *)D_801152A8) = 0;
if (a1v & 1) {
D_801841A4[2] = a2v + 2;
__asm__ __volatile__("");
D_801152AC = 0xFFF;
} else {
D_801152AC = -0xFFF;
D_801841A4[2] = a2v - 2;
}
__asm__ __volatile__("" :: "r"(a1v), "r"(a2v));
(*(s16 *)D_80126720) = (M2C_FIELD(arg0, s16 *, 4) + M2C_FIELD(arg0, s16 *, 6)) >> 1;
D_80126722 = (M2C_FIELD(arg0, s16 *, 8) + M2C_FIELD(arg0, s16 *, 0xA)) >> 1;
result = 1;
D_80126724 = (M2C_FIELD(arg0, s16 *, 0xC) + M2C_FIELD(arg0, s16 *, 0xE)) >> 1;
return result;
}
// @class: regalloc-order — F-band exemplar func_801365B8 (x134). Real-TU reconciled (rtu_match).
// D_8018419C/B0/B8 file-scope `extern u8` holding pointers -> read via *(T**)&sym (§42c-2).
// D_801841A4 file-scope `extern s16*` -> use directly. D_80126720 file-scope `extern u8[]`
// -> single store via *(s16*)D_80126720. D_801152A8/AA/AC, D_80126722/24 block-scope externs
// (siblings use block-scope; gcc-2.7.2 does not cross-conflict block-scope externs).
s32 func_801365B8(void *arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_8018419C;
extern u8 D_801841A0;
extern s16 *D_801841A4;
extern u8 D_801841A8;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
u16 *ac;
s16 *b8;
s16 *b4;
s16 temp_v0;
s16 temp_v1;
s32 var_a3;
s32 temp_a1;
s32 var_a1;
s32 var_v0;
s32 var_v1;
s32 a1c;
s32 a2c;
s32 cond;
register u32 zr __asm__("$0");
__asm__("addu %0,%1,$zero" : "=r"(a1c) : "r"(arg1));
cond = arg1 & 1;
a2c = arg2 + zr;
if (!cond) {
var_v1 = (s16) arg2 - (*(s16 **)&D_8018419C)[0];
var_a1 = var_v1;
var_a3 = -(*(s16 **)&D_801841A8)[0];
} else {
var_a3 = (*(s16 **)&D_801841A8)[0];
var_v1 = (*(s16 **)&D_8018419C)[0] - (s16) arg2;
var_a1 = -var_v1;
}
ac = *(u16 **)&D_8018419C;
b4 = D_801841A4;
b8 = *(s16 **)&D_801841A8;
b4[0] = ac[0] + var_a1;
temp_a1 = -var_v1;
b4[1] = ac[1] + (temp_a1 * b8[1]) / var_a3;
temp_v0 = ac[2] + (temp_a1 * b8[2]) / var_a3;
b4[2] = temp_v0;
var_v0 = 0;
if (temp_v0 < M2C_FIELD(arg0, s16 *, 0xC)) {
return var_v0;
}
if (M2C_FIELD(arg0, s16 *, 0xE) < temp_v0) {
return var_v0;
}
temp_v1 = b4[1];
if (temp_v1 < M2C_FIELD(arg0, s16 *, 8)) {
return var_v0;
}
if (M2C_FIELD(arg0, s16 *, 0xA) < temp_v1) {
return var_v0;
}
__asm__("" :: "r"(a1c));
__asm__("" :: "r"(a1c));
if (a1c & 0x8000) {
b4[1] = (s16) (*(u16 **)&D_801841A0)[1];
b4[2] = (s16) (*(u16 **)&D_801841A0)[2];
}
D_801152AC = 0;
D_801152AA = 0;
if ((a1c & 1) != 0) {
*(s16 *)D_801152A8 = 0xFFF;
M2C_FIELD(D_801841A4, s16 *, 0) = a2c + 2;
} else {
*(s16 *)D_801152A8 = -0xFFF;
M2C_FIELD(D_801841A4, s16 *, 0) = a2c - 2;
}
*(s16 *)D_80126720 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 4) + M2C_FIELD(arg0, s16 *, 6)) >> 1);
D_80126722 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 8) + M2C_FIELD(arg0, s16 *, 0xA)) >> 1);
var_v0 = 1;
D_80126724 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 0xC) + M2C_FIELD(arg0, s16 *, 0xE)) >> 1);
return var_v0;
}
// @class: pointer-type — pointer-vs-array reconcile for func_80136824 (ov_SC01_077_a)
// D_8018419C/B0/B8 are file-scope `extern u8`, D_801841A4 is `extern s32 []`; each HOLDS a
// pointer value that the target loads via lw then derefs. Read as pointer via *(T**)&sym.
// D_801841A4 must be a SCALAR pointer (not s32[]) — as an array it decays and gcc CSEs the
// base address into a held reg (lui;addiu;lw 0(reg)) across the 3 reloads; as a scalar
// pointer it folds %lo (lui;lw %lo). Retype all 3 file-TU occurrences (byte-neutral: the
// siblings read it once via *(u16**)&sym == direct lw either way).
s32 func_80136824(s32 arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_8018419C;
extern u8 D_801841A0;
extern s16 *D_801841A4;
extern u8 D_801841A8;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
register u16 *ac __asm__("$4");
register s16 *b8 __asm__("$6");
register s16 *b4 __asm__("$9");
register s32 r __asm__("$3");
register s32 pos __asm__("$12");
register s32 a1v __asm__("$5");
s16 temp_v0;
s16 temp_v1;
s32 var_a3;
s16 var_v0_3;
s32 temp_a1;
s32 var_t0;
s32 var_v1;
s16 *b4b;
u16 *p;
__asm__ ("" : "=r"(a1v) : "0"(arg1));
pos = arg2;
if (!(a1v & 1)) {
var_t0 = (s16) arg2 - (*(s16 **)&D_8018419C)[1];
var_v1 = var_t0;
var_a3 = -(*(s16 **)&D_801841A8)[1];
} else {
var_a3 = (*(s16 **)&D_801841A8)[1];
var_v1 = (*(s16 **)&D_8018419C)[1] - (s16) arg2;
var_t0 = -var_v1;
}
b8 = (*(s16 **)&D_801841A8);
ac = (*(u16 **)&D_8018419C);
b4 = D_801841A4;
temp_a1 = -var_v1;
r = (temp_a1 * b8[0]) / var_a3;
b4[0] = ac[0] + r;
b4[1] = ac[1] + var_t0;
r = (temp_a1 * b8[2]) / var_a3;
temp_v0 = ac[2] + r;
b4[2] = temp_v0;
temp_v1 = b4[0];
if (temp_v1 < M2C_FIELD(((void *)arg0), s16 *, 4)) {
return 0;
}
if (M2C_FIELD(((void *)arg0), s16 *, 6) < temp_v1) {
return 0;
}
if (temp_v0 < M2C_FIELD(((void *)arg0), s16 *, 0xC)) {
return 0;
}
if (M2C_FIELD(((void *)arg0), s16 *, 0xE) < temp_v0) {
return 0;
}
if (arg1 & 0x8000) {
p = (*(u16 **)&D_801841A0);
b4[0] = (s16) p[0];
b4[2] = (s16) p[2];
}
D_801152AC = 0;
(*(s16 *)D_801152A8) = 0;
if (arg1 & 1) {
b4b = D_801841A4;
D_801152AA = 0xFFF;
__asm__ __volatile__("");
var_v0_3 = pos + 2;
} else {
b4b = D_801841A4;
D_801152AA = -0xFFF;
__asm__ __volatile__("");
var_v0_3 = pos - 2;
}
b4b[1] = var_v0_3;
__asm__ __volatile__("" :: "r"(pos));
(*(s16 *)D_80126720) = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 4) + M2C_FIELD(((void *)arg0), s16 *, 6)) >> 1);
D_80126722 = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 8) + M2C_FIELD(((void *)arg0), s16 *, 0xA)) >> 1);
D_80126724 = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 0xC) + M2C_FIELD(((void *)arg0), s16 *, 0xE)) >> 1);
return 1;
}
// @class: schedule
// @stuck: none — MATCH (76 ins, relocation-masked). Key lever: the D_80126720/22/24 tail is a
// global-short RMW `+=`. Writing it via a cast `*(u16*)&SYM = *(u16*)&SYM + x` makes gcc CSE
// the address into a base reg (base-reuse) for ALL three — but the target only base-reuses
// D_80126720 (a SCHEDULER artifact: its addr-lui fills the load-delay slot after the pb4[4]
// load, and since $v0 is live it lands in $a0, reused for load+store). D_80126722/24 use the
// plain inline 2-lui form. Fix = DIRECT scalar RMW `SYM = SYM + x` (no &/cast) → inline %hi/%lo;
// the scheduler alone forces base-reuse on #1. Also: `s16 D_80126724 = D_80126724 + int` emits
// LHU (gcc-2.7.2 drops the sign-extend because the sum is truncated to 16b on the sh) — so the
// canonical s16 decl is byte-safe here (no u16 retype needed, keeps the sign-sensitive callers).
s32 func_80136A94(s32 a0, s32 a1, s32 a2, s32 a3) {
extern u8 D_801152A8[];
extern u8 D_80126720[];
extern s16 *D_801841A4; /* holds a pointer value (*(u16**)&D_801841A4) */
extern void ApplyMatrixSV(void*, Svec_801372B0*, Svec_801372B0*);
extern void ApplyRotMatrix(void *v0, void *v1);
extern u16 D_80126722;
extern s16 D_80126724;
extern s16 D_801152AA;
extern s16 D_801152AC;
s32 out[4];
u16 *pb4;
if (a0) {
((void (*)(void *, void *, void *))ApplyMatrixSV)((void *)a3, *(void **)&D_801841A4, *(void **)&D_801841A4);
((void (*)(void *, void *, void *))ApplyMatrixSV)((void *)a3, (void *)D_80126720, (void *)D_80126720);
ApplyRotMatrix((void *)D_801152A8, (void *)out);
*(s16 *)D_801152A8 = out[0];
D_801152AA = out[1];
D_801152AC = out[2];
}
pb4 = *(u16 **)&D_801841A4;
*(s16 *)(a2) = pb4[0] + *(s32 *)(a1 + 0x48);
*(s16 *)(a2 + 2) = pb4[1] + *(s32 *)(a1 + 0x4C);
*(s16 *)(a2 + 4) = pb4[2] + *(s32 *)(a1 + 0x50);
*(u16 *)D_80126720 = *(u16 *)D_80126720 + *(s32 *)(a1 + 0x48);
D_80126722 = D_80126722 + *(s32 *)(a1 + 0x4C);
D_80126724 = D_80126724 + *(s32 *)(a1 + 0x50);
}
DEFINE_func_80136BC4() /* dedup: shared engine-core @0x80136bc4 (src/shared) */
DEFINE_func_80136C1C() /* dedup: shared engine-core @0x80136c1c (src/shared) */
void func_80136C3C(void) {
}
void func_80136C44(void) {
}
void func_80136C4C(void) {
}
void func_80136C54(void)
{
extern unsigned short D_800B99F0;
extern void (*D_801841B8[])(void);
D_801841B8[D_800B99F0]();
}
INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_80131340", func_80136C90);
void func_80136D00(void) {
}
DEFINE_func_80136D08() /* dedup: shared engine-core @0x80136d08 (src/shared) */
DEFINE_func_80136DFC() /* dedup: shared engine-core @0x80136dfc (src/shared) */
void func_80136EC4(void) {
}
DEFINE_func_80136ECC() /* dedup: shared engine-core @0x80136ecc (src/shared) */
DEFINE_func_80136F3C() /* dedup: shared engine-core @0x80136f3c (src/shared) */
DEFINE_func_80137030() /* dedup: shared engine-core @0x80137030 (src/shared) */
DEFINE_func_80137178() /* dedup: shared engine-core @0x80137178 (src/shared) */
DEFINE_func_801372B0() /* dedup: shared engine-core @0x801372b0 (src/shared) */
DEFINE_func_801375EC() /* dedup: shared engine-core @0x801375ec (src/shared) */
extern void func_801375EC(s32 a0, s16 a1);
// @class: schedule (arg-copy placement) — PIN-FREE
// match_one: MATCH (26 ins). rtu: MATCH (26 ins) with NO //@EDIT and NO header edit.
//
// ---- RECONCILE 2026-08-01 (uc2 -> uc3) ---------------------------------------------------
// GATE ERROR was:
// jr_80135D20.c:1412 conflicting types for func_80137614 || :1362 previous declaration
// :1362 is `DEFINE_func_801375EC()`, whose expansion (src/shared/engine_core.h:2819) carries
// extern void func_80137614(s32 a0, s32 a1, s32 a2);
// and it is instantiated two lines ABOVE this function's INCLUDE_ASM splice point (:1364).
// :1412 is this draft's own definition. So the conflicting symbol is func_80137614 ITSELF
// and the axis is the §73 RETURN type: the shared header says `void`, the target ends
// `addu $v0, $s0, $zero` and callers in other overlays consume the result
// (ov_SC03_099_jr_80178D40.c already declares it `extern s32 func_80137614(s32,s32,s32)`),
// so the definition MUST stay s32. Re-voiding the definition is the decay loop: gcc-2.7.2
// silently drops the $v0 set and you get 25/26 ins, class LENGTH-DRIFT/-1.
//
// ESCAPE USED: §37/§124 ASM-LABEL ALIAS (escape #2). The definition is given a distinct C
// identifier `aF80137614` with __asm__("func_80137614"), so it never collides with the
// header's `extern void func_80137614` while still emitting the canonical symbol. Zero
// header edits, zero TU edits, blast radius 0 — this replaces uc2's //@EDIT §65b de-macroize
// of DEFINE_func_801375EC, which would have had to be repeated at all 138 sweep sites.
// The TU already uses this exact idiom 60-odd lines below
// (`void *aF801376E8(int a0, int a1) __asm__("func_801376E8");`), so it travels to siblings.
// The in-TU call from func_801375EC still binds to the header's extern declaration and
// resolves to the same symbol at link time; func_801375EC's own 10 instructions are unchanged.
//
// ---- CODEGEN (unchanged from uc2 — do not touch) -----------------------------------------
// Residual before the lever: 4 mismatched, the (sw $sN / addu $sN,$aX) prologue PAIRS mirrored —
// target births $s2<-a2 then $s3<-a1; the naive draft births $s3<-a1 then $s2<-a2 (parm order),
// and drags `sw $s3` above `sw $s2` with it. Register ASSIGNMENT was already right in both, so
// this is NOT a regalloc problem. Measured INERT: body statement order, extra plain locals,
// K&R parm-declaration order (incl. declaring a2 before a1 in the K&R decl block).
//
// LEVER — cookbook §67 (arg-copy PLACEMENT). One zero-instruction launder of the a1 parameter
// pins WHERE its entry copy materialises; a2's copy then takes the earlier slot and the register
// saves fall back into ascending order. DIRECTION MATTERS and is the opposite of the intuition:
// laundering a2 (the copy that must move EARLIER) is inert — launder the copy that must land
// LATER. §67 rule 1 respected: the laundered local is NOT pinned. A pinned variant
// (register s32 __asm__("$18") / __asm__("$19") on a2/a1) also MATCHes, but pins are strictly
// worse for the ×138 family sweep (§42e/§86 pin guard), so the pin-free single launder is banked.
//
// Shape copied from the matched next-door sibling DEFINE_func_8013767C() (engine_core.h),
// which is this function minus the 0xD8 mask and the +0x1C halfword store.
extern s32 func_801399A8(void);
extern void func_801377B4(s32 a0, s32 a1, s32 a2);
s32 aF80137614(s32 a0, s32 a1, s32 a2) __asm__("func_80137614");
s32 aF80137614(s32 a0, s32 a1, s32 a2)
{
s32 v1, s0;
__asm__("" : "=r"(v1) : "0"(a1));
s0 = func_801399A8();
if (s0 != 0) {
func_801377B4(a0, a2 & 0xD8, s0);
*(s16 *)(s0 + 0x1C) = v1;
}
return s0;
}
DEFINE_func_8013767C() /* dedup: shared engine-core @0x8013767c (src/shared) */
DEFINE_func_801376C8() /* dedup: shared engine-core @0x801376c8 (src/shared) */
/* @class: plumbing (globals-around-two-calls)
* @stuck: none — MATCH (51 ins).
*
* RECONCILE (§37/§124 ASM-LABEL ALIAS) — no TU / header edit required.
* Gate error: ov_SC01_077_jr_80135D20.c:1415: conflicting types for `func_801376E8'
* || previous declaration at :1368
* :1368 is DEFINE_func_801376C8(), the shared engine-core macro that carries
* `extern void func_801376E8(int a0, int a1);` — a VOID return. The target's last
* pre-epilogue instruction is `addu $v0, $s1, $zero`, i.e. it RETURNS &D_801269F0,
* so the definition MUST be non-void; a `void` definition makes gcc-2.7.2 merely warn
* and DROP the returned value, killing that instruction (LENGTH-DRIFT/-1, 50 ins).
* The conflict is on func_801376E8 ITSELF and is a pure RETURN-type disagreement
* (params already agree: int,int), so the §37/§124 alias applies verbatim:
* define under the C name aF801376E8 with __asm__("func_801376E8") so the C-level
* declaration never collides, while the emitted symbol is still func_801376E8.
* Codegen is untouched — an asm label renames the symbol, nothing else.
* (The earlier draft's `//@EDIT` widening of the shared extern to `void *` is a
* T2 fleet-shared edit; the alias is T0 draft-only. Cookbook §124: fix the reader,
* not the source.)
*
* Byte levers (unchanged from the passing draft):
* - `obj` local holding (s32)&D_801269F0: the address is CSEd ONCE into $s1 and reused
* for both jal args and the return (same idiom as the neighbouring func_80137B80).
* - D_80126A24 is s16 (`lh`) but D_80126A26 is u16 (`lhu`) with an explicit (s16) cast
* at the use site: gcc combines the cast's `sll 16; sra 16` with the `>>1` into
* `sll 16; sra 17`, which is exactly what the target emits. A plain s16 D_80126A26
* would give `lh; sra 1` instead.
* - D_80126A14 as u16[2] (`lhu` loads, `%lo(D_80126A14 + 0x2)` for element 1).
*/
extern void func_801377B4(s32 a0, s32 a1, s32 a2);
extern void func_80139BE0(s32 a0);
void *aF801376E8(int a0, int a1) __asm__("func_801376E8");
void *aF801376E8(int a0, int a1)
{
extern s32 D_801269F0;
extern u8 D_801269FD;
extern u16 D_80126A14[];
extern s16 D_80126A1C;
extern s16 D_80126A20;
extern s16 D_80126A22;
extern s16 D_80126A24;
extern u16 D_80126A26;
u16 *p = (u16 *)a1;
s32 obj = (s32)&D_801269F0;
func_801377B4(a0, 0x6200, obj);
D_80126A1C = 0x1C;
D_801269FD = 0;
if (p != 0) {
D_80126A14[0] = p[0];
D_80126A14[1] = p[1];
}
func_80139BE0(obj);
D_80126A20 = (D_80126A14[0] + 0x28) - ((D_80126A24 + 0x28) >> 1);
D_80126A22 = D_80126A14[1] - ((s16)D_80126A26 >> 1);
return (void *)obj;
}
DEFINE_func_801377B4() /* dedup: shared engine-core @0x801377b4 (src/shared) */
DEFINE_func_80137840() /* dedup: shared engine-core @0x80137840 (src/shared) */
extern void func_80016714(void *a0, s32 a1);
extern void func_8013A860(void);
void func_801378F0(void) {
extern u8 D_80127520[];
extern u8 aD801269F0[] __asm__("D_801269F0"); /* §37 alias: TU canon is `extern int D_801269F0` */
extern u8 D_80126A28[];
extern u8 D_801841C0[];
s32 i;
s32 si;
s32 di;
u8 *p;
func_80016714(D_80127520, 0xBFC);
i = 0;
si = 0;
p = aD801269F0;
di = 0;
do {
func_80016714(p, 0x4C);
*(u16 *)&D_80126A28[di] = *(u16 *)&D_801841C0[si];
*(u16 *)&D_80126A28[di + 2] = *(u16 *)&D_801841C0[si + 2];
*(u16 *)&D_80126A28[di + 4] = *(u16 *)&D_801841C0[si + 4];
*(u16 *)&D_80126A28[di + 6] = *(u16 *)&D_801841C0[si + 6];
p += 0x4C;
i += 1;
si += 8;
di += 0x4C;
} while (i < 3);
func_8013A860();
}
DEFINE_func_801379D8() /* dedup: shared engine-core @0x801379d8 (src/shared) */
DEFINE_func_801379EC() /* dedup: shared engine-core @0x801379ec (src/shared) */
DEFINE_func_801379FC() /* dedup: shared engine-core @0x801379fc (src/shared) */
// @class: remat
// @stuck: target CSEs &D_801269F0 once for load+call arg; force via local pointer
extern void func_80138BE0(int p);
void func_80137B80(void) {
extern s32 D_80127548[];
extern int D_8018420C;
extern int D_801269F0;
int *p = &D_801269F0;
(*(int *)&D_80127548) = 0x24;
if (*p != 0) {
((void (*)(int *))func_80138BE0)(p);
}
D_8018420C += 1;
}
DEFINE_func_80137BD8() /* dedup: shared engine-core @0x80137bd8 (src/shared) */
// @class: plumbing
// @stuck: none — MATCH (51 ins). Three globals stored/loaded around 3 calls; &D_801269F0 held in $s1, arg1 in $s0 across calls; return reloads global D_800A5E60.
extern void func_801392FC();
extern void func_80137DD4(s32 a0, u8 *a1, u8 *a2);
extern void func_80139680(s32 a0, u8 *a1);
int func_80137D08(int arg0, int arg1, short arg2)
{
extern unsigned char D_80126A0E;
extern short D_80126A0A;
extern s16 D_801269F4;
extern int D_800A5E60;
extern int D_8018420C;
extern int D_801269F0;
unsigned char buf[3];
D_800A5E60 = arg0;
D_80126A0A = arg2;
((void (*)(void *, int, int))func_801392FC)(&D_801269F0, D_80126A0E, arg1);
if ((*(short *)&D_801269F4) == 7) {
buf[0] = 0x39;
buf[1] = 0xFF;
buf[2] = 0x71;
((void (*)(void *, void *, int))func_80137DD4)(&D_801269F0, buf, arg1);
} else if ((*(short *)&D_801269F4) == 3) {
if (D_8018420C & 4) {
((void (*)(void *, int))func_80139680)(&D_801269F0, arg1);
}
}
return D_800A5E60;
}
DEFINE_func_80137DD4() /* dedup: shared engine-core @0x80137dd4 (src/shared) */
DEFINE_func_80137FD8() /* dedup: shared engine-core @0x80137fd8 (src/shared) */
File diff suppressed because it is too large Load Diff
-622
View File
@@ -2619,625 +2619,3 @@ INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_80131340", func_8013588
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_80131340", func_80135A4C);
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_80131340", func_80135D20);
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_80131340", func_80135EB0);
s32 func_80136334(void *arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_80182A38;
extern u8 D_80182A3C;
extern s16 *D_80182A40;
extern u8 D_80182A44;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
register s32 a1v __asm__("$11");
register s32 a2v __asm__("$12");
register s32 n __asm__("$5");
register s16 *b4 __asm__("$7");
s32 d;
s32 dx;
s32 denom;
s32 result;
s32 frame_pad[2];
(void)&frame_pad;
__asm__("" : "=r"(a1v) : "0"(arg1));
a2v = arg2;
if (!(arg1 & 1)) {
dx = (s16) arg2 - (*(s16 **)&D_80182A38)[2];
d = dx;
denom = -(*(s16 **)&D_80182A44)[2];
} else {
denom = (*(s16 **)&D_80182A44)[2];
d = (*(s16 **)&D_80182A38)[2] - (s16) arg2;
dx = -d;
}
n = -d;
{
register s16 *b8 __asm__("$6") = *(s16 **)&D_80182A44;
u16 *ac = *(u16 **)&D_80182A38;
b4 = D_80182A40;
b4[0] = ac[0] + n * b8[0] / denom;
b4[1] = ac[1] + n * b8[1] / denom;
b4[2] = ac[2] + dx;
}
if (b4[0] < M2C_FIELD(arg0, s16 *, 4)) return 0;
if (M2C_FIELD(arg0, s16 *, 6) < b4[0]) return 0;
if (b4[1] < M2C_FIELD(arg0, s16 *, 8)) return 0;
if (M2C_FIELD(arg0, s16 *, 0xA) < b4[1]) return 0;
if (a1v & 0x8000) {
u16 *b0 = *(u16 **)&D_80182A3C;
b4[0] = b0[0];
b4[1] = b0[1];
}
D_801152AA = 0;
(*(s16 *)D_801152A8) = 0;
if (a1v & 1) {
D_80182A40[2] = a2v + 2;
__asm__ __volatile__("");
D_801152AC = 0xFFF;
} else {
D_801152AC = -0xFFF;
D_80182A40[2] = a2v - 2;
}
__asm__ __volatile__("" :: "r"(a1v), "r"(a2v));
(*(s16 *)D_80126720) = (M2C_FIELD(arg0, s16 *, 4) + M2C_FIELD(arg0, s16 *, 6)) >> 1;
D_80126722 = (M2C_FIELD(arg0, s16 *, 8) + M2C_FIELD(arg0, s16 *, 0xA)) >> 1;
result = 1;
D_80126724 = (M2C_FIELD(arg0, s16 *, 0xC) + M2C_FIELD(arg0, s16 *, 0xE)) >> 1;
return result;
}
// @class: regalloc-order — F-band exemplar func_801365B8 (x134). Real-TU reconciled (rtu_match).
// D_80182A38/B0/B8 file-scope `extern u8` holding pointers -> read via *(T**)&sym (§42c-2).
// D_80182A40 file-scope `extern s16*` -> use directly. D_80126720 file-scope `extern u8[]`
// -> single store via *(s16*)D_80126720. D_801152A8/AA/AC, D_80126722/24 block-scope externs
// (siblings use block-scope; gcc-2.7.2 does not cross-conflict block-scope externs).
s32 func_801365B8(void *arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_80182A38;
extern u8 D_80182A3C;
extern s16 *D_80182A40;
extern u8 D_80182A44;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
u16 *ac;
s16 *b8;
s16 *b4;
s16 temp_v0;
s16 temp_v1;
s32 var_a3;
s32 temp_a1;
s32 var_a1;
s32 var_v0;
s32 var_v1;
s32 a1c;
s32 a2c;
s32 cond;
register u32 zr __asm__("$0");
__asm__("addu %0,%1,$zero" : "=r"(a1c) : "r"(arg1));
cond = arg1 & 1;
a2c = arg2 + zr;
if (!cond) {
var_v1 = (s16) arg2 - (*(s16 **)&D_80182A38)[0];
var_a1 = var_v1;
var_a3 = -(*(s16 **)&D_80182A44)[0];
} else {
var_a3 = (*(s16 **)&D_80182A44)[0];
var_v1 = (*(s16 **)&D_80182A38)[0] - (s16) arg2;
var_a1 = -var_v1;
}
ac = *(u16 **)&D_80182A38;
b4 = D_80182A40;
b8 = *(s16 **)&D_80182A44;
b4[0] = ac[0] + var_a1;
temp_a1 = -var_v1;
b4[1] = ac[1] + (temp_a1 * b8[1]) / var_a3;
temp_v0 = ac[2] + (temp_a1 * b8[2]) / var_a3;
b4[2] = temp_v0;
var_v0 = 0;
if (temp_v0 < M2C_FIELD(arg0, s16 *, 0xC)) {
return var_v0;
}
if (M2C_FIELD(arg0, s16 *, 0xE) < temp_v0) {
return var_v0;
}
temp_v1 = b4[1];
if (temp_v1 < M2C_FIELD(arg0, s16 *, 8)) {
return var_v0;
}
if (M2C_FIELD(arg0, s16 *, 0xA) < temp_v1) {
return var_v0;
}
__asm__("" :: "r"(a1c));
__asm__("" :: "r"(a1c));
if (a1c & 0x8000) {
b4[1] = (s16) (*(u16 **)&D_80182A3C)[1];
b4[2] = (s16) (*(u16 **)&D_80182A3C)[2];
}
D_801152AC = 0;
D_801152AA = 0;
if ((a1c & 1) != 0) {
*(s16 *)D_801152A8 = 0xFFF;
M2C_FIELD(D_80182A40, s16 *, 0) = a2c + 2;
} else {
*(s16 *)D_801152A8 = -0xFFF;
M2C_FIELD(D_80182A40, s16 *, 0) = a2c - 2;
}
*(s16 *)D_80126720 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 4) + M2C_FIELD(arg0, s16 *, 6)) >> 1);
D_80126722 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 8) + M2C_FIELD(arg0, s16 *, 0xA)) >> 1);
var_v0 = 1;
D_80126724 = (s16) ((s32) (M2C_FIELD(arg0, s16 *, 0xC) + M2C_FIELD(arg0, s16 *, 0xE)) >> 1);
return var_v0;
}
// @class: pointer-type — pointer-vs-array reconcile for func_80136824 (ov_SC01_077_a)
// D_80182A38/B0/B8 are file-scope `extern u8`, D_80182A40 is `extern s32 []`; each HOLDS a
// pointer value that the target loads via lw then derefs. Read as pointer via *(T**)&sym.
// D_80182A40 must be a SCALAR pointer (not s32[]) — as an array it decays and gcc CSEs the
// base address into a held reg (lui;addiu;lw 0(reg)) across the 3 reloads; as a scalar
// pointer it folds %lo (lui;lw %lo). Retype all 3 file-TU occurrences (byte-neutral: the
// siblings read it once via *(u16**)&sym == direct lw either way).
s32 func_80136824(s32 arg0, s32 arg1, s32 arg2) {
extern u8 D_80126720[];
extern u8 D_80182A38;
extern u8 D_80182A3C;
extern s16 *D_80182A40;
extern u8 D_80182A44;
extern u8 D_801152A8[];
extern s16 D_801152AA;
extern s16 D_801152AC;
extern s16 D_80126722;
extern s16 D_80126724;
register u16 *ac __asm__("$4");
register s16 *b8 __asm__("$6");
register s16 *b4 __asm__("$9");
register s32 r __asm__("$3");
register s32 pos __asm__("$12");
register s32 a1v __asm__("$5");
s16 temp_v0;
s16 temp_v1;
s32 var_a3;
s16 var_v0_3;
s32 temp_a1;
s32 var_t0;
s32 var_v1;
s16 *b4b;
u16 *p;
__asm__ ("" : "=r"(a1v) : "0"(arg1));
pos = arg2;
if (!(a1v & 1)) {
var_t0 = (s16) arg2 - (*(s16 **)&D_80182A38)[1];
var_v1 = var_t0;
var_a3 = -(*(s16 **)&D_80182A44)[1];
} else {
var_a3 = (*(s16 **)&D_80182A44)[1];
var_v1 = (*(s16 **)&D_80182A38)[1] - (s16) arg2;
var_t0 = -var_v1;
}
b8 = (*(s16 **)&D_80182A44);
ac = (*(u16 **)&D_80182A38);
b4 = D_80182A40;
temp_a1 = -var_v1;
r = (temp_a1 * b8[0]) / var_a3;
b4[0] = ac[0] + r;
b4[1] = ac[1] + var_t0;
r = (temp_a1 * b8[2]) / var_a3;
temp_v0 = ac[2] + r;
b4[2] = temp_v0;
temp_v1 = b4[0];
if (temp_v1 < M2C_FIELD(((void *)arg0), s16 *, 4)) {
return 0;
}
if (M2C_FIELD(((void *)arg0), s16 *, 6) < temp_v1) {
return 0;
}
if (temp_v0 < M2C_FIELD(((void *)arg0), s16 *, 0xC)) {
return 0;
}
if (M2C_FIELD(((void *)arg0), s16 *, 0xE) < temp_v0) {
return 0;
}
if (arg1 & 0x8000) {
p = (*(u16 **)&D_80182A3C);
b4[0] = (s16) p[0];
b4[2] = (s16) p[2];
}
D_801152AC = 0;
(*(s16 *)D_801152A8) = 0;
if (arg1 & 1) {
b4b = D_80182A40;
D_801152AA = 0xFFF;
__asm__ __volatile__("");
var_v0_3 = pos + 2;
} else {
b4b = D_80182A40;
D_801152AA = -0xFFF;
__asm__ __volatile__("");
var_v0_3 = pos - 2;
}
b4b[1] = var_v0_3;
__asm__ __volatile__("" :: "r"(pos));
(*(s16 *)D_80126720) = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 4) + M2C_FIELD(((void *)arg0), s16 *, 6)) >> 1);
D_80126722 = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 8) + M2C_FIELD(((void *)arg0), s16 *, 0xA)) >> 1);
D_80126724 = (s16) ((s32) (M2C_FIELD(((void *)arg0), s16 *, 0xC) + M2C_FIELD(((void *)arg0), s16 *, 0xE)) >> 1);
return 1;
}
// @class: schedule
// @stuck: none — MATCH (76 ins, relocation-masked). Key lever: the D_80126720/22/24 tail is a
// global-short RMW `+=`. Writing it via a cast `*(u16*)&SYM = *(u16*)&SYM + x` makes gcc CSE
// the address into a base reg (base-reuse) for ALL three — but the target only base-reuses
// D_80126720 (a SCHEDULER artifact: its addr-lui fills the load-delay slot after the pb4[4]
// load, and since $v0 is live it lands in $a0, reused for load+store). D_80126722/24 use the
// plain inline 2-lui form. Fix = DIRECT scalar RMW `SYM = SYM + x` (no &/cast) → inline %hi/%lo;
// the scheduler alone forces base-reuse on #1. Also: `s16 D_80126724 = D_80126724 + int` emits
// LHU (gcc-2.7.2 drops the sign-extend because the sum is truncated to 16b on the sh) — so the
// canonical s16 decl is byte-safe here (no u16 retype needed, keeps the sign-sensitive callers).
s32 func_80136A94(s32 a0, s32 a1, s32 a2, s32 a3) {
extern u8 D_801152A8[];
extern u8 D_80126720[];
extern s16 *D_80182A40; /* holds a pointer value (*(u16**)&D_80182A40) */
extern void ApplyMatrixSV(void*, Svec_801372B0*, Svec_801372B0*);
extern void ApplyRotMatrix(void *v0, void *v1);
extern u16 D_80126722;
extern s16 D_80126724;
extern s16 D_801152AA;
extern s16 D_801152AC;
s32 out[4];
u16 *pb4;
if (a0) {
((void (*)(void *, void *, void *))ApplyMatrixSV)((void *)a3, *(void **)&D_80182A40, *(void **)&D_80182A40);
((void (*)(void *, void *, void *))ApplyMatrixSV)((void *)a3, (void *)D_80126720, (void *)D_80126720);
ApplyRotMatrix((void *)D_801152A8, (void *)out);
*(s16 *)D_801152A8 = out[0];
D_801152AA = out[1];
D_801152AC = out[2];
}
pb4 = *(u16 **)&D_80182A40;
*(s16 *)(a2) = pb4[0] + *(s32 *)(a1 + 0x48);
*(s16 *)(a2 + 2) = pb4[1] + *(s32 *)(a1 + 0x4C);
*(s16 *)(a2 + 4) = pb4[2] + *(s32 *)(a1 + 0x50);
*(u16 *)D_80126720 = *(u16 *)D_80126720 + *(s32 *)(a1 + 0x48);
D_80126722 = D_80126722 + *(s32 *)(a1 + 0x4C);
D_80126724 = D_80126724 + *(s32 *)(a1 + 0x50);
}
DEFINE_func_80136BC4() /* dedup: shared engine-core @0x80136bc4 (src/shared) */
DEFINE_func_80136C1C() /* dedup: shared engine-core @0x80136c1c (src/shared) */
void func_80136C3C(void) {
}
void func_80136C44(void) {
}
void func_80136C4C(void) {
}
void func_80136C54(void)
{
extern unsigned short D_800B99F0;
extern void (*D_80182A54[])(void);
D_80182A54[D_800B99F0]();
}
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_80131340", func_80136C90);
void func_80136D00(void) {
}
DEFINE_func_80136D08() /* dedup: shared engine-core @0x80136d08 (src/shared) */
DEFINE_func_80136DFC() /* dedup: shared engine-core @0x80136dfc (src/shared) */
void func_80136EC4(void) {
}
DEFINE_func_80136ECC() /* dedup: shared engine-core @0x80136ecc (src/shared) */
DEFINE_func_80136F3C() /* dedup: shared engine-core @0x80136f3c (src/shared) */
DEFINE_func_80137030() /* dedup: shared engine-core @0x80137030 (src/shared) */
DEFINE_func_80137178() /* dedup: shared engine-core @0x80137178 (src/shared) */
DEFINE_func_801372B0() /* dedup: shared engine-core @0x801372b0 (src/shared) */
DEFINE_func_801375EC() /* dedup: shared engine-core @0x801375ec (src/shared) */
extern void func_801375EC(s32 a0, s16 a1);
// @class: schedule (arg-copy placement) — PIN-FREE
// match_one: MATCH (26 ins). rtu: MATCH (26 ins) with NO //@EDIT and NO header edit.
//
// ---- RECONCILE 2026-08-01 (uc2 -> uc3) ---------------------------------------------------
// GATE ERROR was:
// jr_80135D20.c:1412 conflicting types for func_80137614 || :1362 previous declaration
// :1362 is `DEFINE_func_801375EC()`, whose expansion (src/shared/engine_core.h:2819) carries
// extern void func_80137614(s32 a0, s32 a1, s32 a2);
// and it is instantiated two lines ABOVE this function's INCLUDE_ASM splice point (:1364).
// :1412 is this draft's own definition. So the conflicting symbol is func_80137614 ITSELF
// and the axis is the §73 RETURN type: the shared header says `void`, the target ends
// `addu $v0, $s0, $zero` and callers in other overlays consume the result
// (ov_SC03_099_jr_80178D40.c already declares it `extern s32 func_80137614(s32,s32,s32)`),
// so the definition MUST stay s32. Re-voiding the definition is the decay loop: gcc-2.7.2
// silently drops the $v0 set and you get 25/26 ins, class LENGTH-DRIFT/-1.
//
// ESCAPE USED: §37/§124 ASM-LABEL ALIAS (escape #2). The definition is given a distinct C
// identifier `aF80137614` with __asm__("func_80137614"), so it never collides with the
// header's `extern void func_80137614` while still emitting the canonical symbol. Zero
// header edits, zero TU edits, blast radius 0 — this replaces uc2's //@EDIT §65b de-macroize
// of DEFINE_func_801375EC, which would have had to be repeated at all 138 sweep sites.
// The TU already uses this exact idiom 60-odd lines below
// (`void *aF801376E8(int a0, int a1) __asm__("func_801376E8");`), so it travels to siblings.
// The in-TU call from func_801375EC still binds to the header's extern declaration and
// resolves to the same symbol at link time; func_801375EC's own 10 instructions are unchanged.
//
// ---- CODEGEN (unchanged from uc2 — do not touch) -----------------------------------------
// Residual before the lever: 4 mismatched, the (sw $sN / addu $sN,$aX) prologue PAIRS mirrored —
// target births $s2<-a2 then $s3<-a1; the naive draft births $s3<-a1 then $s2<-a2 (parm order),
// and drags `sw $s3` above `sw $s2` with it. Register ASSIGNMENT was already right in both, so
// this is NOT a regalloc problem. Measured INERT: body statement order, extra plain locals,
// K&R parm-declaration order (incl. declaring a2 before a1 in the K&R decl block).
//
// LEVER — cookbook §67 (arg-copy PLACEMENT). One zero-instruction launder of the a1 parameter
// pins WHERE its entry copy materialises; a2's copy then takes the earlier slot and the register
// saves fall back into ascending order. DIRECTION MATTERS and is the opposite of the intuition:
// laundering a2 (the copy that must move EARLIER) is inert — launder the copy that must land
// LATER. §67 rule 1 respected: the laundered local is NOT pinned. A pinned variant
// (register s32 __asm__("$18") / __asm__("$19") on a2/a1) also MATCHes, but pins are strictly
// worse for the ×138 family sweep (§42e/§86 pin guard), so the pin-free single launder is banked.
//
// Shape copied from the matched next-door sibling DEFINE_func_8013767C() (engine_core.h),
// which is this function minus the 0xD8 mask and the +0x1C halfword store.
extern s32 func_801399A8(void);
extern void func_801377B4(s32 a0, s32 a1, s32 a2);
s32 aF80137614(s32 a0, s32 a1, s32 a2) __asm__("func_80137614");
s32 aF80137614(s32 a0, s32 a1, s32 a2)
{
s32 v1, s0;
__asm__("" : "=r"(v1) : "0"(a1));
s0 = func_801399A8();
if (s0 != 0) {
func_801377B4(a0, a2 & 0xD8, s0);
*(s16 *)(s0 + 0x1C) = v1;
}
return s0;
}
DEFINE_func_8013767C() /* dedup: shared engine-core @0x8013767c (src/shared) */
DEFINE_func_801376C8() /* dedup: shared engine-core @0x801376c8 (src/shared) */
/* @class: plumbing (globals-around-two-calls)
* @stuck: none — MATCH (51 ins).
*
* RECONCILE (§37/§124 ASM-LABEL ALIAS) — no TU / header edit required.
* Gate error: ov_SC01_077_jr_80135D20.c:1415: conflicting types for `func_801376E8'
* || previous declaration at :1368
* :1368 is DEFINE_func_801376C8(), the shared engine-core macro that carries
* `extern void func_801376E8(int a0, int a1);` — a VOID return. The target's last
* pre-epilogue instruction is `addu $v0, $s1, $zero`, i.e. it RETURNS &D_801269F0,
* so the definition MUST be non-void; a `void` definition makes gcc-2.7.2 merely warn
* and DROP the returned value, killing that instruction (LENGTH-DRIFT/-1, 50 ins).
* The conflict is on func_801376E8 ITSELF and is a pure RETURN-type disagreement
* (params already agree: int,int), so the §37/§124 alias applies verbatim:
* define under the C name aF801376E8 with __asm__("func_801376E8") so the C-level
* declaration never collides, while the emitted symbol is still func_801376E8.
* Codegen is untouched — an asm label renames the symbol, nothing else.
* (The earlier draft's `//@EDIT` widening of the shared extern to `void *` is a
* T2 fleet-shared edit; the alias is T0 draft-only. Cookbook §124: fix the reader,
* not the source.)
*
* Byte levers (unchanged from the passing draft):
* - `obj` local holding (s32)&D_801269F0: the address is CSEd ONCE into $s1 and reused
* for both jal args and the return (same idiom as the neighbouring func_80137B80).
* - D_80126A24 is s16 (`lh`) but D_80126A26 is u16 (`lhu`) with an explicit (s16) cast
* at the use site: gcc combines the cast's `sll 16; sra 16` with the `>>1` into
* `sll 16; sra 17`, which is exactly what the target emits. A plain s16 D_80126A26
* would give `lh; sra 1` instead.
* - D_80126A14 as u16[2] (`lhu` loads, `%lo(D_80126A14 + 0x2)` for element 1).
*/
extern void func_801377B4(s32 a0, s32 a1, s32 a2);
extern void func_80139BE0(s32 a0);
void *aF801376E8(int a0, int a1) __asm__("func_801376E8");
void *aF801376E8(int a0, int a1)
{
extern s32 D_801269F0;
extern u8 D_801269FD;
extern u16 D_80126A14[];
extern s16 D_80126A1C;
extern s16 D_80126A20;
extern s16 D_80126A22;
extern s16 D_80126A24;
extern u16 D_80126A26;
u16 *p = (u16 *)a1;
s32 obj = (s32)&D_801269F0;
func_801377B4(a0, 0x6200, obj);
D_80126A1C = 0x1C;
D_801269FD = 0;
if (p != 0) {
D_80126A14[0] = p[0];
D_80126A14[1] = p[1];
}
func_80139BE0(obj);
D_80126A20 = (D_80126A14[0] + 0x28) - ((D_80126A24 + 0x28) >> 1);
D_80126A22 = D_80126A14[1] - ((s16)D_80126A26 >> 1);
return (void *)obj;
}
DEFINE_func_801377B4() /* dedup: shared engine-core @0x801377b4 (src/shared) */
DEFINE_func_80137840() /* dedup: shared engine-core @0x80137840 (src/shared) */
extern void func_80016714(void *a0, s32 a1);
extern void func_8013A860(void);
void func_801378F0(void) {
extern u8 D_80127520[];
extern u8 aD801269F0[] __asm__("D_801269F0"); /* §37 alias: TU canon is `extern int D_801269F0` */
extern u8 D_80126A28[];
extern u8 D_80182A5C[];
s32 i;
s32 si;
s32 di;
u8 *p;
func_80016714(D_80127520, 0xBFC);
i = 0;
si = 0;
p = aD801269F0;
di = 0;
do {
func_80016714(p, 0x4C);
*(u16 *)&D_80126A28[di] = *(u16 *)&D_80182A5C[si];
*(u16 *)&D_80126A28[di + 2] = *(u16 *)&D_80182A5C[si + 2];
*(u16 *)&D_80126A28[di + 4] = *(u16 *)&D_80182A5C[si + 4];
*(u16 *)&D_80126A28[di + 6] = *(u16 *)&D_80182A5C[si + 6];
p += 0x4C;
i += 1;
si += 8;
di += 0x4C;
} while (i < 3);
func_8013A860();
}
DEFINE_func_801379D8() /* dedup: shared engine-core @0x801379d8 (src/shared) */
DEFINE_func_801379EC() /* dedup: shared engine-core @0x801379ec (src/shared) */
DEFINE_func_801379FC() /* dedup: shared engine-core @0x801379fc (src/shared) */
// @class: remat
// @stuck: target CSEs &D_801269F0 once for load+call arg; force via local pointer
extern void func_80138BE0(int p);
void func_80137B80(void) {
extern s32 D_80127548[];
extern int D_80182AA8;
extern int D_801269F0;
int *p = &D_801269F0;
(*(int *)&D_80127548) = 0x24;
if (*p != 0) {
((void (*)(int *))func_80138BE0)(p);
}
D_80182AA8 += 1;
}
DEFINE_func_80137BD8() /* dedup: shared engine-core @0x80137bd8 (src/shared) */
// @class: plumbing
// @stuck: none — MATCH (51 ins). Three globals stored/loaded around 3 calls; &D_801269F0 held in $s1, arg1 in $s0 across calls; return reloads global D_800A5E60.
extern void func_801392FC();
extern void func_80137DD4(s32 a0, u8 *a1, u8 *a2);
extern void func_80139680(s32 a0, u8 *a1);
int func_80137D08(int arg0, int arg1, short arg2)
{
extern unsigned char D_80126A0E;
extern short D_80126A0A;
extern s16 D_801269F4;
extern int D_800A5E60;
extern int D_80182AA8;
extern int D_801269F0;
unsigned char buf[3];
D_800A5E60 = arg0;
D_80126A0A = arg2;
((void (*)(void *, int, int))func_801392FC)(&D_801269F0, D_80126A0E, arg1);
if ((*(short *)&D_801269F4) == 7) {
buf[0] = 0x39;
buf[1] = 0xFF;
buf[2] = 0x71;
((void (*)(void *, void *, int))func_80137DD4)(&D_801269F0, buf, arg1);
} else if ((*(short *)&D_801269F4) == 3) {
if (D_80182AA8 & 4) {
((void (*)(void *, int))func_80139680)(&D_801269F0, arg1);
}
}
return D_800A5E60;
}
DEFINE_func_80137DD4() /* dedup: shared engine-core @0x80137dd4 (src/shared) */
DEFINE_func_80137FD8() /* dedup: shared engine-core @0x80137fd8 (src/shared) */
File diff suppressed because it is too large Load Diff