mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-30 07:31:59 -04:00
feat(phase-30 S48-0b): jtbl family func_80135D20 — 3/3 blocked-binary siblings banked
This commit is contained in:
@@ -4918,6 +4918,7 @@ ov_MAIN_012_SPLAT_YAML := config/splat.ov_MAIN_012.yaml
|
||||
ov_MAIN_012_JTBL_INTERLEAVE := --order tail.data.o,ov_MAIN_012.o,tail2.data.o,ov_MAIN_012_jr_80131340.o,tail3.data.o,ov_MAIN_012_jr_80135A4C.o,tail4.data.o,ov_MAIN_012_jr_80135EB0.o,tail5.data.o,ov_MAIN_012_jr_801380E0.o,tail6.data.o,ov_MAIN_012_jr_8013F350.o,tail7.data.o,ov_MAIN_012_jr_801555F4.o,tail8.data.o,ov_MAIN_012_jr_80159C84.o,tail9.data.o,ov_MAIN_012_jr_8015A3C8.o,tail10.data.o,ov_MAIN_012_jr_801789AC.o,tail11.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_MAIN_012/ov_MAIN_012.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_MAIN_012/ov_MAIN_012_jr_80131340.o: JTBL_PADS := 0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14,+0x2c
|
||||
build/src/ov_MAIN_012/ov_MAIN_012_jr_80135A4C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
build/src/ov_MAIN_012/ov_MAIN_012_jr_8013F350.o: JTBL_PADS := 0,0,4,0,4,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38,+0x58,+0x70,+0x90,+0xa8
|
||||
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
|
||||
@@ -4945,6 +4946,7 @@ ov_SC02_037_SPLAT_YAML := config/splat.ov_SC02_037.yaml
|
||||
ov_SC02_037_JTBL_INTERLEAVE := --order tail.data.o,ov_SC02_037.o,tail2.data.o,ov_SC02_037_jr_80131340.o,tail3.data.o,ov_SC02_037_jr_80135A4C.o,tail4.data.o,ov_SC02_037_jr_80135EB0.o,tail5.data.o,ov_SC02_037_jr_801380E0.o,tail6.data.o,ov_SC02_037_jr_8013F350.o,tail7.data.o,ov_SC02_037_jr_801555F4.o,tail8.data.o,ov_SC02_037_jr_80159C84.o,tail9.data.o,ov_SC02_037_jr_8015A3C8.o,tail10.data.o,ov_SC02_037_jr_801789AC.o,tail11.data.o,ov_SC02_037_jr_8017AE2C.o,tail12.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC02_037/ov_SC02_037.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC02_037/ov_SC02_037_jr_80131340.o: JTBL_PADS := 0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14,+0x2c
|
||||
build/src/ov_SC02_037/ov_SC02_037_jr_80135A4C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
build/src/ov_SC02_037/ov_SC02_037_jr_8013F350.o: JTBL_PADS := 0,0,4,0,4,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38,+0x58,+0x70,+0x90,+0xa8
|
||||
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,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x40,+0x60
|
||||
@@ -4973,6 +4975,7 @@ ov_SC03_107_SPLAT_YAML := config/splat.ov_SC03_107.yaml
|
||||
ov_SC03_107_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_107.o,tail2.data.o,ov_SC03_107_jr_80131340.o,tail3.data.o,ov_SC03_107_jr_80135A4C.o,tail4.data.o,ov_SC03_107_jr_80135EB0.o,tail5.data.o,ov_SC03_107_jr_801380E0.o,tail6.data.o,ov_SC03_107_jr_8013F350.o,tail7.data.o,ov_SC03_107_jr_801555F4.o,tail8.data.o,ov_SC03_107_jr_80159C84.o,tail9.data.o,ov_SC03_107_jr_8015A3C8.o,tail10.data.o,ov_SC03_107_jr_801789AC.o,tail11.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC03_107/ov_SC03_107.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC03_107/ov_SC03_107_jr_80131340.o: JTBL_PADS := 0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14,+0x2c
|
||||
build/src/ov_SC03_107/ov_SC03_107_jr_80135A4C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
build/src/ov_SC03_107/ov_SC03_107_jr_8013F350.o: JTBL_PADS := 0,0,4,0,4,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38,+0x58,+0x70,+0x90,+0xa8
|
||||
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
|
||||
|
||||
@@ -109,7 +109,7 @@ segments:
|
||||
- [0x5ad78, .rodata, ov_MAIN_012_jr_80131340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x5adb8, data, tail3]
|
||||
- [0x5adbc, .rodata, ov_MAIN_012_jr_80135A4C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x5add0, data, tail4]
|
||||
- [0x5ade8, data, tail4]
|
||||
- [0x5adec, .rodata, ov_MAIN_012_jr_80135EB0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x5ae18, data, tail5]
|
||||
- [0x5ae24, .rodata, ov_MAIN_012_jr_801380E0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
|
||||
@@ -110,7 +110,7 @@ segments:
|
||||
- [0x9f25c, .rodata, ov_SC02_037_jr_80131340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x9f29c, data, tail3]
|
||||
- [0x9f2a0, .rodata, ov_SC02_037_jr_80135A4C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x9f2b4, data, tail4]
|
||||
- [0x9f2cc, data, tail4]
|
||||
- [0x9f2d0, .rodata, ov_SC02_037_jr_80135EB0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x9f2fc, data, tail5]
|
||||
- [0x9f308, .rodata, ov_SC02_037_jr_801380E0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
|
||||
@@ -109,7 +109,7 @@ segments:
|
||||
- [0x71590, .rodata, ov_SC03_107_jr_80131340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x715d0, data, tail3]
|
||||
- [0x715d4, .rodata, ov_SC03_107_jr_80135A4C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x715e8, data, tail4]
|
||||
- [0x71600, data, tail4]
|
||||
- [0x71604, .rodata, ov_SC03_107_jr_80135EB0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x71630, data, tail5]
|
||||
- [0x7163c, .rodata, ov_SC03_107_jr_801380E0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
|
||||
@@ -716,5 +716,111 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_80135A4C", func_80135D20);
|
||||
|
||||
|
||||
|
||||
// @class: regalloc-order
|
||||
// @stuck: none — MATCH (match_one 100/100 + rtu_match real-TU); needs the PAIRED //@EDIT on ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(return s16->s32 + `s32 result;`->`s16 result;`, whole-TU byte-neutral, verified) + one $s1 pin on `flag`
|
||||
//@EDIT s16 ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(void *param_1, s32 param_2, s16 *param_3, s16 *param_4)||s32 ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(void *param_1, s32 param_2, s16 *param_3, s16 *param_4)
|
||||
//@EDIT s32 result;|| s16 result;
|
||||
|
||||
/* func_80135D20 — "is <thing> visible/hittable from <pos>" gate (100 ins, ov_SC06_018 jr_8012ACE0).
|
||||
*
|
||||
* Builds a second probe point 0x300 above the caller's point on the stack, asks func_80135480 to
|
||||
* cull/transform it, then dispatches on that result (jtbl_801D2A90, cases 0..4; default falls
|
||||
* through with p/flag/q UNINITIALISED — reproduced by leaving the switch without a default).
|
||||
*
|
||||
* Load-bearing details (do not "clean up"):
|
||||
* - `u8 dead[96];` is a DEAD aggregate whose only job is the frame layout: it forces the probe
|
||||
* buffer to sp+0x70 and the frame to 0x98 (gcc-2.7.2 assign_stack_local runs at expand time, so
|
||||
* an unreferenced aggregate still owns its slot). Remove it and every sp offset shifts by 0x60.
|
||||
* - `__asm__ __volatile__("")` is the §5a CROSS-JUMP BARRIER: without it jump.c merges the peeled
|
||||
* first func_80135EB0 probe into the list loop (100 ins -> 88).
|
||||
* - the explicit goto layout (loop / hit / body / elsepath) reproduces the target's basic-block
|
||||
* ORDER: the `hit` block sits physically between the loop test and the loop body. A structured
|
||||
* while/do-while emits the inverted layout (-3 ins, 39 diffs).
|
||||
* - `register s32 flag __asm__("$17")` is a §17 pin. WITHOUT it gcc ties `arg1`->$s1 / `flag`->$s2,
|
||||
* the reverse of the target (12 diffs, everything else already byte-exact). Pin-free attempts
|
||||
* (declaring `flag` before `p`; assigning `flag` first in every case body) were both tried and
|
||||
* do NOT flip the tie-break. The pin's live range does cross calls, so prefer ×1 banking.
|
||||
* - func_80135480 must be declared INT-returning here: the target does NOT re-extend the callee's
|
||||
* result before the switch (`addu $v1,$v0,$zero` only), while an s16-returning prototype costs a
|
||||
* `sll/sra 16` pair. The two //@EDIT lines flip the in-TU definition s16->s32 and narrow its local
|
||||
* `result` to s16 instead — the narrowing simply moves from the return-type conversion to the
|
||||
* assignment, so the WHOLE TU compiles byte-identically (objdump-diffed: only the filename line
|
||||
* changes). Both edits are required; flipping the return type alone drops func_80135480's tail
|
||||
* `sll/sra` and shortens it by one instruction.
|
||||
*/
|
||||
extern s16 func_80135480(void*, s32, s16*, s16*);
|
||||
extern s32 func_80135EB0(void *arg0, s32 arg1_);
|
||||
extern s32 func_801345F8(s32 arg);
|
||||
extern s32 func_80136A94(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern s32 D_80184134;
|
||||
extern s32 D_80184154;
|
||||
|
||||
s32 func_80135D20(s32 arg0, s32 arg1, u16 *arg2)
|
||||
{
|
||||
u8 dead[96];
|
||||
u16 sp[3];
|
||||
s32 *p;
|
||||
register s32 flag __asm__("$17");
|
||||
s32 q;
|
||||
|
||||
sp[0] = arg2[0];
|
||||
sp[1] = arg2[1] + 0x300;
|
||||
sp[2] = arg2[2];
|
||||
switch (((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)((void *)arg0, arg1, (s16 *)arg2, (s16 *)sp)) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
q = arg0 + 0x34;
|
||||
p = (s32 *)((arg1 & 0xFFFFFFF) | 0x80000000);
|
||||
flag = 0;
|
||||
break;
|
||||
case 2:
|
||||
q = arg0 + 0x34;
|
||||
p = (s32 *)((arg1 & 0xFFFFFFF) | 0x80000000);
|
||||
flag = 1;
|
||||
break;
|
||||
case 3:
|
||||
q = arg0 + 0x34;
|
||||
p = &D_80184154;
|
||||
flag = 0;
|
||||
break;
|
||||
case 4:
|
||||
q = (s32)&D_80184134;
|
||||
p = &D_80184154;
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
if (arg1 >= 0) {
|
||||
goto elsepath;
|
||||
}
|
||||
if (func_80135EB0(p, 0) != 0) {
|
||||
goto hit;
|
||||
}
|
||||
p = (s32 *)*p;
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
__asm__ __volatile__("");
|
||||
loop:
|
||||
if (func_80135EB0(p, 0) == 0) {
|
||||
goto body;
|
||||
}
|
||||
hit:
|
||||
func_80136A94(flag, arg0, (s32)arg2, q);
|
||||
return 1;
|
||||
body:
|
||||
p = (s32 *)*p;
|
||||
if (p != NULL) {
|
||||
goto loop;
|
||||
}
|
||||
return 0;
|
||||
elsepath:
|
||||
if (func_801345F8(arg1) != 0) {
|
||||
goto hit;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -716,5 +716,111 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_80135A4C", func_80135D20);
|
||||
|
||||
|
||||
|
||||
// @class: regalloc-order
|
||||
// @stuck: none — MATCH (match_one 100/100 + rtu_match real-TU); needs the PAIRED //@EDIT on ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(return s16->s32 + `s32 result;`->`s16 result;`, whole-TU byte-neutral, verified) + one $s1 pin on `flag`
|
||||
//@EDIT s16 ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(void *param_1, s32 param_2, s16 *param_3, s16 *param_4)||s32 ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(void *param_1, s32 param_2, s16 *param_3, s16 *param_4)
|
||||
//@EDIT s32 result;|| s16 result;
|
||||
|
||||
/* func_80135D20 — "is <thing> visible/hittable from <pos>" gate (100 ins, ov_SC06_018 jr_8012ACE0).
|
||||
*
|
||||
* Builds a second probe point 0x300 above the caller's point on the stack, asks func_80135480 to
|
||||
* cull/transform it, then dispatches on that result (jtbl_801D2A90, cases 0..4; default falls
|
||||
* through with p/flag/q UNINITIALISED — reproduced by leaving the switch without a default).
|
||||
*
|
||||
* Load-bearing details (do not "clean up"):
|
||||
* - `u8 dead[96];` is a DEAD aggregate whose only job is the frame layout: it forces the probe
|
||||
* buffer to sp+0x70 and the frame to 0x98 (gcc-2.7.2 assign_stack_local runs at expand time, so
|
||||
* an unreferenced aggregate still owns its slot). Remove it and every sp offset shifts by 0x60.
|
||||
* - `__asm__ __volatile__("")` is the §5a CROSS-JUMP BARRIER: without it jump.c merges the peeled
|
||||
* first func_80135EB0 probe into the list loop (100 ins -> 88).
|
||||
* - the explicit goto layout (loop / hit / body / elsepath) reproduces the target's basic-block
|
||||
* ORDER: the `hit` block sits physically between the loop test and the loop body. A structured
|
||||
* while/do-while emits the inverted layout (-3 ins, 39 diffs).
|
||||
* - `register s32 flag __asm__("$17")` is a §17 pin. WITHOUT it gcc ties `arg1`->$s1 / `flag`->$s2,
|
||||
* the reverse of the target (12 diffs, everything else already byte-exact). Pin-free attempts
|
||||
* (declaring `flag` before `p`; assigning `flag` first in every case body) were both tried and
|
||||
* do NOT flip the tie-break. The pin's live range does cross calls, so prefer ×1 banking.
|
||||
* - func_80135480 must be declared INT-returning here: the target does NOT re-extend the callee's
|
||||
* result before the switch (`addu $v1,$v0,$zero` only), while an s16-returning prototype costs a
|
||||
* `sll/sra 16` pair. The two //@EDIT lines flip the in-TU definition s16->s32 and narrow its local
|
||||
* `result` to s16 instead — the narrowing simply moves from the return-type conversion to the
|
||||
* assignment, so the WHOLE TU compiles byte-identically (objdump-diffed: only the filename line
|
||||
* changes). Both edits are required; flipping the return type alone drops func_80135480's tail
|
||||
* `sll/sra` and shortens it by one instruction.
|
||||
*/
|
||||
extern s16 func_80135480(void*, s32, s16*, s16*);
|
||||
extern s32 func_80135EB0(void *arg0, s32 arg1_);
|
||||
extern s32 func_801345F8(s32 arg);
|
||||
extern s32 func_80136A94(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern s32 D_801C842C;
|
||||
extern s32 D_801C844C;
|
||||
|
||||
s32 func_80135D20(s32 arg0, s32 arg1, u16 *arg2)
|
||||
{
|
||||
u8 dead[96];
|
||||
u16 sp[3];
|
||||
s32 *p;
|
||||
register s32 flag __asm__("$17");
|
||||
s32 q;
|
||||
|
||||
sp[0] = arg2[0];
|
||||
sp[1] = arg2[1] + 0x300;
|
||||
sp[2] = arg2[2];
|
||||
switch (((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)((void *)arg0, arg1, (s16 *)arg2, (s16 *)sp)) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
q = arg0 + 0x34;
|
||||
p = (s32 *)((arg1 & 0xFFFFFFF) | 0x80000000);
|
||||
flag = 0;
|
||||
break;
|
||||
case 2:
|
||||
q = arg0 + 0x34;
|
||||
p = (s32 *)((arg1 & 0xFFFFFFF) | 0x80000000);
|
||||
flag = 1;
|
||||
break;
|
||||
case 3:
|
||||
q = arg0 + 0x34;
|
||||
p = &D_801C844C;
|
||||
flag = 0;
|
||||
break;
|
||||
case 4:
|
||||
q = (s32)&D_801C842C;
|
||||
p = &D_801C844C;
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
if (arg1 >= 0) {
|
||||
goto elsepath;
|
||||
}
|
||||
if (func_80135EB0(p, 0) != 0) {
|
||||
goto hit;
|
||||
}
|
||||
p = (s32 *)*p;
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
__asm__ __volatile__("");
|
||||
loop:
|
||||
if (func_80135EB0(p, 0) == 0) {
|
||||
goto body;
|
||||
}
|
||||
hit:
|
||||
func_80136A94(flag, arg0, (s32)arg2, q);
|
||||
return 1;
|
||||
body:
|
||||
p = (s32 *)*p;
|
||||
if (p != NULL) {
|
||||
goto loop;
|
||||
}
|
||||
return 0;
|
||||
elsepath:
|
||||
if (func_801345F8(arg1) != 0) {
|
||||
goto hit;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -717,5 +717,111 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_80135A4C", func_80135D20);
|
||||
|
||||
|
||||
|
||||
// @class: regalloc-order
|
||||
// @stuck: none — MATCH (match_one 100/100 + rtu_match real-TU); needs the PAIRED //@EDIT on ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(return s16->s32 + `s32 result;`->`s16 result;`, whole-TU byte-neutral, verified) + one $s1 pin on `flag`
|
||||
//@EDIT s16 ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(void *param_1, s32 param_2, s16 *param_3, s16 *param_4)||s32 ((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)(void *param_1, s32 param_2, s16 *param_3, s16 *param_4)
|
||||
//@EDIT s32 result;|| s16 result;
|
||||
|
||||
/* func_80135D20 — "is <thing> visible/hittable from <pos>" gate (100 ins, ov_SC06_018 jr_8012ACE0).
|
||||
*
|
||||
* Builds a second probe point 0x300 above the caller's point on the stack, asks func_80135480 to
|
||||
* cull/transform it, then dispatches on that result (jtbl_801D2A90, cases 0..4; default falls
|
||||
* through with p/flag/q UNINITIALISED — reproduced by leaving the switch without a default).
|
||||
*
|
||||
* Load-bearing details (do not "clean up"):
|
||||
* - `u8 dead[96];` is a DEAD aggregate whose only job is the frame layout: it forces the probe
|
||||
* buffer to sp+0x70 and the frame to 0x98 (gcc-2.7.2 assign_stack_local runs at expand time, so
|
||||
* an unreferenced aggregate still owns its slot). Remove it and every sp offset shifts by 0x60.
|
||||
* - `__asm__ __volatile__("")` is the §5a CROSS-JUMP BARRIER: without it jump.c merges the peeled
|
||||
* first func_80135EB0 probe into the list loop (100 ins -> 88).
|
||||
* - the explicit goto layout (loop / hit / body / elsepath) reproduces the target's basic-block
|
||||
* ORDER: the `hit` block sits physically between the loop test and the loop body. A structured
|
||||
* while/do-while emits the inverted layout (-3 ins, 39 diffs).
|
||||
* - `register s32 flag __asm__("$17")` is a §17 pin. WITHOUT it gcc ties `arg1`->$s1 / `flag`->$s2,
|
||||
* the reverse of the target (12 diffs, everything else already byte-exact). Pin-free attempts
|
||||
* (declaring `flag` before `p`; assigning `flag` first in every case body) were both tried and
|
||||
* do NOT flip the tie-break. The pin's live range does cross calls, so prefer ×1 banking.
|
||||
* - func_80135480 must be declared INT-returning here: the target does NOT re-extend the callee's
|
||||
* result before the switch (`addu $v1,$v0,$zero` only), while an s16-returning prototype costs a
|
||||
* `sll/sra 16` pair. The two //@EDIT lines flip the in-TU definition s16->s32 and narrow its local
|
||||
* `result` to s16 instead — the narrowing simply moves from the return-type conversion to the
|
||||
* assignment, so the WHOLE TU compiles byte-identically (objdump-diffed: only the filename line
|
||||
* changes). Both edits are required; flipping the return type alone drops func_80135480's tail
|
||||
* `sll/sra` and shortens it by one instruction.
|
||||
*/
|
||||
extern s16 func_80135480(void*, s32, s16*, s16*);
|
||||
extern s32 func_80135EB0(void *arg0, s32 arg1_);
|
||||
extern s32 func_801345F8(s32 arg);
|
||||
extern s32 func_80136A94(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern s32 D_8019A78C;
|
||||
extern s32 D_8019A7AC;
|
||||
|
||||
s32 func_80135D20(s32 arg0, s32 arg1, u16 *arg2)
|
||||
{
|
||||
u8 dead[96];
|
||||
u16 sp[3];
|
||||
s32 *p;
|
||||
register s32 flag __asm__("$17");
|
||||
s32 q;
|
||||
|
||||
sp[0] = arg2[0];
|
||||
sp[1] = arg2[1] + 0x300;
|
||||
sp[2] = arg2[2];
|
||||
switch (((s32 (*)(void *, s32, s16 *, s16 *))func_80135480)((void *)arg0, arg1, (s16 *)arg2, (s16 *)sp)) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
q = arg0 + 0x34;
|
||||
p = (s32 *)((arg1 & 0xFFFFFFF) | 0x80000000);
|
||||
flag = 0;
|
||||
break;
|
||||
case 2:
|
||||
q = arg0 + 0x34;
|
||||
p = (s32 *)((arg1 & 0xFFFFFFF) | 0x80000000);
|
||||
flag = 1;
|
||||
break;
|
||||
case 3:
|
||||
q = arg0 + 0x34;
|
||||
p = &D_8019A7AC;
|
||||
flag = 0;
|
||||
break;
|
||||
case 4:
|
||||
q = (s32)&D_8019A78C;
|
||||
p = &D_8019A7AC;
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
if (arg1 >= 0) {
|
||||
goto elsepath;
|
||||
}
|
||||
if (func_80135EB0(p, 0) != 0) {
|
||||
goto hit;
|
||||
}
|
||||
p = (s32 *)*p;
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
__asm__ __volatile__("");
|
||||
loop:
|
||||
if (func_80135EB0(p, 0) == 0) {
|
||||
goto body;
|
||||
}
|
||||
hit:
|
||||
func_80136A94(flag, arg0, (s32)arg2, q);
|
||||
return 1;
|
||||
body:
|
||||
p = (s32 *)*p;
|
||||
if (p != NULL) {
|
||||
goto loop;
|
||||
}
|
||||
return 0;
|
||||
elsepath:
|
||||
if (func_801345F8(arg1) != 0) {
|
||||
goto hit;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user