mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-03 00:05:11 -04:00
feat(decomp): parallel gate — 2 fns across 2 binaries (10 workers)
md_SC07_004 func_801A3798 ov_SC07_007 func_8017DFB8
This commit is contained in:
@@ -1181,7 +1181,103 @@ void func_801A3744(s32 a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/md_SC07_004/nonmatchings/md_SC07_004", func_801A3798);
|
||||
#include "common.h"
|
||||
|
||||
extern void func_801A395C(s32 a0, s32 a1);
|
||||
extern void func_8013240C(s32 a0);
|
||||
extern void func_8001C924(s32 a0, void *a1);
|
||||
extern void func_8012A860(void *a0, int a1);
|
||||
extern void func_801A3A6C(u8 *s0);
|
||||
extern void func_8012B2CC(s32 a0);
|
||||
extern void func_801A7D18(s32 arg0);
|
||||
extern s32 func_801A8564(s32 a0);
|
||||
extern void func_80132288(s32 *a0, s32 *a1, s32 a2);
|
||||
extern void func_801292C8(u8 *a0);
|
||||
|
||||
extern s32 D_801B6E94[0x11];
|
||||
extern u8 D_801EF9A8;
|
||||
extern s32 D_801F8724;
|
||||
extern s32 D_801F8730;
|
||||
extern s32 D_801BC9EC;
|
||||
extern s32 *D_801AFB7C[];
|
||||
extern u16 D_8019FF8A;
|
||||
|
||||
/* Three zero-byte levers carry this body; all three are load-bearing (single-axis A/B'd):
|
||||
*
|
||||
* 1. `y = arg1 + zr` with `zr` pinned to $0 (§36 "$0-add opaque copy"). The target keeps
|
||||
* TWO callee-saved registers holding arg1 ($s2 = the parameter home, $s1 = a copy born
|
||||
* after the jal). A plain `y = arg1;` is head-promoted by cse.c make_regs_eqv and the
|
||||
* copy vanishes (LENGTH-DRIFT -1, and $s0/$s1 instead of $s0/$s1/$s2).
|
||||
* 2. The non-volatile re-tie `__asm__("" : "=r"(y) : "0"(y))` gives `y` a second RTL SET,
|
||||
* which kills the sched1 birthing boost on the copy and emits it BEFORE the call's
|
||||
* return-value copy — so dbr steals `addu $a0,$v0,$zero` for the bltz delay slot
|
||||
* instead of the arg1 copy (§47-addendum / §34 reg_n_sets==2).
|
||||
* 3. `goto ret0` instead of `return 0` after the func_80132288 tail. With an in-block
|
||||
* `return 0` the tail block's rare_destination flips and reorg refuses to steal
|
||||
* `addiu $v0,$zero,3` into the `bnez $v0` delay slot (an unfillable +1 nop). Routing
|
||||
* the exit through one shared `ret0:` tail restores the fill (§16 / §3-B shared-ret0).
|
||||
*
|
||||
* `t <<= 16; v1 = t >> 16;` (rather than `v1 = (s16)t;`) makes the sll reuse $v0 in place,
|
||||
* which is what stops dbr from sinking `sh $v0,0xE6($s0)` into the bltz delay slot.
|
||||
*/
|
||||
s32 func_801A3798(s32 s0, s32 arg1) {
|
||||
s32 v0;
|
||||
s32 v1;
|
||||
s32 y;
|
||||
s32 t;
|
||||
s32 p;
|
||||
u16 f9;
|
||||
register s32 zr __asm__("$0");
|
||||
|
||||
v0 = ((s32 (*)(s32, s32))func_801A395C)(s0, (s16)(*(u16 *)(s0 + 0x100) - 0x240));
|
||||
y = arg1 + zr;
|
||||
__asm__ ("" : "=r" (y) : "0" (y));
|
||||
v1 = *(s16 *)(s0 + 0xE6);
|
||||
if (v1 >= 0) {
|
||||
func_8013240C((s32)&D_801F8724);
|
||||
if (D_801F8730 & 0x4000) {
|
||||
t = *(u16 *)(s0 + 0xE6) - 1;
|
||||
*(u16 *)(s0 + 0xE6) = t;
|
||||
t <<= 16;
|
||||
v1 = t >> 16;
|
||||
if (v1 >= 0) {
|
||||
if (v1 >= 3) {
|
||||
if (v1 != 3) {
|
||||
goto other;
|
||||
}
|
||||
func_8001C924(*(s32 *)(s0 + 0x20), &D_801BC9EC);
|
||||
if (*(s32 *)(s0 + 0xD4) != 0) {
|
||||
func_801A7D18(*(s32 *)(s0 + 0xD4));
|
||||
*(s32 *)(s0 + 0xD4) = 0;
|
||||
}
|
||||
func_801A3A6C((u8 *)s0);
|
||||
*(u16 *)(s0 + 0x100) = 0;
|
||||
func_8012B2CC(s0);
|
||||
if ((arg1 << 16) != 0) {
|
||||
*(s32 *)(s0 + 0xD4) = func_801A8564(s0);
|
||||
}
|
||||
}
|
||||
func_80132288(&D_801F8724, D_801AFB7C[*(s16 *)(s0 + 0xE6)], D_801BC9EC);
|
||||
goto ret0;
|
||||
}
|
||||
other:
|
||||
func_8001C924(*(s32 *)(s0 + 0x20), D_801B6E94);
|
||||
func_8012A860((void *)s0, (int)&D_801EF9A8);
|
||||
if ((y << 16) != 0) {
|
||||
f9 = D_8019FF8A & 0xFFF7;
|
||||
p = *(s32 *)(s0 + 0xD4);
|
||||
D_8019FF8A = f9;
|
||||
if (p != 0) {
|
||||
func_801292C8((u8 *)p);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret0:
|
||||
return 0;
|
||||
}
|
||||
return (*(s16 *)(s0 + 0x98) == 0) && (v0 != 0);
|
||||
}
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
@@ -4430,7 +4430,112 @@ s32 func_8017DF74(s32 a0, s32 a1)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_007/nonmatchings/ov_SC07_007_jr_8017BEBC", func_8017DFB8);
|
||||
// @class: schedule
|
||||
// @stuck: none — MATCH (110 ins)
|
||||
//
|
||||
// func_8017DFB8 — per-frame entity tick: bail out through func_800D1724 when the
|
||||
// pad/state guard passes, otherwise dispatch through the D_801882B8 handler table and
|
||||
// rebuild the three 16-byte light records at D_800A5E88[0..2] from three rotated copies
|
||||
// of the D_80187C60 source vectors (func_800139C8 = "rotate SVECTOR by angle").
|
||||
//
|
||||
// Guard shape copied verbatim from the already-banked twin func_8017D3EC
|
||||
// (src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c:4092-4102) — same five tests, same
|
||||
// literals; ours differs only in setting D_801C79CC and RETURNING from the arm.
|
||||
//
|
||||
// FOUR LOAD-BEARING LEVERS (do NOT "clean these up" — each was byte-measured):
|
||||
//
|
||||
// (1) §249 asm-INITIALISATION of the record base. `__asm__("la %0, D_800A5E88" : "=r"(p))`
|
||||
// gives one pseudo whose single SET is ASM_OPERANDS, so it is never CONSTANT_P: no
|
||||
// REG_EQUIV, update_equiv_regs' absolute fold stays blocked, and the three first-field
|
||||
// stores keep the target's base-relative `sw $v0,0/0x10/0x20($s0)` form. A plain
|
||||
// `s32 *p = &D_800A5E88;` const-folds the +0x10/+0x20 stores back to
|
||||
// `lui $at; sw %lo(D_800A5E98)($at)` (+2 ins each) — measured, closeness 45.
|
||||
//
|
||||
// (2) §385 PRIORITY-DONOR inputs on that same asm. The `la` insn is dependence-free, so
|
||||
// sched1 hoists it to the top of the block (it landed before the `jalr`, closeness 66).
|
||||
// The dead `"r"(x0),"r"(y0),"r"(z0)` inputs release it only after the three `lh`s, and
|
||||
// the dead `"r"(ab)` input additionally releases it after the next call's $a1 setup —
|
||||
// which is what pulls `addu $a0,$s1,$zero` / `addiu $a1,$s2,0x8` ahead of the loads
|
||||
// (target idx 59-60). Dropping just `"r"(ab)` costs 8 instructions of rotation.
|
||||
//
|
||||
// (3) $a0/$a1 PINS (aa/ab) give the second func_800139C8 call's argument copies a source
|
||||
// statement — hence an early LUID and an addressable name for lever (2). The call's
|
||||
// own copies degenerate to self-moves and are deleted, so this is zero bytes.
|
||||
//
|
||||
// (4) §385 donor asm for the pointer bump. `p += 0x20; func_80028620(2, p);` is folded by
|
||||
// combine into a single `addiu $a1,$s0,0x20` (-1 ins); spelling the bump as a one-
|
||||
// instruction asm keeps `addiu $s0,$s0,0x20` + `addu $a1,$s0,$zero`, and its dead
|
||||
// `"r"(aa)` input orders it AFTER `addiu $a0,$zero,0x2` (target idx 99-100).
|
||||
// The trailing zero-byte use-barrier keeps p live so the bump cannot be dead-coded.
|
||||
#include "common.h"
|
||||
|
||||
extern s32 func_80029178(s32 arg);
|
||||
extern s32 func_8002AE60(void);
|
||||
extern s32 func_80014C54(s32 a0, s32 a1, s32 a2);
|
||||
extern s32 func_800CF8B4();
|
||||
extern void func_800D1724(s32 a0);
|
||||
extern s16 func_8012A758(void);
|
||||
extern void func_800139C8(s32 a0, void *a1, void *a2);
|
||||
extern void func_80028620(s32, void *);
|
||||
extern u8 D_80186964[];
|
||||
extern u8 D_80187C60[];
|
||||
extern void (*D_801882B8[])(void *);
|
||||
extern s32 D_801C79CC;
|
||||
extern s32 D_800A5E8C;
|
||||
extern s32 D_800A5E90;
|
||||
extern s32 D_800A5E9C;
|
||||
extern s32 D_800A5EA0;
|
||||
extern s32 D_800A5EAC;
|
||||
extern s32 D_800A5EB0;
|
||||
|
||||
void func_8017DFB8(void *a0) {
|
||||
register u8 *p __asm__("$16");
|
||||
register u8 *tbl __asm__("$18");
|
||||
register s32 aa __asm__("$4");
|
||||
register u8 *ab __asm__("$5");
|
||||
s32 idx;
|
||||
s16 v[3];
|
||||
s32 x0, y0, z0;
|
||||
s32 x1, y1, z1;
|
||||
s32 x2, y2, z2;
|
||||
|
||||
p = (u8 *)a0;
|
||||
if ((u8)func_80029178(0x123) != 0 && (s16)func_8002AE60() == 0 &&
|
||||
((s16)func_80014C54(0, 0, 0x800) != 0 || (s16)func_80014C54(0, 0, 0x40) != 0) &&
|
||||
func_800CF8B4() != 0) {
|
||||
D_801C79CC = 1;
|
||||
func_800D1724((s32)D_80186964);
|
||||
return;
|
||||
}
|
||||
D_801882B8[*(u16 *)(p + 2)](p);
|
||||
idx = func_8012A758();
|
||||
tbl = D_80187C60;
|
||||
func_800139C8(idx, tbl, v);
|
||||
aa = idx;
|
||||
ab = tbl + 8;
|
||||
x0 = v[0]; y0 = v[1]; z0 = v[2];
|
||||
__asm__("la %0, D_800A5E88" : "=r"(p) : "r"(x0), "r"(y0), "r"(z0), "r"(ab));
|
||||
*(s32 *)p = x0;
|
||||
D_800A5E8C = y0;
|
||||
D_800A5E90 = z0;
|
||||
func_800139C8(aa, ab, v);
|
||||
x1 = v[0]; y1 = v[1]; z1 = v[2];
|
||||
*(s32 *)(p + 0x10) = x1;
|
||||
D_800A5E9C = y1;
|
||||
D_800A5EA0 = z1;
|
||||
func_800139C8(idx, tbl + 0x10, v);
|
||||
x2 = v[0]; y2 = v[1]; z2 = v[2];
|
||||
*(s32 *)(p + 0x20) = x2;
|
||||
D_800A5EAC = y2;
|
||||
D_800A5EB0 = z2;
|
||||
func_80028620(0, p);
|
||||
func_80028620(1, p + 0x10);
|
||||
aa = 2;
|
||||
__asm__("addiu %0,%1,0x20" : "=r"(p) : "0"(p), "r"(aa));
|
||||
func_80028620(aa, p);
|
||||
__asm__("" : : "r"(p));
|
||||
}
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user