diff --git a/src/ov_SC07_006/ov_SC07_006.c b/src/ov_SC07_006/ov_SC07_006.c index 1574d4382..c30a1a5f8 100644 --- a/src/ov_SC07_006/ov_SC07_006.c +++ b/src/ov_SC07_006/ov_SC07_006.c @@ -922,7 +922,58 @@ DEFINE_func_8012B70C() /* dedup: shared engine-core @0x8012b70c (src/shared) */ DEFINE_func_8012B744() /* dedup: shared engine-core @0x8012b744 (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006", func_8012B77C); +// @class: struct +// @stuck: none — MATCH (58 ins) +#include "common.h" + +extern s32 ratan2(s32 a0, s32 a1); +extern s32 func_80047948(s32 a0); /* rsin-like: angle (0..0xFFF) -> 1.12 fixed */ +extern s32 func_8004787C(s32 a0); /* rcos-like: angle (0..0xFFF) -> 1.12 fixed */ + +/* The 4-byte destination is a PACKED PAIR of angles held entirely in ONE saved register + * ($s4) across all three calls — that is what produces the target's + * andi $s4,$s4,0xFFFF (read of the still-uninitialized local, hoisted into the prologue) + * ... or $s4,$s4,ang<<16 -> t.hi = yaw + * ... and $s4,$s4,0xFFFF0000 / or $s4,$s4,ang&0xFFFF -> t.lo = pitch + * A `struct { s16 lo, hi; }` has align 2 -> BLKmode-ish handling: gcc spills it to the stack + * and stores it with lwl/lwr + swl/swr (54 ins, 53 mismatched). Two 16-bit BITFIELDS in a + * u32 container give the SImode, align-4 struct gcc keeps in a register. */ +typedef struct { + u32 lo : 16; + u32 hi : 16; +} Ang2_8012B77C; + +/* a0 = destination packed-angle word, a1 = "from" entity, a2 = "to" entity. + * Both entities carry 16.16 fixed-point x/y/z at +0/+4/+8; the s16 reads at +2/+6/+0xA are + * the integer halves. Returns the destination pointer — the return value is REAL: without it + * gcc stores with `sw $s4,0($s3)` (57 ins) instead of the target's + * addu $v0,$s3,$zero ; sw $s4,0($v0) (the return-value copy that the store's base coalesces onto). + * The flattened `dz` reuse at the end is also load-bearing: making the (dz*sin + dx*cos)>>12 + * temp its OWN variable gives it $a1 for the whole chain; reusing `dz` extends that allocno so + * it lands in $s5 exactly as the target does (`sra $s5,$v0,12` / `negu $a1,$s5`), and it also + * demotes dz's priority so the saved-reg order comes out $s3=out, $s4=t, $s5=dz. */ +s32 func_8012B77C(s32 out, s32 from, s32 to) { + Ang2_8012B77C t; + s32 dx, dy, dz; + s32 ang; + s32 r1, r2; + + dz = *(s16 *)(to + 0xA) - *(s16 *)(from + 0xA); + dx = *(s16 *)(to + 0x2) - *(s16 *)(from + 0x2); + dy = *(s16 *)(to + 0x6) - *(s16 *)(from + 0x6); + + ang = (ratan2(-dz, dx) - 0x400) & 0xFFF; + t.hi = ang; + + r1 = func_80047948(ang); + r2 = func_8004787C(ang); + dz = (dz * r1 + dx * r2) >> 12; + t.lo = ratan2(dy, -dz); + + *(Ang2_8012B77C *)out = t; + return out; +} + DEFINE_func_8012B864() /* dedup: shared engine-core @0x8012b864 (src/shared) */ diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80131340.c b/src/ov_SC07_006/ov_SC07_006_jr_80131340.c index 648945c86..33ffb9102 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80131340.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80131340.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80135888.c b/src/ov_SC07_006/ov_SC07_006_jr_80135888.c index a92446efe..2e70e3e5d 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80135888.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80135888.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80135A4C.c b/src/ov_SC07_006/ov_SC07_006_jr_80135A4C.c index edc4d4dc3..07fb5bcd3 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80135A4C.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80135A4C.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80135D20.c b/src/ov_SC07_006/ov_SC07_006_jr_80135D20.c index 8037fc62a..708b4e4de 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80135D20.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80135D20.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); @@ -1006,7 +1006,80 @@ void func_80136EC4(void) { DEFINE_func_80136ECC() /* dedup: shared engine-core @0x80136ecc (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_80135D20", func_80136F3C); +// @class: regalloc-order +// @stuck: none — MATCH (match_one 61/61, relocation-masked) +// +// 2-line "X cross" GsSortLine family (same shape as byte-proven DEFINE_func_80137030 / +// DEFINE_func_80137178, RED variant): +// line1 = (a0-3, a1-3) -> (a0+3, a1+3); line2 = (a0+3, a1-3) -> (a0-3, a1+3); +// color r=0xFF g=0 b=0. All four endpoints are loop-invariant across the two calls, so all +// six live values (x0,y0,x1,y1,white,base) are homed in $s0-$s5 for the whole body. +// +// Levers that make gcc-2.7.2 -O2 emit the target's exact regalloc + schedule: +// * ROLE COALESCING (the 28 -> 13 step): the target coalesces x0 into a0's incoming copy +// ($s1: `addu $s1,$a0,$zero` ... `addiu $s1,$s1,-0x3`) and y1 into a1's copy ($s2), while +// x1 lands in a FRESH $s0. gcc coalesces whichever derived value is computed LAST off the +// param, so the source must emit y0, x1, y1, x0 in that order — writing x0 first (the +// "natural" order) coalesces x1 instead and costs 28 instructions. +// * `__asm__("" : "=r"(x1) : "0"(x1))` right after `x1 = a0 + 3;` nails x1's compute point +// between x1 and y1, which is what keeps x1 from being the last a0-user (13 -> 7). +// * PINS: x1 -> $s0 ($16), x0 -> $s1 ($17), base(&D_800A6518) -> $s3 ($19), white(0xFF) -> +// $s4 ($20). Without the x1 pin the whole $s bank rotates by one; without the x0 pin the +// a0-copy fights x1 for $s0. y0/y1 must stay UNPINNED — pinning y1 to $s2 kills the +// `addu $s2,$a1,$zero` param copy entirely (a1 stays in $a1, -1 insn, 58 mismatched). +// * NO anchor on `white`: an `__asm__` on white front-loads its `li $s4,255` ahead of the +// call's $a0/$a2 argument setup (the last 4-mismatch schedule residual). Leaving white +// un-anchored lets the scheduler emit `addiu $a0,$sp,0x10` / `addu $a2,$zero,$zero` first, +// exactly as the target does. +extern short D_800B9A02; +extern u8 D_800A6518[]; +extern void GsSortLine(void *a0, void *a1, s32 a2); + +void func_80136F3C(s32 a0, s32 a1) +{ + struct { + u32 tag; + s16 x0; + s16 y0; + s16 x1; + s16 y1; + u8 r; + u8 g; + u8 b; + } line; + register s16 x1 __asm__("$16"); /* $s0 */ + register s16 x0 __asm__("$17"); /* $s1 */ + register u8 *base __asm__("$19") = D_800A6518; /* $s3 */ + register s16 white __asm__("$20"); /* $s4 */ + s16 y0; + s16 y1; + + y0 = a1 - 3; + x1 = a0 + 3; + __asm__("" : "=r"(x1) : "0"(x1)); + y1 = a1 + 3; + white = 0xFF; + x0 = a0 - 3; + line.tag = 0; + line.r = white; + line.g = 0; + line.b = 0; + line.x0 = x0; + line.y0 = y0; + line.x1 = x1; + line.y1 = y1; + GsSortLine(&line, &base[(u16)D_800B9A02 * 20], 0); + line.tag = 0; + line.r = white; + line.g = 0; + line.b = 0; + line.x0 = x1; + line.y0 = y0; + line.x1 = x0; + line.y1 = y1; + GsSortLine(&line, &base[(u16)D_800B9A02 * 20], 0); +} + DEFINE_func_80137030() /* dedup: shared engine-core @0x80137030 (src/shared) */ diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8013F350.c b/src/ov_SC07_006/ov_SC07_006_jr_8013F350.c index f25e0c68c..dd3af0a10 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8013F350.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8013F350.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80140608.c b/src/ov_SC07_006/ov_SC07_006_jr_80140608.c index b57b1598a..06bf90dc6 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80140608.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80140608.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); @@ -2372,7 +2372,100 @@ void func_80146360(void) } -INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_80140608", func_801463A0); +// @class: struct +// @stuck: none — MATCH (101 ins); also byte-verified spliced into the real ov_SC07_006 TU +/* func_801463A0 — ov_SC07_006 / ov_SC07_006_jr_80140608 (cross-overlay family reach 138). + * + * Byte-verified twice: `match_one` in isolation AND spliced into a scratch copy of + * src/ov_SC07_006/ov_SC07_006_jr_80140608.c compiled whole (§42a: iso-MATCH != TU bank). + * + * Keys: + * - D_80126B78 is `s32 *`, read ONCE before the five calls -> it lives in $s0 across them; + * &D_80126B58 is CSE'd into $s1 for all eight `addu $a0,$s1,$zero` call arguments. + * - The 8-byte BE0->BE8 copy is a STRUCT ASSIGN of an align-1 blob (cookbook §48-C2) -> + * emit_block_move force_regs both bases (`la $a1` / `la $a0`) + lwl/lwr + swl/swr. + * NOT `memcpy(...)`: the real TU declares `extern void *memcpy(...)`, which disables the + * builtin TU-wide and would lower this copy to a `jal memcpy` CALL (§42a T1 drift class). + * - NEW IDIOM (this was the whole residual, -1 instruction): the halfword store at the SAME + * address as the block-copy SOURCE must not be spelled with the same C declaration. If it is, + * cse substitutes the block move's already-loaded base register for the store's constant + * address (`sh $v1,0($a3)` instead of `lui $at,%hi; sh %lo($at)`) — one instruction short, and + * the extended live range of that base also pushes the block move off $a1/$a0 onto $a3/$a1. + * Splitting the two views into two DECLS (here: the TU's `u8 D_80126BE0[]` for the copy, an + * `__asm__("D_80126BE0")`-labelled `u16` for the store) gives cse two non-identical SYMBOL_REFs + * (rtx_equal_p compares XSTR pointers), so the direct `lui %hi / sh %lo($at)` macro survives. + * The emitted relocation is still against D_80126BE0 — no new undefined symbol. + * - The three halfword stores must precede the D_80126B9C read-modify-write so its `sw` schedules last. + * - Callee decls mirror the real TU's environment (the engine_core DEFINE_func_* signatures and + * `u8 D_80126BE0[]` from DEFINE_func_80146128) so the def splices in with no conflicting types. + */ +#include "common.h" + +typedef struct { char _b[8]; } Blk8_801463A0; /* size 8, align 1 -> unaligned block move */ + +extern void func_8014C6F4(u8*); +extern void func_80155150(s32 a0); +extern void func_801470C0(s32 a0); +extern void func_80147478(s32 a0); +extern void func_80147118(s32 a0); +extern void func_8014BDE8(s32 a0); +extern short func_801508F8(s32 a0); +extern void func_8014B5B0(s32 *a0); +extern void func_80161D88(s32 a0); + +extern s32 D_80126B58; +extern s32 *D_80126B78; +extern u16 D_80126B5E; +extern u16 D_80126B62; +extern u16 D_80126B66; +extern u16 D_80126C90; +extern u16 D_80126C92; +extern u16 D_80126C94; +extern s32 D_80126B9C; +extern s32 D_80126BA0; +extern u8 D_80126BE0[]; /* identical to the decl DEFINE_func_80146128() already emits in this TU */ +extern u8 D_80126BE8[]; +extern u16 D_80126BE0_hw __asm__("D_80126BE0"); /* halfword view of BE0 — see NEW IDIOM above */ +extern u16 D_80126BE2; +extern u16 D_80126BE4; +extern s16 D_80126C9E; + +void func_801463A0(void) +{ + s32 obj; + short v; + + obj = (s32)D_80126B78; + func_8014C6F4((s32)&D_80126B58); + func_80155150((s32)&D_80126B58); + func_801470C0((s32)&D_80126B58); + func_80147478((s32)&D_80126B58); + func_80147118((s32)&D_80126B58); + if (obj != 0) { + v = D_80126B5E + D_80126C90; + *(short *)(obj + 8) = v; + *(s32 *)(obj + 0x48) = (s32)v; + v = D_80126B62 + D_80126C92; + *(short *)(obj + 0xA) = v; + *(s32 *)(obj + 0x4C) = (s32)v; + v = D_80126B66 + D_80126C94; + *(short *)(obj + 0xC) = v; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x11; + *(s32 *)(obj + 0x50) = (s32)v; + } + func_8014BDE8((s32)&D_80126B58); + *(Blk8_801463A0 *)&D_80126BE8 = *(Blk8_801463A0 *)&D_80126BE0; + D_80126BE0_hw = D_80126B5E; + D_80126BE2 = D_80126B62; + D_80126BE4 = D_80126B66; + D_80126BA0 = D_80126B9C; + D_80126B9C = D_80126B9C & 0x3FFFFFFF; + func_801508F8((s32)&D_80126B58); + D_80126C9E = 0; + func_8014B5B0(&D_80126B58); + func_80161D88((s32)&D_80126B58); +} + DEFINE_func_80146534() /* dedup: shared engine-core @0x80146534 (src/shared) */ @@ -3472,7 +3565,87 @@ DEFINE_func_8014C6D0() /* dedup: shared engine-core @0x8014c6d0 (src/shared) */ DEFINE_func_8014C6E0() /* dedup: shared engine-core @0x8014c6e0 (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_80140608", func_8014C6F4); +// @class: schedule +// @stuck: none — MATCH (match_one 91/91) +// +// Levers used (all byte-gated on ov_SC07_006): +// 1. §struct 8-byte alignment-1 struct copy `*(M8_8014C6F4*)(a+0x164) = *(M8_8014C6F4*)(p+0x10)` +// -> the lwl/lwr,lwl/lwr,swl/swr,swl/swr block (engine_types.h M8_xxx convention). +// 2. §17 base-pointer cache: `u8 *p = D_80078E78;` (NOT a direct D_80078E78[0x49]) so gcc pins +// the base into callee-saved $s1 and hoists the la into the prologue (live across the jal). +// 3. §17 register pins: the search result `e` MUST be $v0 and the limit `lim` $v1, else +// local-alloc swaps the loop IV/limit pair ($v1<->$a0) and coalesces `e` into the IV. +// 4. DELAY-SLOT lever (new): writing the compare constant as its own pre-loop statement +// (`want = 0x22;`) instead of the literal `0x22` inside the loop test. With the literal, +// loop.c hoists the `li $a1,0x22` into the loop PREHEADER (after the duplicated entry test), +// so reorg.c's guard branch has nothing local to take and instead COPIES the branch-target +// insn (`addu $v0,$zero,$zero`) into its delay slot and redirects past it — a +1 shift that +// also lets the loop-back branch steal the same insn (nop -> move). Materialising the +// constant in the block BEFORE the entry test makes fill_simple_delay_slots take it from +// the preceding insns, reproducing `beqz $v0,.L8014C7F4 / addiu $a1,$zero,0x22` and leaving +// the loop-back delay slot a nop. `want` needs no pin — gcc lands it in $a1 on its own. + +typedef struct { char _b[8]; } M8_8014C6F4; + +void func_8014C6F4(u8 *a) { + extern u8 D_80078E78[]; + extern s32 D_8011F9D0; + extern s32 func_8016F1AC(void); + extern void func_80015978(s32 a0, s32 *a1); + + u8 *p = D_80078E78; + register u8 *e __asm__("$2"); + register u8 *lim __asm__("$3"); + u8 *q; + s32 want; + u8 *src; + + if ((*(u32 *)(a + 0x44) & 2) != 0) { + a[0x1C3] = 1; + } + if (((*(u32 *)(a + 0x44) ^ *(u32 *)(a + 0x48)) & *(u32 *)(a + 0x44) & 0x200) != 0) { + a[0x1C3] = 0; + } + *(M8_8014C6F4 *)(a + 0x164) = *(M8_8014C6F4 *)(*(u8 **)(a + 0x20) + 0x10); + if (func_8016F1AC() != 0 + || (((*(u32 *)(a + 0x44) & 0x200) != 0) && a[0x1C3] == 0)) { + *(s16 *)(a + 0x162) = 1; + goto tail; + } + if (p[0x49] == 0x17) { + want = 0x22; + q = (u8 *)&D_8011F9D0; + lim = q + 0xC30; + for (; q < lim; q += 0x68) { + if (*(u16 *)q == want) { + e = q; + goto found; + } + } + e = 0; + found: + if (e != 0) { + src = e + 4; + goto call; + } + } + if (*(u16 *)a == 0x19) { + goto done; + } + src = a + 4; +call: + func_80015978((s32)src, (s32 *)(a + 0x15C)); +done: + *(s16 *)(a + 0x162) = 0; +tail: + if (*(s16 *)(a + 0x15A) == 0) { + *(u16 *)(a + 0x154) = *(u16 *)(a + 0x6); + *(u16 *)(a + 0x156) = *(u16 *)(a + 0xA); + *(u16 *)(a + 0x158) = *(u16 *)(a + 0xE); + } + *(s16 *)(a + 0x15A) = 0; +} + DEFINE_func_8014C860() /* dedup: shared engine-core @0x8014c860 (src/shared) */ diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80154C24.c b/src/ov_SC07_006/ov_SC07_006_jr_80154C24.c index b0be3d3b4..1fa8c68d3 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80154C24.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80154C24.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); @@ -2137,7 +2137,74 @@ INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_80154C24", func_8015660 DEFINE_func_80156648() /* dedup: shared engine-core @0x80156648 (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_80154C24", func_80156670); +// @class: regalloc-order +// @stuck: none — MATCH (83 ins) +// +// Body notes (what makes the codegen land): +// * param_2/param_3 MUST be s32 (not u16) — u16 params flip the $s5/$s6 tie-break and reorder +// the prologue; the explicit `& 0xFFFF` at the call site is what yields the two `andi`s. +// * D_80126AF0 as `S8[]` (8-byte stride) folds the guard load into +// `lui %hi(D_80126AF6)` + `addu $at,$at,$s0` + `lh %lo(D_80126AF6)($at)` (§18 %lo-fold). +// * do-while + `D_801151E0[i]` lets gcc derive all three IVs itself +// ($s2 = &D_801151E0[i], $s0 = i*8, $s1 = i) and strength-reduce $s2 to an `addiu 4`. +// +// TU-plumbing notes (this is the revision that should BANK; the older +// .run/drafts-sc07006-fresh-* copies match_one-MATCHed but were struct-walled, §23 case 3): +// * `S8` / `B8` are ALREADY defined in src/shared/engine_types.h (Phase-22 type-lift), which +// engine_core.h includes — a local `typedef ... S8;` is a hard C89 redefinition error in the +// TU. They are therefore emitted only under `#ifndef BFM_ENGINE_TYPES_H` so the draft still +// compiles standalone under match_one and is a no-op once spliced into the TU. +// * The TU's DEFINE_func_801567BC / _80156848 / _80156A88 / _80156B74 expansions already declare +// D_801151E0/D_801150E0/D_8011DAD8/D_80128120/D_80128138/D_80126AF0/D_80126730 with exactly +// these types, and D_801270A8 as scalar `S8` (not `u8[]`) — declared canonically here so no +// "type mismatch with previous external decl" fires. `(s32)&D_801270A8` is byte-identical to +// the old `(s32)D_801270A8` on a `u8[]` (both are just the symbol address). + +#ifndef BFM_ENGINE_TYPES_H + + +#endif + +extern void func_80156B74(s32 param_1, u32 param_2, u8 *param_3); +extern void func_80157158(s32 a0, u16 a1, u16 a2, s32 a3, s32 a4, s32 a5, + s32 a6, s32 a7, s32 a8, s32 a9, u16 a10, s32 a11, s32 a12); +extern s32 D_801151E0[]; +extern s32 D_801150E0[]; +extern u8 D_8011DAD8[]; +extern B8 D_80128120[]; +extern B8 D_80128138[]; +extern S8 D_80126AF0[]; +extern u8 D_80126730[]; +extern u8 D_8011520C[]; +extern S8 D_801270A8; + +void func_80156670(s32 param_1, s32 param_2, s32 param_3, s32 param_4, s32 param_5, u16 param_6) +{ + u32 i; + + func_80156B74(param_1, param_4, (u8 *)(param_1 + 0x1A9)); + i = 0; + do { + D_801151E0[i] = 0; + if (D_80126AF0[i].d == 0) { + D_801151E0[i] = ((s32 (*)(s32, u16, u16, s32, s32, s32, s32, s32, s32, + s32, u16, s32, s32))func_80157158)( + param_1, param_2 & 0xFFFF, param_3 & 0xFFFF, + (s32)&D_801270A8, + (s32)&D_80126AF0[i], + (s32)&D_80128120[i], + (s32)&D_80128138[i], + (s32)&D_801150E0[i], + (s32)&D_8011DAD8[i * 8], + param_5, + param_6, + (s32)&D_8011520C[i], + (s32)&D_80126730[i]); + } + i = i + 1; + } while (i < 3); +} + DEFINE_func_801567BC() /* dedup: shared engine-core @0x801567bc (src/shared) */ diff --git a/src/ov_SC07_006/ov_SC07_006_jr_801588CC.c b/src/ov_SC07_006/ov_SC07_006_jr_801588CC.c index f242d7b29..3bb68759e 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_801588CC.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_801588CC.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c index fe49bd90b..480e232b3 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c @@ -137,7 +137,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); @@ -8491,7 +8491,55 @@ s32 func_8017496C(void *a0) { DEFINE_func_801749A8() /* dedup: shared engine-core @0x801749a8 (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8015C32C", func_801749C8); +// @class: regalloc-order +// @stuck: none — MATCH (pins $s2=D_80126B5E, $s1=D_80126B66 + Buf_c1 struct local; ported from the banked ov_SC01_000 exemplar) + + + +extern u16 D_80126B5E; +extern u16 D_80126B62; +extern u16 D_80126B66; + +extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2); +extern s32 func_80012ABC(s32, s32, s32); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012F14C(s32 a0, s32 a1, s32 a2); + + +s32 func_801749C8(s32 param_1) +{ + Buf_c1 buf; + register s32 iVar5 __asm__("$18"); + register u32 iVar4 __asm__("$17"); + + *(s32 *)(param_1 + 8) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 8), (s32)*(s16 *)(param_1 + 0xc), 4); + *(s32 *)(param_1 + 0x10) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), 4); + *(s16 *)(param_1 + 0x18) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x18), (s32)*(s16 *)(param_1 + 0x20), 4); + *(s16 *)(param_1 + 0x1a) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x1a), (s32)*(s16 *)(param_1 + 0x22), 4); + *(s16 *)(param_1 + 0x1c) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x1c), (s32)*(s16 *)(param_1 + 0x24), 4); + *(s16 *)(param_1 + 0x28) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x28), (s32)*(s16 *)(param_1 + 0x2e), 0x10); + *(s16 *)(param_1 + 0x2a) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x2a), (s32)*(s16 *)(param_1 + 0x30), 0x10); + *(s16 *)(param_1 + 0x2c) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x2c), (s32)*(s16 *)(param_1 + 0x32), 0x10); + + iVar4 = (u16)D_80126B66; + *(s32 *)(param_1 + 0x48) = *(s16 *)(param_1 + 0x28) + (iVar5 = (s16)D_80126B5E); + *(s32 *)(param_1 + 0x4c) = *(s16 *)(param_1 + 0x2a) + (s16)D_80126B62; + *(s32 *)(param_1 + 0x50) = *(s16 *)(param_1 + 0x2c) + (s16)iVar4; + func_80049CAC(param_1 + 0x18, (s32)&buf); + + buf.f14 = *(s16 *)(param_1 + 0x28) + iVar5; + buf.f18 = *(s16 *)(param_1 + 0x2a) + (s16)D_80126B62; + buf.f1c = *(s16 *)(param_1 + 0x2c) + (s16)iVar4; + buf.f20 = 0; + buf.f22 = 0; + buf.f24 = (s16)*(s32 *)(param_1 + 0x10); + ((void (*)(s32, s32, s32))func_8012F14C)((s32)&buf, (s32)&buf.f20, (s32)&buf.f28); + + *(s32 *)(param_1 + 0x3c) = buf.f28; + *(s32 *)(param_1 + 0x40) = buf.f2a; + *(s32 *)(param_1 + 0x44) = buf.f2c; +} + DEFINE_func_80174B6C() /* dedup: shared engine-core @0x80174b6c (src/shared) */ diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8017AE2C.c b/src/ov_SC07_006/ov_SC07_006_jr_8017AE2C.c index 215d6b2a5..ea7b09a3f 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8017AE2C.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8017AE2C.c @@ -139,7 +139,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8017BEBC.c b/src/ov_SC07_006/ov_SC07_006_jr_8017BEBC.c index 77666ee55..aaff64d8e 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8017BEBC.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8017BEBC.c @@ -139,7 +139,7 @@ extern s8 D_801152C0; extern u8 D_80127504; extern void func_800144D4(void); extern void func_80129C40(s32 _arg0); -extern void func_8012A328(void); +extern void func_8012A328(); extern void func_80053308(s32); extern s32 func_80012F74(s32, s32, s32, s32); /* canonical s32 (engine_core); (s16)-cast the return for the sll/sra */ extern void GsSetRefView2L(void *); diff --git a/src/shared/engine_core.h b/src/shared/engine_core.h index b7057645d..35c36081c 100644 --- a/src/shared/engine_core.h +++ b/src/shared/engine_core.h @@ -2027,7 +2027,7 @@ } #define DEFINE_func_801749A8() \ - extern s32 func_801749C8(s32); \ + extern s32 func_801749C8(); \ s32 func_801749A8(s32 a0) { \ return func_801749C8(a0); \ }