mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-29 23:24:32 -04:00
feat(decomp): worker gate — +2 fns x0 propagated (fleet 95.2%)
This commit is contained in:
@@ -4192,7 +4192,17 @@ void func_80188694(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_801863CC", func_80188748);
|
||||
void func_80188748(void *a0) {
|
||||
s32 *p = *(s32 **)((s32)a0 + 0x20);
|
||||
p[1] = p[1] | 0x58000000;
|
||||
*(s16 *)((s32)p + 0x1E) = 0;
|
||||
*(s16 *)((s32)p + 0x18) = 0;
|
||||
*(s16 *)((s32)p + 0x1A) = 0;
|
||||
*(s16 *)((s32)p + 0x1C) = 0;
|
||||
*(s32 *)((s32)a0 + 0x2C) = 0x400;
|
||||
*(u16 *)((s32)a0 + 0x2) = *(u16 *)((s32)a0 + 0x2) + 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_801863CC", func_80188788);
|
||||
|
||||
@@ -4244,7 +4254,152 @@ s32 func_801887DC(s32 a0, s16 a1, s16 a2) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_801863CC", func_80188990);
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* func_80188990 -- adapted from func_80181500 (src/ov_SC03_107/ov_SC03_107_jr_801789AC.c),
|
||||
* a byte-matched sibling in ov_SC03_107. Measured 9-site / 30-instruction diff vs that seed:
|
||||
*
|
||||
* 1. The seed's leading `if (*(s16*)(a0+0xA) >= 0x10) { func_80131C78(a0); ... }` guard is
|
||||
* ABSENT here -- the target .s goes straight from the prologue into the `lbu $v1,0xC2($s0)`
|
||||
* switch read with no lh/slti/bnez/jal func_80131C78 at all.
|
||||
* 2. In case 0's `if (D & 0x6000) { if (D & 0x1000) {...return;} ... }` body, the order of the
|
||||
* two calls is swapped relative to the seed: func_8002D4C8(0x754, 0) now precedes
|
||||
* func_80143B6C(a0, 1) (seed had func_80143B6C first). Case 1 already had this order in the
|
||||
* seed (that's the whole point of the `t = D_..` scheduling comment there), so case 1 is
|
||||
* unchanged.
|
||||
* 3. In case 2, both `* 15 / 16` roundings lost their `bgez/addiu +0xF` sign-correction dance --
|
||||
* the target uses a plain arithmetic right shift (`(x * 15) >> 4`), not a C signed division.
|
||||
* 4. The seed's tail call `func_8018134C(a0, -0x28, 1);` is not present anywhere in the target
|
||||
* .s (func_8018134C's opcode/address never appears) -- it is simply not called here.
|
||||
*
|
||||
* Everything else (switch skeleton, both early-return blocks, case1 body, the shared >=0x78/>=0x28
|
||||
* reset tail, and the final 0x108 countdown) is structurally identical to the seed.
|
||||
*
|
||||
* Decls chosen to agree with the seed's own choices (func_8012CBCC returns void there too, read
|
||||
* through the same function-pointer cast; D_801D46D8/D_801D46DC are this overlay's counterparts of
|
||||
* the seed's D_8019BBC8/D_8019BBCC, declared nowhere else in this standalone draft -- free choice).
|
||||
*/
|
||||
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
extern s32 func_8012B030(u8 *a0);
|
||||
extern void func_8012CBCC(s32);
|
||||
extern void func_80131C78(s32 a0);
|
||||
extern s32 func_80143B6C(s32 a0, s32 a1);
|
||||
extern void func_800291C8(s32, s32);
|
||||
|
||||
extern s32 D_801D46D8;
|
||||
extern s32 D_801D46DC;
|
||||
|
||||
void func_80188990(s32 a0) {
|
||||
/* §162i1 dead-local pad: target frame 0x28 = args 0x10 + vars 0x10 + 4*2 regs;
|
||||
* the raw draft compiles vars=0. Never read, never &-taken, >=2 elements. */
|
||||
s32 pad[4];
|
||||
|
||||
switch (*(u8 *)(a0 + 0xC2)) {
|
||||
case 0:
|
||||
D_801D46D8 = ((s32 (*)(s32))func_8012CBCC)(a0);
|
||||
if (D_801D46D8 & 0x6000) {
|
||||
if (D_801D46D8 & 0x1000) {
|
||||
*(s16 *)(a0 + 0x2) = 2;
|
||||
*(u8 *)(a0 + 0xC1) = 0;
|
||||
*(s16 *)(a0 + 0x5E) = 0;
|
||||
*(s32 *)(a0 + 0x1C) = 0x30;
|
||||
func_8002D4C8(0x7DF, 0);
|
||||
func_800291C8(0xA, *(s16 *)(a0 + 0xFE));
|
||||
return;
|
||||
}
|
||||
func_8002D4C8(0x754, 0);
|
||||
func_80143B6C(a0, 1);
|
||||
*(u8 *)(a0 + 0xC2) = 1;
|
||||
*(s32 *)(a0 + 0x14) = 0xFFF30000;
|
||||
*(s32 *)(a0 + 0x1C) = 0;
|
||||
*(s32 *)(a0 + 0x10) = *(s32 *)(a0 + 0x10) >> 2;
|
||||
*(s32 *)(a0 + 0x18) = *(s32 *)(a0 + 0x18) >> 2;
|
||||
}
|
||||
*(s32 *)(a0 + 0x1C) += 1;
|
||||
if (*(s32 *)(a0 + 0x1C) >= 0x78) {
|
||||
func_80131C78(a0);
|
||||
*(s16 *)(a0 + 0x2) = 2;
|
||||
*(s32 *)(a0 + 0x1C) = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
D_801D46DC = *(s32 *)(a0 + 0x14);
|
||||
D_801D46D8 = ((s32 (*)(s32))func_8012CBCC)(a0);
|
||||
if (D_801D46D8 & 0x6000) {
|
||||
if (D_801D46D8 & 0x1000) {
|
||||
*(s16 *)(a0 + 0x2) = 2;
|
||||
*(u8 *)(a0 + 0xC1) = 0;
|
||||
*(s16 *)(a0 + 0x5E) = 0;
|
||||
*(s32 *)(a0 + 0x1C) = 0x30;
|
||||
func_8002D4C8(0x7DF, 0);
|
||||
func_800291C8(0xA, *(s16 *)(a0 + 0xFE));
|
||||
return;
|
||||
}
|
||||
{
|
||||
/* The read of D_801D46DC MUST precede the two pointer stores in the
|
||||
* source: gcc-2.7.2's scheduler cannot hoist a symbol_ref load above a
|
||||
* store through a register base (may-alias), so writing it inline in the
|
||||
* `-D_801D46DC` expression leaves the load-delay slot unfilled -> a nop,
|
||||
* and the function is 1 instruction long. */
|
||||
s32 t;
|
||||
func_8002D4C8(0x754, 0);
|
||||
func_80143B6C(a0, 1);
|
||||
t = D_801D46DC;
|
||||
*(u8 *)(a0 + 0xC2) = 2;
|
||||
*(s32 *)(a0 + 0x1C) = 0;
|
||||
*(s32 *)(a0 + 0x14) = -t;
|
||||
}
|
||||
}
|
||||
*(s32 *)(a0 + 0x1C) += 1;
|
||||
if (*(s32 *)(a0 + 0x1C) >= 0x28) {
|
||||
func_80131C78(a0);
|
||||
*(s16 *)(a0 + 0x2) = 2;
|
||||
*(s32 *)(a0 + 0x1C) = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(s32 *)(a0 + 0x10) = (*(s32 *)(a0 + 0x10) * 15) >> 4;
|
||||
*(s32 *)(a0 + 0x18) = (*(s32 *)(a0 + 0x18) * 15) >> 4;
|
||||
D_801D46D8 = ((s32 (*)(s32))func_8012CBCC)(a0);
|
||||
if (D_801D46D8 & 0x6000) {
|
||||
*(s32 *)(a0 + 0x14) = 0;
|
||||
if (D_801D46D8 & 0x1000) {
|
||||
*(s16 *)(a0 + 0x2) = 2;
|
||||
*(u8 *)(a0 + 0xC1) = 0;
|
||||
*(s16 *)(a0 + 0x5E) = 0;
|
||||
*(s32 *)(a0 + 0x1C) = 0x30;
|
||||
func_8002D4C8(0x7DF, 0);
|
||||
func_800291C8(0xA, *(s16 *)(a0 + 0xFE));
|
||||
return;
|
||||
}
|
||||
if (!(*(u16 *)(a0 + 0x84) & 1)) {
|
||||
*(u16 *)(a0 + 0x84) |= 1;
|
||||
func_8002D4C8(0x754, 0);
|
||||
}
|
||||
if ((*(s32 *)(a0 + 0x1C) & 3) == 3) {
|
||||
func_80143B6C(a0, 1);
|
||||
}
|
||||
*(s32 *)(a0 + 0x1C) += 1;
|
||||
if (*(s32 *)(a0 + 0x1C) >= 0x11) {
|
||||
func_80131C78(a0);
|
||||
func_8012B030((u8 *)a0);
|
||||
*(s16 *)(a0 + 0x2) = 1;
|
||||
*(u16 *)(a0 + 0x84) &= 0xFFFE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*(s16 *)(a0 + 0x108) = *(u16 *)(a0 + 0x108) - 1;
|
||||
if (*(s16 *)(a0 + 0x108) == 0) {
|
||||
func_800291C8(0xA, *(s16 *)(a0 + 0xFE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_801863CC", func_80188C8C);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user