feat(decomp): parallel gate — 2 fns across 2 binaries (10 workers)

ov_SC02_011    func_80182714
  ov_SC04_011    func_80180B24
This commit is contained in:
Drew T
2026-09-02 02:10:07 -06:00
parent 2f46e3e0fc
commit 0fb99b763b
2 changed files with 263 additions and 2 deletions
+124 -1
View File
@@ -8162,7 +8162,130 @@ void func_801826D8(void *a0) {
}
INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_80182714);
/* func_80182714 (ov_SC02_011) — MATCH, 189 ins (match_one closeness 0).
*
* Levers (S71a, fable):
* §209 `mode` and `ang` are 16-BIT locals. The target's `addu $v1,$s3` before the
* mode `beq`s and `addu $v1,$s4` before the 0x800/0xB01/0x210 tests are the
* deferred sign-extension copies of s16 locals; `angle` has ONE set
* (`ratan2() & 0xFFF`), so combine proves the sign bit clear and each
* `sign_extend` collapses to a move. `ang = angle` itself is the HImode
* truncation copy ($s4 = $s0) that plain s32 copies coalesce away — no asm
* tie needed (the earlier draft's "=r"/"0" trick and fence are gone).
* §48-A global-alloc priority: with the copies in place ang and mode both have 5
* refs, and their post-sched1 live lengths tie within one insn (107 vs 108,
* ang first -> ang=$s3, mode=$s4, close=13). Writing `ang = angle;` BEFORE
* the `dist = func_80013294()` call lengthens ang to 109 (zero bytes: sched1
* still parks the copy in the bnez delay slot) so mode allocates first and
* takes $s3, ang/q share $s4, dist $s5 — byte-exact.
* §199-G/§222/§256 (carried from the s67o2 draft): mode dispatch is a `switch`;
* the redundant `ang >= 0x800` re-test reproduces `beqz $a0,.L80182930`.
*/
#include "common.h"
void func_80182714(s32 param_1) {
typedef struct { s16 x0, x1, x2, x3; } Blk8S16;
extern s32 D_801E9DA8;
extern s32 D_80126B58;
extern s16 D_80195058[];
extern s16 D_80126940;
extern s16 D_80126942;
extern s16 D_80126944;
extern u16 func_80148800(s32 *a0);
extern s32 ratan2(s32 dx, s32 dy);
extern s32 func_80013294(void *a0, void *a1);
extern void func_8018B5A8(s32 a0, void *a1, void *a2);
extern void func_80182B88(s32 a0, s32 a1, s32 a2, s32 a3);
u16 buf[8];
s16 *base;
u16 *p;
u16 *q;
s32 angle;
s16 ang;
s16 dist;
s16 mode;
*(Blk8S16 *)&buf[4] = *(Blk8S16 *)&D_801E9DA8;
q = &buf[4];
mode = 0;
if ((func_80148800(&D_80126B58) & 3) != 0) {
*(u8 *)(param_1 + 5) = (*(u8 *)(param_1 + 5) + 1) & 1;
}
*(s32 *)(param_1 + 0x14) = D_80195058[*(u8 *)(param_1 + 5)];
base = &D_80126940;
angle = ratan2(*base << 16, D_80126944 << 16) & 0xFFF;
*(Blk8S16 *)&buf[0] = *(Blk8S16 *)base;
p = &buf[0];
buf[5] = D_80126942;
ang = angle;
dist = func_80013294(p, q);
if (dist >= 0xA01) {
buf[0] = 0;
buf[1] = D_80126942;
buf[2] = 0xA00;
func_8018B5A8(angle, p, p);
buf[0] = (s32)(s16)buf[0] >> 3;
buf[1] = (s32)(s16)buf[1] >> 3;
buf[2] = (s32)(s16)buf[2] >> 3;
} else {
*(s16 *)(param_1 + 0x20) = 0x1C7;
*(s16 *)(param_1 + 0x22) = 0;
*(s16 *)(param_1 + 0x24) = 0;
*(s16 *)(param_1 + 0x2E) = 0;
*(s16 *)(param_1 + 0x30) = 0;
*(s16 *)(param_1 + 0x32) = 0;
}
if (ang >= 0x800) {
if (ang >= 0xB01) goto checks;
if (ang >= 0x800) goto set1c7;
}
if (ang >= 0x210) goto set1c7;
checks:
if (dist < 0x3C1) goto set1c7;
if (*(s16 *)&buf[1] < -0x2FF) goto set1c7;
if (ang < 0xD01) goto arm1;
if (dist < 0x500) {
*(s16 *)(param_1 + 0x20) = 0x31C;
mode = 2;
goto after;
}
mode = 2;
*(s16 *)(param_1 + 0x20) = 0x38E;
*(s32 *)(param_1 + 0x14) = 0x4B0;
goto after;
arm1:
mode = 1;
goto after;
set1c7:
*(s16 *)(param_1 + 0x20) = 0x1C7;
after:
if (dist < 0x200) {
*(s16 *)(param_1 + 0x20) = 0xE3;
*(s16 *)(param_1 + 0x22) = 0;
*(s16 *)(param_1 + 0x24) = 0;
*(s16 *)(param_1 + 0x2E) = 0;
*(s16 *)(param_1 + 0x30) = -0xC0;
*(s16 *)(param_1 + 0x32) = 0;
}
if (dist >= 0x981) {
*(s32 *)(param_1 + 0x14) = 0x384;
}
switch (mode) {
case 1:
*(s16 *)(param_1 + 0x20) = 0x2AA;
*(s32 *)(param_1 + 0x14) = 0x4B0;
break;
case 2:
*(s32 *)(param_1 + 0x14) = 0x4B0;
break;
}
if ((u32)(ang - 0xD01) < 0xFF && (u16)(dist - 0x481) < 0x29F) {
*(s16 *)(param_1 + 0x20) = 0x1C7;
}
func_80182B88(param_1, ang, (s32)&buf[0], (s32)&buf[0]);
}
void func_80182A08(void *a0) {
extern s32 ratan2(s32 dx, s32 dy);
+139 -1
View File
@@ -4880,7 +4880,145 @@ void func_80180AB4(struct Ent_80180AB4 *arg0) {
}
INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_80180B24);
/* func_80180B24 — S71a_1 fable. Body = .run/pool_1/opus (standalone MATCH 215/215);
* integration fix: D_80126B58 spelled through the TU's house __asm__ alias (the TU also
* declares it `u8 []` at block scope in func_80184978, so a file-scope `s32` decl conflicts). */
struct Ent_80180B24 {
/* 0x00 */ u8 pad00[0x34];
/* 0x34 */ u16 unk34;
/* 0x36 */ u8 pad36[0xBC];
/* 0xF2 */ u16 unkF2;
/* 0xF4 */ u16 unkF4;
};
extern u16 D_801EFD20;
extern u16 D_801EFD40;
extern s32 aB58_80180B24[1] __asm__("D_80126B58");
extern s32 aFC4C[] __asm__("D_801EFC4C");
extern u8 D_80194470[];
extern void func_80183880(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern void func_8012BEE8(u8 *a0);
extern void func_80183564(s32 a0, s16 *a1);
extern void func_801833D4(int a0, int a1);
extern s32 func_80183A28(u8 *a0);
extern void func_80180E80(u8 *self);
extern void func_80183BAC(u8 *a0);
extern void func_801837C4(s32, s32);
void func_80180B24(s32 s0)
{
/* BLOCK scope on purpose (house style, TU l.5019/5156): the TU defines
* `void func_80183BD0(s32 a0)` at ~l.7238 and its earlier block-scope `(u8 *a0)` externs
* sit in limbo; a FILE-scope decl here would let gcc-2.7.2's pushdecl merge that
* prototype into the global (different_binding_level) and the definition then errors
* `conflicting types for func_80183BD0` -- measured on a spliced-TU cc1 run. */
extern void func_80183BD0(u8 *a0);
struct Ent_80180B24 *p;
s32 a;
s32 ta;
s32 tb;
s32 tc;
s32 s1;
s32 s3;
s16 x;
s16 y;
s16 buf[3];
p = (struct Ent_80180B24 *)s0;
s3 = (s32)&aB58_80180B24[0];
if (*(u16 *)(s0 + 0x34) == 4) {
s1 = aFC4C[D_801EFD20];
x = *(u16 *)(*(s32 *)(s1 + 0x20) + 0x12) & 0xFFF;
if (x >= 0x800) {
x |= 0xF000;
}
func_80183880((s32)s0);
y = *(u16 *)(*(s32 *)(s1 + 0x20) + 0x12) & 0xFFF;
if (y >= 0x800) {
y |= 0xF000;
}
if ((x < -0x200 && -0x201 < y) || (-0x200 < x && y < -0x1FF)) {
func_8002D4C8(0x9C3, 0);
}
if (((s32 (*)(u8 *))func_8012BEE8)((u8 *)s0) != 0) {
buf[0] = *(u16 *)(s3 + 6);
buf[1] = *(u16 *)(s3 + 0xA) - 0x50;
buf[2] = *(u16 *)(s3 + 0xE);
func_80183BD0((u8 *)s0);
func_80183564((s32)s0, buf);
*(u16 *)(s0 + 0xE0) = 0x10;
*(u16 *)(s0 + 0x34) = 0;
}
return;
}
if (((s32 (*)(int, int))func_801833D4)((int)s0, 0) != 0) {
switch (*(u16 *)(s0 + 0x34)) {
case 0:
/* §49-variant/§30#3: zero-byte re-ties set reg_n_sets=2, killing sched1's
* birthing_insn_p LAUNCH_PRIORITY boost that glued each add to its store;
* yields the target's load*3 / add*3 / store*3 order. */
ta = *(u16 *)(s0 + 0xF4) + 1;
tb = *(u16 *)(s0 + 0xF2) + 1;
__asm__("" : "=r"(ta) : "0"(ta));
__asm__("" : "=r"(tb) : "0"(tb));
*(u16 *)(s0 + 0xF4) = ta;
*(u16 *)(s0 + 0xF2) = tb;
*(u16 *)(s0 + 0x34) = *(u16 *)(s0 + 0x34) + 1;
func_8002D4C8(0x992, 0);
break;
case 1:
/* struct-member spelling (MEM_IN_STRUCT_P) on the s0 fields defeats the false
* alias against the D_801EFD40 store. */
D_801EFD40 = D_801EFD40 & 0xFFFE;
a = p->unkF4 + 1;
p->unkF4 = a + (p->unkF2 & 1);
tc = p->unk34 + 1;
__asm__("" : "=r"(tc) : "0"(tc));
p->unk34 = tc;
break;
case 2:
if (*(s16 *)(s0 + 0x76) == 0) {
func_80180E80((u8 *)s0);
return;
}
*(u16 *)(s0 + 0xF4) = 0;
func_80183BAC((u8 *)s0);
*(u16 *)(s0 + 0x34) = 3;
break;
case 3:
((void (*)(s32))func_801837C4)(s0);
func_80183BAC((u8 *)s0);
*(s32 *)(s0 + 0x1C) = 0x80;
*(u16 *)(s0 + 0x100) = 0;
*(u16 *)(s0 + 0x34) = 4;
return;
}
func_80183564((s32)s0, (s16 *)(D_80194470 + (*(s16 *)(s0 + 0xF4) * 8)));
*(u16 *)(s0 + 0xE0) = 0x10;
} else {
/* store 0xE0 in BOTH arms: cross_jump merges the sh at the join, and the s16 local
* yields the un-coalesced addu $v1,$v0,$zero that stops reorg stealing the decrement. */
s16 v0 = *(s16 *)(s0 + 0xE0);
if (v0 != 0) {
*(s16 *)(s0 + 0xE0) = v0 - 1;
} else {
func_80183A28((u8 *)s0);
*(s16 *)(s0 + 0xE0) = 0x10;
}
if (*(u16 *)(s0 + 0x34) == 0) {
u16 flag = D_801EFD40;
if (!(flag & 1)) {
s1 = aFC4C[D_801EFD20];
if ((u16)(((*(u16 *)(s0 + 0x106) & 0xFFF) -
(*(u16 *)(*(s32 *)(s1 + 0x20) + 0x12) & 0xFFF)) - 0x180) >= 0xD01) {
D_801EFD40 = flag | 1;
func_8002D4C8(0x7E3, 0);
}
}
}
}
}
extern void func_80183564(s32 a0, s16 *a1);
extern s32 func_80186710(void);