mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-30 23:37:39 -04:00
feat(decomp): worker gate — +1 fns x0 propagated (fleet 95.2%)
This commit is contained in:
@@ -4010,7 +4010,83 @@ void func_8017D6F8(s32 a0)
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_8017D748);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_8017D7CC);
|
||||
#include "common.h"
|
||||
|
||||
/* func_8017D7CC @ ov_SC06_010 (subseg ov_SC06_010_jr_8017A4AC) — 87 ins.
|
||||
*
|
||||
* SEED: func_801822E0 @ ov_SC02_016 (src/ov_SC02_016/ov_SC02_016_jr_8017DC70.c), 91.9% skeleton-similar,
|
||||
* already byte-matched. This is the near-identical sibling.
|
||||
*
|
||||
* Diff vs seed (byte-verified via objdump of the seed's matched .o):
|
||||
* - Seed uses an explicit `s32 i = 0; do { iVar1 = func_801824AC(); if (iVar1 >= 0) {...} i++; } while (i < 3);`
|
||||
* — a genuine do-while (no pre-loop guard), with the call's return value (iVar1) kept ONLY in $v1 (never
|
||||
* saved across calls) and a SEPARATE loop counter `i` in $s3.
|
||||
* - This target has NO separate counter: the loop variable IS the call's return value itself, tested both
|
||||
* for the if-guard (>=0) and for loop continuation (<3). Because that variable is reassigned only INSIDE
|
||||
* the loop body, the while-loop rotation ("if (cond) { preheader; do {...} while(cond); }") needs a
|
||||
* pre-loop guard test — but since the variable has no source-level initializer before the loop, the guard
|
||||
* reads whatever is in its (freshly register-allocated, never-yet-written) register: `slti $v0,$s2,3` /
|
||||
* `beqz $v0,<post-loop>` right after the buf[1]-=0x40 store, with NO assignment to $s2 anywhere before it.
|
||||
* Reproduced here as a genuinely uninitialized local tested by a `while` loop (matches gcc-2.7.2's
|
||||
* loop-rotation idiom exactly — the guard is emitted even though the variable's "value" is indeterminate).
|
||||
* - The `func_80146A6C(...)` calls' 7th argument is `1` here (not `0` as in the seed) — this constant is
|
||||
* loop-invariant and reused at BOTH call sites, so gcc hoists it once into a callee-saved register ($s4)
|
||||
* before the loop rather than re-materializing `li $a,1` at each site (the seed's constant is `0`, which
|
||||
* is free via $zero, so the seed needed no such register — hence the seed has one fewer saved S-register).
|
||||
* - The post-loop `if (cnt == 0) { ... }` here has NO else-branch (the seed's else called
|
||||
* `func_80172630((u8*)param_1)`); the asm falls straight from the 3-call if-body into the epilogue.
|
||||
* - Register roles differ naturally from the seed given the above (actor pointer ends up in $s3 here, not
|
||||
* $s2 — $s2 is claimed by the loop-return-value variable instead).
|
||||
*
|
||||
* Callee/global renames from the seed (per this TU's own asm ground truth):
|
||||
* func_801824AC -> func_8017D9A0 (still s32, no args)
|
||||
* func_80182434 -> func_8017D928 (still void, s32 a0)
|
||||
* func_80172630 -> (unused; no else-branch in this target)
|
||||
*/
|
||||
|
||||
extern void func_80015978(s32 a0, s32 *a1);
|
||||
extern s32 func_8017D9A0(void);
|
||||
extern s32 func_80146A6C(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5, s32 a6);
|
||||
extern int rand(void);
|
||||
extern void func_8017D928(s32 a0);
|
||||
extern void func_80159B3C(void *a0);
|
||||
extern void func_80165718(s32 a0);
|
||||
|
||||
void func_8017D7CC(s32 param_1)
|
||||
{
|
||||
s16 buf[4];
|
||||
s32 v2;
|
||||
s32 uVar3;
|
||||
s32 uVar4;
|
||||
s32 uVar5;
|
||||
s16 rnd;
|
||||
u8 cnt;
|
||||
|
||||
func_80015978(param_1 + 4, (s32 *)buf);
|
||||
buf[1] -= 0x40;
|
||||
|
||||
while (v2 < 3) {
|
||||
v2 = func_8017D9A0();
|
||||
if (v2 >= 0) {
|
||||
func_80146A6C(0x51, (void *)param_1, buf[0], buf[1], buf[2], v2, 1);
|
||||
|
||||
uVar3 = rand();
|
||||
uVar4 = rand();
|
||||
uVar5 = rand();
|
||||
rnd = (uVar3 & 3) * 0x400 + (uVar4 & 3) * 0xfa + (uVar5 & 3) * 0x44;
|
||||
func_80146A6C(0x52, (void *)param_1, 0, -0x20, 0x10, rnd, 1);
|
||||
}
|
||||
}
|
||||
|
||||
cnt = *(u8 *)(param_1 + 0xde);
|
||||
*(u8 *)(param_1 + 0xde) = cnt + 0xff;
|
||||
if (cnt == 0) {
|
||||
func_8017D928(param_1);
|
||||
func_80159B3C((void *)param_1);
|
||||
func_80165718(param_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern void func_80147324(s32 a0);
|
||||
extern void func_80147364(u16, s32);
|
||||
|
||||
Reference in New Issue
Block a user