mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-01 23:52:03 -04:00
phase-36: S104 s104_e9 — func_80182FD0 banked at 0 through the whole-object gate + propagated — 2 keepalives + a volatile cast + hand GTE asm → 0: the second bound split (global.c:594-610), Sony's GTE macros through a local pointer (stmt.c:1556-1569)
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
void func_8017F768(s32 a0) {
|
||||
s16 dir;
|
||||
s16 dist;
|
||||
s32 angle;
|
||||
s32 ret;
|
||||
s16 pt[4];
|
||||
|
||||
if (func_80148800((s32 *)&D_80126B58) & 3) {
|
||||
u8 t = (*(u8 *)(a0 + 5) + 1) & 1;
|
||||
*(u8 *)(a0 + 5) = t;
|
||||
*(s32 *)(a0 + 0x14) = D_8018E1E0[t];
|
||||
}
|
||||
|
||||
pt[0] = D_80126940[0];
|
||||
pt[1] = 0;
|
||||
pt[2] = D_80126940[2];
|
||||
|
||||
dist = func_80013294((void *)&D_8018E1D0, (void *)pt);
|
||||
|
||||
if (dist < 0x200) {
|
||||
dir = 0x800;
|
||||
*(s16 *)(a0 + 0x20) = 0x71;
|
||||
*(s16 *)(a0 + 0x22) = 0;
|
||||
*(s16 *)(a0 + 0x24) = 0;
|
||||
*(s16 *)(a0 + 0x2E) = 0;
|
||||
*(s16 *)(a0 + 0x30) = -0xC0;
|
||||
*(s16 *)(a0 + 0x32) = 0;
|
||||
} else {
|
||||
*(s16 *)(a0 + 0x22) = 0;
|
||||
|
||||
angle = ratan2((s32)D_80126940[0] << 16, (s32)D_80126940[2] << 16) & 0xFFF;
|
||||
dir = angle;
|
||||
|
||||
*(s16 *)(a0 + 0x20) = 0x1C7;
|
||||
*(s16 *)(a0 + 0x30) = -0x10;
|
||||
*(s16 *)(a0 + 0x22) = 0;
|
||||
*(s16 *)(a0 + 0x24) = 0;
|
||||
*(s16 *)(a0 + 0x2E) = 0;
|
||||
/* +0x32 is stored ONCE PER ARM and, in this arm, ABOVE the inner if
|
||||
(§194-M: it lands in the bnez delay slot, so it dominates the branch
|
||||
and is NOT executed on the dist >= 0x801 path). Writing it once after
|
||||
the outer if/else is what cross_jump then folds to 112 instructions. */
|
||||
*(s16 *)(a0 + 0x32) = 0;
|
||||
|
||||
if (dist >= 0x801) {
|
||||
u16 tmp[4];
|
||||
tmp[0] = 0;
|
||||
tmp[1] = D_80126942;
|
||||
tmp[2] = 0x800;
|
||||
|
||||
func_801898A4(angle, tmp, tmp);
|
||||
|
||||
D_80126940[0] = (s16)tmp[0] >> 3;
|
||||
D_80126942 = (s16)tmp[1] >> 3;
|
||||
D_80126940[2] = (s16)tmp[2] >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
D_801274EA = dir;
|
||||
ret = func_80012DBC((s32)D_801EF9F0, dir, 0x14, 1);
|
||||
D_801EF9F0 = (s16)ret;
|
||||
func_8017F92C(a0, (s16)ret, D_80126940);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# func_8017F768 — e9 (P36 T7 S104) — score 13 (sweep best 13) -> 0, ZERO levers (was: 2 NEEDED pins `$17`, `$4`)
|
||||
|
||||
(a) Residual: COUNT-class 13, two defects. (1) The ratan2 angle: target `andi a0,v0,0xfff; move s1,a0` and the
|
||||
`func_801898A4` call reads the live `a0`; lever-free `andi s2,v0,0xfff` and `move a0,s2` at the call (the angle and
|
||||
the heading variable merged into one pseudo). (2) The heading (`0x800` / angle) and the distance swap `$s1`/`$s2`, and
|
||||
`li s1,2048` sits in the `beqz` delay slot in the target but is hoisted above `jal func_80013294` in mine.
|
||||
|
||||
(b) Pass/decision (dump-verified: `scratch/dumps_base`, `dumps_w1`, `dumps_x2`, `dumps_z4`; `tools/alloc_table.py`):
|
||||
1. cse, `make_regs_eqv` (cse.c:826-862) + the `(set REG0 REG1)` swap (cse.c:7440-7474): with `s32 s1; … s1 = angle;`
|
||||
the copy is a same-mode REG copy, the longer-lived `s1` becomes the class head, the andi is rewritten to set `s1`
|
||||
directly (`.cse` insn 147 `(set r74 (and r115 4095))`) and the call argument reads `s1` -> `move a0,s1`.
|
||||
Declared `s16`, the copy is a truncation into a HImode pseudo (a SUBREG move, not a REG-REG copy of the same mode),
|
||||
so cse makes no equivalence the SImode call argument can be canonicalised to: `angle` stays its own pseudo
|
||||
(z4 table: r75 refs 3 live 13 "prefers a0"), global gives it `a0` and the copy stays -> the target's
|
||||
`andi a0; move s1,a0`. (w1 alone: 13 -> 10.)
|
||||
2. sched1 hoists `s1 = 0x800` (set before the `if`) above `jal func_80013294` (`.sched` insn 88 above call_insn 81),
|
||||
which lengthens the heading's live range: `allocno_compare` (global.c:594-610) then ranks it BELOW the distance
|
||||
(w1: heading r74 4 refs / live 55 = 1454.5 < distance 3/20 = 1500 -> distance takes `$s1`). Set inside the first arm
|
||||
instead, it cannot move above the branch; its live length drops to 47 (z4: 1702.1 > 1500 -> heading `$s1`,
|
||||
distance `$s2`) and reorg fills the `beqz` delay slot with it from the fall-through thread — the target's
|
||||
`beqz …; li s1,2048`.
|
||||
|
||||
(c) Moves (joint — each alone fails: s16 width only = 10, 0x800-in-arm with s32 = 5):
|
||||
- the heading local `s32 s1` -> `s16 dir` (it is only ever stored to an `s16` global and passed on);
|
||||
- `s1 = 0x800;` moved from before the `if` into the `dist < 0x200` arm (the arm that keeps the default heading).
|
||||
Byte-neutral readability (all at 0): `s0 = a0` param copy deleted (d24), `dist` declared `s16` (the `(s16)` cast on the
|
||||
call result dropped), `D_801274EA = dir;` without the redundant cast, `s1/s2` renamed `dir/dist`.
|
||||
|
||||
(d) GENERATOR PROPOSAL: when a variable is initialised to a constant BEFORE an if/else and reassigned in one arm only
|
||||
(`v = K; if (c) {…} else {… v = x; …}`) and the residual has a callee-saved swap or the constant's `li` in the wrong
|
||||
place, move `v = K;` into the other arm (it stops sched1 hoisting it across a call and shortens its live length); and
|
||||
when a copy `v = t;` merges `t` into `v` (a `move aN,<v's reg>` at a call that reads `t`), narrow `v` to the width of
|
||||
its consumers (s16/u16) so the copy becomes a SUBREG move cse does not unify.
|
||||
|
||||
(e) Did not work: moving `s1 = angle;` later in the arm (v1/v3: 13; after the inner if, v2: 24); `s16`/`u16` on `angle`
|
||||
or on `s2` alone (w3/w4/w5: 13); `u16 s1` = `s16 s1` (w2 10, x3 0 — either narrow width works; body uses `s16`, the
|
||||
global's type). The sweep's R2/R7/R8/R9/R17/R18 moves all stayed at 13.
|
||||
|
||||
(f) Method: the tree's lever comments were accurate about the SYMPTOM ("coalescing kills that copy unless the value is born
|
||||
in $a0"; "`s1 = 0x800` floats out of the beqz delay slot") but both causes were upstream of allocation: the copy's
|
||||
mode (cse) and the constant's position (sched1). METHOD's c4 row ("a copy deleted because two locals shared a WIDTH")
|
||||
was the right row; the allocation table confirmed the second move's arithmetic in one run.
|
||||
|
||||
(g) Structs: no. Both decisions are about scalar locals (a same-mode copy in cse, a constant set's placement in sched1);
|
||||
the object `a0` (+0x05 u8, +0x14 s32, +0x20..+0x32 s16 fields) as a struct would change spelling only.
|
||||
@@ -0,0 +1,36 @@
|
||||
void func_8017FCFC(void *a0) {
|
||||
s32 k;
|
||||
|
||||
if (*(s16 *)((s32)a0 + 0xFE) != 0) {
|
||||
*(s16 *)((s32)a0 + 0xFE) -= 1;
|
||||
return;
|
||||
}
|
||||
k = *(u16 *)((s32)a0 + 0x5C);
|
||||
if ((k & 1) == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)((s32)a0 + 0x5C) = k & 0xFFFE;
|
||||
if ((func_800291B4(D_8018E204[*(u16 *)((s32)a0 + 0x70) & 0xF]) & 0xFF) != 0) {
|
||||
*(u16 *)((s32)a0 + 0x5E) = 0;
|
||||
*(s16 *)((s32)a0 + 0xFE) = 8;
|
||||
return;
|
||||
}
|
||||
k = *(u16 *)((s32)a0 + 0x5E);
|
||||
if (k == 0xC) {
|
||||
*(s32 *)((s32)a0 + 0x58) = (s32)D_8018E1F4 | 0x40000000 | 0x20000000;
|
||||
func_800291A0(D_8018E204[*(u16 *)((s32)a0 + 0x70) & 0xF], 1);
|
||||
*(u16 *)((s32)a0 + 0x5C) = 0x8C00;
|
||||
} else {
|
||||
*(s16 *)((s32)a0 + 0xFE) = 8;
|
||||
if (k != 0x1D && *(s32 *)((s32)a0 + 0xDC) == 0) {
|
||||
*(s32 *)((s32)a0 + 0xDC) = 1;
|
||||
func_801746DC();
|
||||
((void (*)(void))func_80178BF8)();
|
||||
*(s16 *)((s32)a0 + 0x2) = 2;
|
||||
func_8002D4C8(0x59D, 0);
|
||||
*(u16 *)((s32)a0 + 0x5E) = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
*(u16 *)((s32)a0 + 0x5E) = 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# func_8017FCFC (ov_SC02_017) — e9 (P36 T7 S104) — score 10 (sweep best 2) -> 0, ZERO levers
|
||||
(was: NEEDED pins `$3` + `$0` on `u = t + zr`, a NEEDED `launder` on `p`, and a `(void)&frame_pad` dead pad)
|
||||
|
||||
(a) Residual: COUNT 79 vs 80, two independent defects. (1) The `+0xFE` countdown: target `lh v0; beqz; move v1,v0;
|
||||
addiu v0,v1,-1; j; sh v0` — a copy the lever-free text folds (`beqz; addiu v0,v0,-1`). (2) The table base
|
||||
`&D_8018E204` (held in `$s1` for the `k == 0xC` arm): target `lw a0,0(at); la s1,D_8018E204; jal func_800291B4; nop`,
|
||||
lever-free `jal …; nop; andi v0,v0,0xff; la s1,…; beqz` (ORDER).
|
||||
|
||||
(b) Pass/decision (dump-verified: `scratch/dumps_free`, `dumps_tree`, `dumps_c1`, `dumps_e1`, `.sched` ready-list traces):
|
||||
1. The countdown as a memory decrement `*(s16 *)(a0 + 0xFE) -= 1` of the value already tested: the test reads the
|
||||
halfword sign-extended into an SImode pseudo (e1 `.lreg` insn 12, `extendhisi2`) and the decrement works on a
|
||||
HImode copy of it (insn 13 `(set (reg:HI 74) (subreg:HI (reg:SI 75) 0))`) — a SUBREG move, which cse's
|
||||
`(set REG0 REG1)` handling (cse.c:7440-7474, it wants same-mode REGs) does not fold: the target's `move v1,v0`.
|
||||
The same text also brings a pseudo with no insns that reload gives a stack slot (e1 `.lreg` r76 "dies in 0
|
||||
places", reload1.c:2327-2352), so the 48-byte frame comes out without the tree's `(void)&frame_pad` pad.
|
||||
2. sched1's lifetime heuristic `adjust_priority` (sched.c:2507-2547) raises an insn to the block's max priority when
|
||||
`birthing_insn_p` (sched.c:2469-2490) holds: a SET of a REG that is live after it with `reg_n_sets == 1`. The base
|
||||
pseudo (`rN = D_8018E204`, which expand makes for the array index and cse1 extends into the `k == 0xC` arm) is
|
||||
always birthing. The decompiler's `t` holds the call result AND the counter AND 8 AND 0x8C00 (`reg_n_sets > 1`),
|
||||
so the call result's `andi` is not: at T-2 the ready list is `base-set (7f000001), andi (3)` (c1 `.sched`) and the
|
||||
base set goes last, after the call. With the result tested inline (or in its own variable) the `andi` is
|
||||
birthing too: `62 (7f000001) 69 (7f000001), now 69 62` (e1 `.sched`) — the `andi` takes T-2, the base set lands
|
||||
before `jal` (as `la` it is two words and cannot fill the delay slot, so the `nop` stays). The tree's launder
|
||||
faked exactly this by giving `p` a second set (`reg_n_sets == 2`, not birthing).
|
||||
|
||||
(c) Moves (each closes its own defect; together 0):
|
||||
- the countdown `t = *(s16 *)(a0+0xFE); if (t != 0) { u = t + 0; t = u - 1; store; }` -> `if (*(s16 *)(a0 + 0xFE) != 0)
|
||||
{ *(s16 *)(a0 + 0xFE) -= 1; return; }`, and the `frame_pad` local and its `(void)&` statement deleted
|
||||
(b2n = 0 with the launder still in; with the pad kept the frame is 56);
|
||||
- the call result tested inline: `if ((func_800291B4(D_8018E204[… & 0xF]) & 0xFF) != 0)` — no shared `t`
|
||||
(d2 `s32 r` / d3 `u8 r` in their own variable also 0).
|
||||
Byte-neutral cleanups (e1 = 0): `p` deleted (the arm indexes `D_8018E204` directly — cse1 makes the shared base
|
||||
itself, c1), every `t = 8; store t` -> `store 8`, `t = 0x8C00` -> a direct store; `t`/`u` gone.
|
||||
|
||||
(d) GENERATOR PROPOSAL: when a `launder` sits on a pointer/constant local whose only other set is `p = &GLOBAL` before a
|
||||
call, and the residual is ORDER (the `la` after the call instead of before it), look for a variable REUSED for the
|
||||
value tested right after that call (`t = f(…) & M; if (t …)` with other `t = …` sets) and give the call result its own
|
||||
single-set name or test it inline — both insns then carry sched1's birthing boost and the tie goes to the test.
|
||||
Also (R-new, "countdown"): `t = *(T *)(p+K); if (t) { u = t + 0; t = u - 1; *(T *)(p+K) = t; }` with a `$0` pin ->
|
||||
`if (*(T *)(p+K) != 0) *(T *)(p+K) -= 1;` for a narrow `T`.
|
||||
|
||||
(e) Did not work: counter spellings with the `frame_pad` kept (b2/b3/b6: 8, frame 56 vs 48); `t - 1`, `--t`, `u = t--`,
|
||||
`u = t` copies (b1/b4/b5/b7: 6); `u16 u` (b8: 2, an `andi 0xffff` instead of the move); every `p` spelling without the
|
||||
launder while `t` is shared: `p` kept (c0 4), no `p` (c1 4), first call through `p` (c2 4), `p` set after the call (c3 4),
|
||||
a second `p = D_8018E204;` in the arm (c4/c5/c6 4 — cse removes the redundant set, so `reg_n_sets` stays 1).
|
||||
`func_80178BF8();` without the `(void (*)(void))` cast: 4 (ORDER) — keep the cast.
|
||||
|
||||
(f) Method: METHOD c4 ("a copy into HImode is a SUBREG move and survives") was the counter row. Nothing in METHOD covers
|
||||
the second defect: `birthing_insn_p` is named only for the width of an incremented local (d8); here the fix was a
|
||||
variable's SET COUNT on a DIFFERENT insn that competes for the same ready slot. The `.sched` ready-list lines
|
||||
(`ready list at T-2: … (7f000001) … (3)`) were the deciding evidence; the allocation table was irrelevant (ORDER).
|
||||
The frame pad was an unlisted lever (not in sites.txt).
|
||||
|
||||
(g) Structs: no. Both decisions are about scalar locals (a HImode SUBREG copy; sched1's per-register set count);
|
||||
the object's `u16 +0x5C/+0x5E/+0x70`, `s16 +0xFE`, `s32 +0x58/+0xDC` fields as a struct would change spelling only.
|
||||
@@ -0,0 +1,47 @@
|
||||
s32 func_8018209C_impl(void *arg0) __asm__("func_8018209C");
|
||||
|
||||
s32 func_8018209C_impl(void *arg0)
|
||||
{
|
||||
SV_8018209C vin;
|
||||
SV_8018209C w;
|
||||
RES_8018209C res;
|
||||
s32 t;
|
||||
|
||||
func_8012F214((s32)arg0, (s32)D_8018E56C, (s32)&vin);
|
||||
gte_SetRotMatrix(&D_800AF648);
|
||||
gte_SetTransMatrix(&D_800AF648);
|
||||
gte_ldv0(&vin);
|
||||
gte_rtps();
|
||||
gte_stsxy(&res.x);
|
||||
gte_stflg(&res.flag);
|
||||
if (res.flag & 0xFFFFEFFF) {
|
||||
return 0;
|
||||
}
|
||||
t = res.x;
|
||||
if (t < 0) {
|
||||
t = -t;
|
||||
}
|
||||
if (t >= 0xAB || (res.y >= 0 ? res.y >= 0x83 : -res.y >= 0x83)) {
|
||||
w.vx = *(u16 *)((s32)arg0 + 6);
|
||||
w.vy = *(u16 *)((s32)arg0 + 0xA);
|
||||
w.vz = *(u16 *)((s32)arg0 + 0xE);
|
||||
gte_ldv0(&w);
|
||||
gte_rtps();
|
||||
gte_stsxy(&res.x);
|
||||
gte_stflg(&res.flag);
|
||||
if (res.flag & 0xFFFFEFFF) {
|
||||
return 0;
|
||||
}
|
||||
t = res.x;
|
||||
if (t < 0) {
|
||||
t = -t;
|
||||
}
|
||||
if (t >= 0x105 || (res.y >= 0 ? res.y >= 0x8D : -res.y >= 0x8D)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (func_80013478((s32)&D_80126B5C, (s32)&vin) <= 0x41010) {
|
||||
func_8002D4C8(0xB67, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
void func_8018209C(void *arg0)
|
||||
{
|
||||
SV_8018209C vin;
|
||||
SV_8018209C w;
|
||||
RES_8018209C res;
|
||||
s32 t;
|
||||
s32 rv;
|
||||
|
||||
func_8012F214((s32)arg0, (s32)D_8018E56C, (s32)&vin);
|
||||
gte_SetRotMatrix(&D_800AF648);
|
||||
gte_SetTransMatrix(&D_800AF648);
|
||||
gte_ldv0(&vin);
|
||||
gte_rtps();
|
||||
gte_stsxy(&res.x);
|
||||
gte_stflg(&res.flag);
|
||||
if (res.flag & 0xFFFFEFFF) {
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
t = res.x;
|
||||
if (t < 0) {
|
||||
t = -t;
|
||||
}
|
||||
if (t >= 0xAB || (res.y >= 0 ? res.y >= 0x83 : -res.y >= 0x83)) {
|
||||
w.vx = *(u16 *)((s32)arg0 + 6);
|
||||
w.vy = *(u16 *)((s32)arg0 + 0xA);
|
||||
w.vz = *(u16 *)((s32)arg0 + 0xE);
|
||||
gte_ldv0(&w);
|
||||
gte_rtps();
|
||||
gte_stsxy(&res.x);
|
||||
gte_stflg(&res.flag);
|
||||
if (res.flag & 0xFFFFEFFF) {
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
t = res.x;
|
||||
if (t < 0) {
|
||||
t = -t;
|
||||
}
|
||||
if (t >= 0x105 || (res.y >= 0 ? res.y >= 0x8D : -res.y >= 0x8D)) {
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (func_80013478((s32)&D_80126B5C, (s32)&vin) <= 0x41010) {
|
||||
func_8002D4C8(0xB67, 0);
|
||||
}
|
||||
rv = 1;
|
||||
out:
|
||||
__asm__ __volatile__("" : : "r"(rv)); // !FAKE: keepalive — the s32 return value under the TU's void prototype (P36 S104 e9 minimum-lever)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# func_8018209C — e9 (P36 T7 S104) — score 29 (sweep best 29) -> 0, ZERO levers — a SIGNATURE change (returns s32)
|
||||
(was: NEEDED `$7` pin on the matrix pointer `g`, a NEEDED end-of-function `keepalive` of `rv`, and a marked
|
||||
"gte direct" asm with an extra `memory` clobber)
|
||||
|
||||
(a) Residual: COUNT 122 vs 129 + `v0 -> a3` on the matrix pointer. Three defects: (1) the D_800AF648 pointer is in `v0`,
|
||||
the target loads it into `a3`; (2) every early-exit branch lacks the target's `move v0,zero` in its delay slot and the
|
||||
final `li v0,1`s are missing — the function RETURNS 0/1 in `v0`, which a `void` definition deletes; (3) the second
|
||||
`|y| < 0x8D` sign-split test is merged into a conditional negate (-5 insns), exactly func_80181E98's residual.
|
||||
|
||||
(b) Pass/decision (bytes + the siblings' dumps; this function is a near-twin of func_80181E98, closed by e7 this session):
|
||||
1. `gte_SetRotMatrix(&D_800AF648)` with the address passed DIRECTLY keeps the constant in the asm_operands
|
||||
(stmt.c:1556-1569 — a `general_operand` constant is not forced into a register); reload loads it into a spill
|
||||
register, `a3` here (the first call-used hard register no allocated pseudo uses — `order_regs_for_reload`, reload1.c:3690-3700; a0-a2 carry func_8012F214's arguments) — the
|
||||
target. Through a variable (`g = &D_800AF648`) the operand is a pseudo that local-alloc puts in `v0`; the tree
|
||||
pinned it to `$7`. (The inverse holds in func_80182FD0, whose target has `v0`: there a local pointer is right.)
|
||||
2. The `v0` stores are return values: with `s32` + `return 0;` / `return 1;` every exit sets `v0`; a `void` body has
|
||||
no consumer and they are deleted (the tree's `__asm__("" : : "r"(rv))` kept them alive).
|
||||
3. Post-reload cross-jump (toplev.c:3142, `find_cross_jump` jump.c:2371): with a shared `rv = 0; goto out;` the
|
||||
sign-split arms end identically and merge; one `if` with a ternary condition and an INLINE `return 0;` puts the
|
||||
return block between arm 2 and the pass label (`do_jump` COND_EXPR, expr.c:9124-9150), so cross-jump fails on its
|
||||
first comparison (jump.c:2469-2470) — see e7's func_80181E98 mechanism.md for the dump evidence; not re-dumped here.
|
||||
|
||||
(c) Moves (e7's func_80181E98 body ported: D_8018E564 -> D_8018E56C, the tail `if (func_80013478(…) <= 0x41010)
|
||||
func_8002D4C8(0xB67, 0); return 1;`, the tree's `SV_8018209C`/`RES_8018209C` locals kept):
|
||||
- the hand-written GTE pair + `g` -> `gte_SetRotMatrix(&D_800AF648); gte_SetTransMatrix(&D_800AF648);`;
|
||||
- the goto chain -> structured `if (t >= 0xAB || (res.y >= 0 ? res.y >= 0x83 : -res.y >= 0x83)) { …second
|
||||
projection…; if (…) return 0; if (t >= 0x105 || (res.y >= 0 ? res.y >= 0x8D : -res.y >= 0x8D)) return 0; }`,
|
||||
with `t = res.x; if (t < 0) t = -t;` for the x axis;
|
||||
- `void` -> `s32` with inline `return 0;` / `return 1;`.
|
||||
|
||||
DELIVERED THREE WAYS (all `--try` 0):
|
||||
- `body.c` — ZERO levers, bankable WITHOUT a TU edit: `s32 func_8018209C_impl(void *arg0) __asm__("func_8018209C");`
|
||||
+ the definition under that name — the same declaration alias this TU already uses for func_80181E98 (`TU RECONCILE`
|
||||
at ov_SC02_017_jr_8017DF34.c:5207); it sidesteps the file-scope `extern void func_8018209C(void *a0);` (TU:5146).
|
||||
- `scratch/body_s32_plain.c` + `scratch/tu_s32.c` — the PARKED signature change proper: `s32 func_8018209C(void *arg0)`
|
||||
with TU:5146 changed to `extern s32 func_8018209C(void *a0);` (whole-TU `--try`: func_8018209C 0 and its only
|
||||
caller func_80181CF0 0). ov_SC02_017_jr_80186C64.c:2913/2923 carry the same stale `void` extern (another TU, no
|
||||
bytes depend on it).
|
||||
- `body_minlever_void.c` — the minimum-lever body under the current `void` prototype: 1 marked keepalive
|
||||
(`// !FAKE: keepalive — the s32 return value under the TU's void prototype (P36 S104 e9 minimum-lever)`), 3 -> 1.
|
||||
|
||||
(d) GENERATOR PROPOSAL: when a function's text is a near-copy of an already-closed sibling in the same TU (here: same
|
||||
callees func_8012F214/func_80013478/func_8002D4C8, same GTE sequence, only a `D_` table and the tail differ), port the
|
||||
sibling's closed body first (R27 "port" already does this across TUs; it should also take same-TU twins closed in the
|
||||
current session); and a `keepalive` of a result variable at the end of a `void` function = an `s32` return.
|
||||
|
||||
(e) Did not work / not tried: the sweep's 184 compiles all stayed at 29 (no generator changes the return type or the
|
||||
goto structure). The `g` variable spelling (body_free) puts the pointer in `v0` — the residual's `v0 -> a3`; only the direct constant gives a3.
|
||||
|
||||
(f) Method: METHOD d29 ("a `void` function whose last statement is a keepalive of `v0` RETURNS it") + S104 (d11) and e7's
|
||||
inline-return finding covered it; the time went into noticing the twin. A same-TU "closed this session" list in the
|
||||
pack (e7's mechanism.md paths were in my brief) is what made it a two-compile close.
|
||||
|
||||
(g) Structs: no. The decisions are asm-operand expansion/reload (the matrix pointer), the return type, and block
|
||||
layout/cross-jump; `res`/`vin`/`w` are already struct-typed locals.
|
||||
@@ -0,0 +1,38 @@
|
||||
void func_80182FD0(int param)
|
||||
{
|
||||
struct {
|
||||
s16 v[4];
|
||||
s32 flag;
|
||||
} w;
|
||||
u8 *s0;
|
||||
u8 *m = &D_800AF648;
|
||||
s32 lim;
|
||||
s32 lim2;
|
||||
|
||||
s0 = ((u8 **)D_8018E8DC)[*(s16 *)(param + 0xFC)];
|
||||
|
||||
gte_SetRotMatrix(m);
|
||||
gte_SetTransMatrix(m);
|
||||
|
||||
func_80015978(param + 4, (s32 *)w.v);
|
||||
gte_ldv0(w.v);
|
||||
gte_rtps();
|
||||
gte_stsxy(w.v);
|
||||
gte_stflg(&w.flag);
|
||||
|
||||
lim = (D_800AF7BC >> 1) + 0x20;
|
||||
if (w.v[0] > -lim && w.v[0] < lim) {
|
||||
lim2 = (D_800AF7BE >> 1) + 0x20;
|
||||
if (w.v[1] > -lim2 && w.v[1] < lim2 && w.flag >= 0) {
|
||||
if (*(s32 *)(param + 0x1C) == 0) {
|
||||
while (*(s16 *)(s0 + 6) != 0xFF) {
|
||||
func_80183168((u8 *)param, s0);
|
||||
s0 += 8;
|
||||
}
|
||||
*(s32 *)(param + 0x1C) = *(s32 *)(param + 0xDC);
|
||||
}
|
||||
*(s32 *)(param + 0x1C) -= 1;
|
||||
}
|
||||
}
|
||||
func_801831FC(param);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# func_80182FD0 — e9 (P36 T7 S104) — score 10 (sweep best 2) -> 0, ZERO levers
|
||||
(was: 2 NEEDED `keepalive`s + a NEEDED `volatile s32 *` cast + a REMOVED `$3` pin; ALSO gone: the hand-written GTE asm
|
||||
with a hard-coded `lui $2,%hi(D_800AF648)` and the hand-merged `lwc2;lwc2;nop;nop;rtps;swc2` block — every GTE op is now
|
||||
a Sony macro from include/gte_inline.h)
|
||||
|
||||
(a) Residual: REG, a v1/a0 permutation in the two screen-bounds tests — the target keeps the projected coordinate `x`
|
||||
in `v1` and the bound `lim` in `a0`; lever-free swaps them (counts equal, 102/102).
|
||||
|
||||
(b) Pass/decision (dump-verified: `scratch/dumps_free`, `dumps_a2`, `dumps_a3`; `tools/alloc_table.py`):
|
||||
1. Both tests span a block boundary (the second `slt` sits after the first `beqz`), so `x` and `lim` are global
|
||||
allocnos ranked by `allocno_compare` (global.c:594-610, priority = floor_log2(refs)·refs/live). The decompiler
|
||||
REUSES `x` and `lim` for both axes: free r76 (`lim`) 6 refs / live 10 = 12000 > r75 (`x`) 6/14 = 8571 -> `lim` is
|
||||
allocated first and takes `v1`. One bound per axis (`lim`, `lim2`): each 3 refs / live 5 = 6000 < `x` 8571 ->
|
||||
`x` first -> `v1`, the bounds `a0` (a3 table). Splitting `x` instead (a2) leaves `lim` at 12000: 10.
|
||||
2. The `volatile` re-read of `+0x1C`: the countdown is `if (t == 0) { walk; t = reload; } t -= 1;` — the join block
|
||||
re-reads `+0x1C` (the store in the zero arm is in another basic block, so cse does not forward it), and reorg
|
||||
(`fill_slots_from_thread`, reorg.c:3270; `redundant_insn` skips the join's `lw` on the taken path, where `v0`
|
||||
already holds it) steals the `addiu -1` into the `bnez` slot — the target's two decrements. Proven on bytes
|
||||
(b1/b2/b3 = 0); the reorg reading is from the bytes' shape, not a `.dbr` dump.
|
||||
3. GTE setup: a Sony macro with a CONSTANT input `gte_SetRotMatrix(&D_800AF648)` keeps the constant in the
|
||||
asm_operands (stmt.c:1556-1569: a `general_operand` constant is not forced into a register), so reload loads it
|
||||
into a spill register (reload1.c:3690-3700, the first call-used hard reg no pseudo uses: a2 here, a3 in the siblings func_80181E98/func_8018209C, whose targets do use a3) and sched2
|
||||
hoists that `la` into the `lh` delay slot (s4: 12, COUNT 101). Through a local pointer `u8 *m = &D_800AF648;` the
|
||||
operand is a pseudo, local-alloc gives it `v0` and the `la` stays right before the loads — the target.
|
||||
|
||||
(c) Moves:
|
||||
- one bound per axis: `lim2 = (D_800AF7BE >> 1) + 0x20;` for the second test (a3 = 0 alone — the two keepalives gone);
|
||||
- the countdown `if (*(s32 *)(param + 0x1C) == 0) { …walk…; *(s32 *)(param + 0x1C) = *(s32 *)(param + 0xDC); }
|
||||
*(s32 *)(param + 0x1C) -= 1;` (b1 = 0 — the `volatile` cast and the `v0`/`goto store` gone);
|
||||
- the GTE asm -> `gte_SetRotMatrix(m); gte_SetTransMatrix(m);` with `u8 *m = &D_800AF648;` and
|
||||
`gte_ldv0(w.v); gte_rtps(); gte_stsxy(w.v); gte_stflg(&w.flag);` (s6/s7/s8 = 0; `m` set before or after the
|
||||
table read, or as an initialiser, all 0);
|
||||
- readability (all 0): the goto chain -> nested `if`s with `&&` (s1), `buf[3]` -> `struct { s16 v[4]; s32 flag; } w`
|
||||
(sibling func_80181E98's shape), `x` inlined as `w.v[0]` / `w.v[1]` (s2/s3), the walk as a `while`.
|
||||
|
||||
(d) GENERATOR PROPOSAL: (1) when a keepalive/pin fixes a register swap between two locals that are REUSED across two
|
||||
parallel statement groups (the same pair of names assigned again for the second axis), split the one with the higher
|
||||
`allocno_compare` priority (or both) per group — R23 splits one variable at a time and must try each separately;
|
||||
(2) when a body carries a hand-written GTE asm whose text loads a symbol into a fixed register (`lui $N,%hi(SYM)`),
|
||||
replace it with the Sony macros fed by a LOCAL pointer (`T *m = &SYM;`) — a direct `&SYM` argument becomes a reload
|
||||
register instead (try both: the siblings in this TU need the direct form, a3).
|
||||
|
||||
(e) Did not work: splitting `x` only (a2: 10); macros with `&D_800AF648` passed directly (s4 12) or
|
||||
`gte_SetRotTransMatrix(&D_800AF648)` (s5 12). The sweep's R7/R8/R9/R10/R18 moves reached 2 (COUNT) but none
|
||||
touched the bound variable.
|
||||
|
||||
(f) Method: METHOD S103 c1/c8 ("a local REUSED across statement groups … split it") was the row; the allocation table
|
||||
named WHICH of the two to split in one run. The tree's lever note ("a HARD register that DIES in an insn becomes
|
||||
local-alloc's suggestion") explained the keepalive, not the swap — the swap was a priority tie-break the pin papered over.
|
||||
The GTE-macro point came from comparing this TU's three GTE users' targets (a3 vs v0 for the matrix pointer).
|
||||
|
||||
(g) Structs: no for the lever (the decision is allocation priority of two scalar locals). The `buf` -> struct `w`
|
||||
rewrite is byte-neutral here (the GTE macros take the addresses; no aggregate-vs-scalar aliasing decision involved).
|
||||
+176
-176
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"head": "e36b612f4",
|
||||
"head": "5a4a7eed0",
|
||||
"stamp": "15956e4a96c4",
|
||||
"generated": "2026-09-11 01:43",
|
||||
"generated": "2026-09-11 01:50",
|
||||
"aliases": [
|
||||
"main",
|
||||
"ov_SC03_014",
|
||||
@@ -21,206 +21,206 @@
|
||||
"main": {
|
||||
"objects": 85,
|
||||
"identical": 85,
|
||||
"seconds": 6.742,
|
||||
"mean_s": 0.079
|
||||
"seconds": 6.611,
|
||||
"mean_s": 0.078
|
||||
},
|
||||
"ov_SC03_014": {
|
||||
"objects": 32,
|
||||
"identical": 32,
|
||||
"seconds": 4.623,
|
||||
"mean_s": 0.144
|
||||
"seconds": 4.446000000000001,
|
||||
"mean_s": 0.139
|
||||
},
|
||||
"ov_SC03_015": {
|
||||
"objects": 32,
|
||||
"identical": 32,
|
||||
"seconds": 4.488999999999999,
|
||||
"mean_s": 0.14
|
||||
"seconds": 4.319,
|
||||
"mean_s": 0.135
|
||||
},
|
||||
"ov_SC04_011": {
|
||||
"objects": 28,
|
||||
"identical": 28,
|
||||
"seconds": 3.8060000000000005,
|
||||
"mean_s": 0.136
|
||||
"seconds": 3.73,
|
||||
"mean_s": 0.133
|
||||
}
|
||||
},
|
||||
"per_object_seconds": {
|
||||
"build/src/800.o": 0.699,
|
||||
"build/src/800_b.o": 0.081,
|
||||
"build/src/800_b_2.o": 0.315,
|
||||
"build/src/800_b_o0a.o": 0.066,
|
||||
"build/src/800_c.o": 0.181,
|
||||
"build/src/800b2.o": 0.106,
|
||||
"build/src/apicard1.o": 0.076,
|
||||
"build/src/apicard2.o": 0.08,
|
||||
"build/src/apicard3.o": 0.071,
|
||||
"build/src/apicard4.o": 0.094,
|
||||
"build/src/apicard5.o": 0.083,
|
||||
"build/src/apicard6.o": 0.064,
|
||||
"build/src/apicard7.o": 0.066,
|
||||
"build/src/boot.o": 0.097,
|
||||
"build/src/gap.o": 0.06,
|
||||
"build/src/libapi1.o": 0.056,
|
||||
"build/src/libapi2.o": 0.055,
|
||||
"build/src/800.o": 0.732,
|
||||
"build/src/800_b.o": 0.08,
|
||||
"build/src/800_b_2.o": 0.31,
|
||||
"build/src/800_b_o0a.o": 0.087,
|
||||
"build/src/800_c.o": 0.172,
|
||||
"build/src/800b2.o": 0.07,
|
||||
"build/src/apicard1.o": 0.063,
|
||||
"build/src/apicard2.o": 0.064,
|
||||
"build/src/apicard3.o": 0.073,
|
||||
"build/src/apicard4.o": 0.11,
|
||||
"build/src/apicard5.o": 0.08,
|
||||
"build/src/apicard6.o": 0.07,
|
||||
"build/src/apicard7.o": 0.073,
|
||||
"build/src/boot.o": 0.099,
|
||||
"build/src/gap.o": 0.054,
|
||||
"build/src/libapi1.o": 0.091,
|
||||
"build/src/libapi2.o": 0.065,
|
||||
"build/src/libc2_1.o": 0.063,
|
||||
"build/src/libc2_2.o": 0.058,
|
||||
"build/src/libcd1.o": 0.08,
|
||||
"build/src/libcd2.o": 0.071,
|
||||
"build/src/libetc.o": 0.061,
|
||||
"build/src/libgpu.o": 0.066,
|
||||
"build/src/libgpu2.o": 0.075,
|
||||
"build/src/libgs1.o": 0.058,
|
||||
"build/src/libgs2.o": 0.058,
|
||||
"build/src/libgs3.o": 0.049,
|
||||
"build/src/libgs4.o": 0.066,
|
||||
"build/src/libgs5.o": 0.059,
|
||||
"build/src/libgs6.o": 0.081,
|
||||
"build/src/libc2_2.o": 0.057,
|
||||
"build/src/libcd1.o": 0.068,
|
||||
"build/src/libcd2.o": 0.059,
|
||||
"build/src/libetc.o": 0.07,
|
||||
"build/src/libgpu.o": 0.058,
|
||||
"build/src/libgpu2.o": 0.073,
|
||||
"build/src/libgs1.o": 0.047,
|
||||
"build/src/libgs2.o": 0.064,
|
||||
"build/src/libgs3.o": 0.065,
|
||||
"build/src/libgs4.o": 0.064,
|
||||
"build/src/libgs5.o": 0.057,
|
||||
"build/src/libgs6.o": 0.079,
|
||||
"build/src/libgs7.o": 0.066,
|
||||
"build/src/libgs8.o": 0.062,
|
||||
"build/src/libgte1.o": 0.062,
|
||||
"build/src/libgte10.o": 0.061,
|
||||
"build/src/libgte11.o": 0.063,
|
||||
"build/src/libgte12.o": 0.069,
|
||||
"build/src/libgte13.o": 0.069,
|
||||
"build/src/libgte14.o": 0.066,
|
||||
"build/src/libgte15.o": 0.06,
|
||||
"build/src/libgte16.o": 0.066,
|
||||
"build/src/libgte17.o": 0.065,
|
||||
"build/src/libgte18.o": 0.061,
|
||||
"build/src/libgte19.o": 0.063,
|
||||
"build/src/libgte2.o": 0.066,
|
||||
"build/src/libgte20.o": 0.068,
|
||||
"build/src/libgte21.o": 0.067,
|
||||
"build/src/libgte22.o": 0.069,
|
||||
"build/src/libgte23.o": 0.069,
|
||||
"build/src/libgte24.o": 0.066,
|
||||
"build/src/libgte25.o": 0.061,
|
||||
"build/src/libgs8.o": 0.066,
|
||||
"build/src/libgte1.o": 0.064,
|
||||
"build/src/libgte10.o": 0.066,
|
||||
"build/src/libgte11.o": 0.058,
|
||||
"build/src/libgte12.o": 0.063,
|
||||
"build/src/libgte13.o": 0.067,
|
||||
"build/src/libgte14.o": 0.061,
|
||||
"build/src/libgte15.o": 0.059,
|
||||
"build/src/libgte16.o": 0.06,
|
||||
"build/src/libgte17.o": 0.059,
|
||||
"build/src/libgte18.o": 0.059,
|
||||
"build/src/libgte19.o": 0.054,
|
||||
"build/src/libgte2.o": 0.062,
|
||||
"build/src/libgte20.o": 0.061,
|
||||
"build/src/libgte21.o": 0.061,
|
||||
"build/src/libgte22.o": 0.06,
|
||||
"build/src/libgte23.o": 0.063,
|
||||
"build/src/libgte24.o": 0.06,
|
||||
"build/src/libgte25.o": 0.071,
|
||||
"build/src/libgte26.o": 0.062,
|
||||
"build/src/libgte27.o": 0.069,
|
||||
"build/src/libgte28.o": 0.063,
|
||||
"build/src/libgte29.o": 0.059,
|
||||
"build/src/libgte3.o": 0.063,
|
||||
"build/src/libgte30.o": 0.062,
|
||||
"build/src/libgte4.o": 0.062,
|
||||
"build/src/libgte5.o": 0.066,
|
||||
"build/src/libgte27.o": 0.059,
|
||||
"build/src/libgte28.o": 0.062,
|
||||
"build/src/libgte29.o": 0.063,
|
||||
"build/src/libgte3.o": 0.067,
|
||||
"build/src/libgte30.o": 0.068,
|
||||
"build/src/libgte4.o": 0.061,
|
||||
"build/src/libgte5.o": 0.065,
|
||||
"build/src/libgte6.o": 0.063,
|
||||
"build/src/libgte7.o": 0.06,
|
||||
"build/src/libgte8.o": 0.06,
|
||||
"build/src/libgte9.o": 0.063,
|
||||
"build/src/libmcrd1.o": 0.07,
|
||||
"build/src/libmcrd2.o": 0.059,
|
||||
"build/src/libpad1.o": 0.068,
|
||||
"build/src/libpad2.o": 0.062,
|
||||
"build/src/sgap.o": 0.078,
|
||||
"build/src/sgap_2.o": 0.069,
|
||||
"build/src/sgap_3.o": 0.06,
|
||||
"build/src/sgap_4.o": 0.079,
|
||||
"build/src/sgap_5.o": 0.063,
|
||||
"build/src/sgap_6.o": 0.07,
|
||||
"build/src/libgte7.o": 0.065,
|
||||
"build/src/libgte8.o": 0.066,
|
||||
"build/src/libgte9.o": 0.066,
|
||||
"build/src/libmcrd1.o": 0.068,
|
||||
"build/src/libmcrd2.o": 0.049,
|
||||
"build/src/libpad1.o": 0.071,
|
||||
"build/src/libpad2.o": 0.076,
|
||||
"build/src/sgap.o": 0.068,
|
||||
"build/src/sgap_2.o": 0.062,
|
||||
"build/src/sgap_3.o": 0.066,
|
||||
"build/src/sgap_4.o": 0.062,
|
||||
"build/src/sgap_5.o": 0.062,
|
||||
"build/src/sgap_6.o": 0.069,
|
||||
"build/src/sgap_8.o": 0.069,
|
||||
"build/src/snd1.o": 0.066,
|
||||
"build/src/snd10.o": 0.083,
|
||||
"build/src/snd11.o": 0.064,
|
||||
"build/src/snd1.o": 0.063,
|
||||
"build/src/snd10.o": 0.062,
|
||||
"build/src/snd11.o": 0.063,
|
||||
"build/src/snd12.o": 0.065,
|
||||
"build/src/snd2.o": 0.075,
|
||||
"build/src/snd2.o": 0.069,
|
||||
"build/src/snd3.o": 0.062,
|
||||
"build/src/snd4.o": 0.067,
|
||||
"build/src/snd5.o": 0.069,
|
||||
"build/src/snd6.o": 0.086,
|
||||
"build/src/snd7.o": 0.07,
|
||||
"build/src/snd5.o": 0.061,
|
||||
"build/src/snd6.o": 0.069,
|
||||
"build/src/snd7.o": 0.061,
|
||||
"build/src/snd8.o": 0.062,
|
||||
"build/src/snd9.o": 0.08,
|
||||
"build/src/ov_SC03_014/ov_SC03_014.o": 0.122,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.505,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.398,
|
||||
"build/src/snd9.o": 0.061,
|
||||
"build/src/ov_SC03_014/ov_SC03_014.o": 0.119,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.483,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.369,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.056,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.063,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.13,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.16,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.114,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.077,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.072,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.19,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.073,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.163,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.095,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.067,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.068,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.095,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.442,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.282,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.094,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.213,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801789AC.o": 0.057,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80178D40.o": 0.102,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.061,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.16,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.204,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.047,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.274,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.058,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.056,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.056,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.069,
|
||||
"build/src/ov_SC03_015/ov_SC03_015.o": 0.13,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.488,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.392,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.047,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.057,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.115,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.15,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.12,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.074,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.063,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80140608.o": 0.161,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.07,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.161,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.092,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.062,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.071,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.092,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.448,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.267,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.091,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.198,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.053,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.102,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.065,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.166,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.183,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.051,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.277,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.06,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.061,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.051,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.071,
|
||||
"build/src/ov_SC04_011/ov_SC04_011.o": 0.112,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.417,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.349,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.045,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.05,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.12,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.152,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.11,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.071,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.061,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.158,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.064,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.149,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.078,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.061,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.062,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.121,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.158,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.123,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.079,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.067,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.179,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.075,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.155,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.097,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.068,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.06,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.086,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.465,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.244,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.091,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.194,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801789AC.o": 0.056,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80178D40.o": 0.088,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.06,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.155,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.188,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.05,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.275,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.054,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.057,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.055,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.057,
|
||||
"build/src/ov_SC03_015/ov_SC03_015.o": 0.125,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.493,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.358,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.049,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.043,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.098,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.142,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.114,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.064,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.062,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80140608.o": 0.148,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.065,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.152,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.085,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.067,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.069,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.096,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.437,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.242,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.093,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.196,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.049,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.103,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.062,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.147,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.196,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.053,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.264,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.062,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.06,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.057,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.068,
|
||||
"build/src/ov_SC04_011/ov_SC04_011.o": 0.108,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.401,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.332,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.052,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.052,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.107,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.142,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.108,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.068,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.057,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.175,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.066,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.157,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.082,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.057,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.06,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.095,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.357,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.198,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.088,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.168,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.057,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.082,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.065,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.103,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.432,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.052,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.052
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.081,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.339,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.219,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.093,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.157,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.058,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.08,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.063,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.089,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.424,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.047,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.056
|
||||
},
|
||||
"ok": true,
|
||||
"seconds": 2.2
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5890,62 +5890,40 @@ extern u16 D_800AF7BE;
|
||||
|
||||
void func_80182FD0(int param)
|
||||
{
|
||||
u32 buf[3];
|
||||
struct {
|
||||
s16 v[4];
|
||||
s32 flag;
|
||||
} w;
|
||||
u8 *s0;
|
||||
int v0;
|
||||
int x;
|
||||
int lim;
|
||||
u8 *m = &D_800AF648;
|
||||
s32 lim;
|
||||
s32 lim2;
|
||||
|
||||
s0 = ((u8 **)D_8018E8DC)[*(s16 *)(param + 0xFC)];
|
||||
|
||||
/* gte_SetRotMatrix(&D_800AF648); gte_SetTransMatrix(&D_800AF648); */
|
||||
__asm__ volatile(
|
||||
"lui $2,%%hi(D_800AF648);addiu $2,$2,%%lo(D_800AF648);"
|
||||
"lw $12,0($2);lw $13,4($2);ctc2 $12,$0;ctc2 $13,$1;"
|
||||
"lw $12,8($2);lw $13,12($2);lw $14,16($2);"
|
||||
"ctc2 $12,$2;ctc2 $13,$3;ctc2 $14,$4;"
|
||||
"lw $12,20($2);lw $13,24($2);ctc2 $12,$5;"
|
||||
"lw $14,28($2);ctc2 $13,$6;ctc2 $14,$7"
|
||||
: : : "$12", "$13", "$14", "$2", "memory");
|
||||
gte_SetRotMatrix(m);
|
||||
gte_SetTransMatrix(m);
|
||||
|
||||
func_80015978(param + 4, (s32 *)buf);
|
||||
|
||||
/* gte_ldv0(buf); gte_rtps(); gte_stsxy(buf); */
|
||||
__asm__ volatile("lwc2 $0,0(%0);lwc2 $1,4(%0);nop;nop;rtps;swc2 $14,0(%0)"
|
||||
: : "r"(buf) : "memory");
|
||||
/* gte_stflg(&buf[2]); */
|
||||
gte_stflg(buf + 2);
|
||||
func_80015978(param + 4, (s32 *)w.v);
|
||||
gte_ldv0(w.v);
|
||||
gte_rtps();
|
||||
gte_stsxy(w.v);
|
||||
gte_stflg(&w.flag);
|
||||
|
||||
lim = (D_800AF7BC >> 1) + 0x20;
|
||||
x = (int)(s16)buf[0];
|
||||
if (x <= -lim) goto done;
|
||||
if (x >= lim) goto done;
|
||||
__asm__ volatile("" : : "r"(x)); /* keep $v1 live: see LEVER above */ // !FAKE: keepalive — NEEDED DIFFERS (P36 rung B tus8)
|
||||
|
||||
lim = (D_800AF7BE >> 1) + 0x20;
|
||||
x = (int)(s16)((s16 *)buf)[1];
|
||||
if (x <= -lim) goto done;
|
||||
if (x >= lim) goto done;
|
||||
__asm__ volatile("" : : "r"(x)); /* keep $v1 live: see LEVER above */ // !FAKE: keepalive — NEEDED DIFFERS (P36 rung B tus8)
|
||||
|
||||
if ((int)buf[2] < 0) goto done;
|
||||
|
||||
v0 = *(s32 *)(param + 0x1C);
|
||||
if (v0 != 0) { v0--; goto store; }
|
||||
|
||||
if (*(s16 *)(s0 + 6) != 0xFF) {
|
||||
do {
|
||||
func_80183168((u8 *)param, s0);
|
||||
s0 += 8;
|
||||
} while (*(s16 *)(s0 + 6) != 0xFF);
|
||||
if (w.v[0] > -lim && w.v[0] < lim) {
|
||||
lim2 = (D_800AF7BE >> 1) + 0x20;
|
||||
if (w.v[1] > -lim2 && w.v[1] < lim2 && w.flag >= 0) {
|
||||
if (*(s32 *)(param + 0x1C) == 0) {
|
||||
while (*(s16 *)(s0 + 6) != 0xFF) {
|
||||
func_80183168((u8 *)param, s0);
|
||||
s0 += 8;
|
||||
}
|
||||
*(s32 *)(param + 0x1C) = *(s32 *)(param + 0xDC);
|
||||
}
|
||||
*(s32 *)(param + 0x1C) -= 1;
|
||||
}
|
||||
}
|
||||
v0 = *(s32 *)(param + 0xDC);
|
||||
*(s32 *)(param + 0x1C) = v0;
|
||||
v0 = *(volatile s32 *)(param + 0x1C);
|
||||
v0--;
|
||||
store:
|
||||
*(s32 *)(param + 0x1C) = v0;
|
||||
done:
|
||||
func_801831FC(param);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user