phase-36: S104 s104_e12 — func_80182560 banked at 0 through the whole-object gate + propagated — la lever → 0: a named derived pointer q = p - 7 (find_best_addr keeps a REG address, cse.c:2656-2721)

This commit is contained in:
Drew T
2026-09-11 02:22:26 -06:00
parent 9a075c8159
commit cf2f8b444c
11 changed files with 697 additions and 181 deletions
@@ -0,0 +1,258 @@
void func_8017E35C(s32 arg0)
{
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern u8 D_800A6610[];
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern u8 *D_800A5E60;
typedef struct { u32 w0, w1, w2; } Prim;
typedef struct { u8 b[8]; } V8;
DVec35C tmpxy[4];
SVec35C box[8];
SVec35C sxy[8];
V8 vbuf[3];
V8 vdbuf;
Mtx35C mtx;
struct { long otz, flag, opz, sz0, sz1, sz2, sz3; } g;
s32 lim;
s32 j;
u32 i;
u8 *pkt;
Prim *prim;
u32 nprim;
u8 *vtx;
s32 nparts;
Part35C *part;
u32 ot;
u32 w;
s32 code;
u8 *va, *vb, *vc, *vd;
u32 wx, wy, wz, zh;
s16 my, mny, mx, mn;
s32 xa32, xb32, t32;
s32 xmn1, xmx1, xmn2, xmx2;
s32 mnc, mxc;
s32 za, zb, d, oz;
u32 *tp;
u32 uvw;
if (*(s32 *)arg0 != 0) {
return;
}
lim = func_800491EC() + *(s32 *)(arg0 + 0x64);
func_800547D8(arg0 + 0x10, &mtx);
func_80052E38(&mtx);
pkt = D_800A5E60;
part = *(Part35C **)(arg0 + 0xC);
nparts = *(s32 *)(*(s32 *)(arg0 + 8) + 8);
vtx = *(u8 **)(*(s32 *)(arg0 + 8) + 0x10);
ot = (u32)&D_800A6610[(u16)D_800B9A02 << 14];
for (j = 0; j < nparts; j++, part++) {
wx = part->xx;
wy = part->yy;
wz = part->zz;
mn = wx;
mx = wx >> 16;
mny = wy;
my = wy >> 16;
zh = wz >> 16;
box[0].vx = mn; box[0].vy = mny; box[0].vz = wz;
box[1].vx = mx; box[1].vy = mny; box[1].vz = wz;
box[2].vx = mn; box[2].vy = mny; box[2].vz = zh;
box[3].vx = mx; box[3].vy = mny; box[3].vz = zh;
gte_ldv3c(&box[0]);
gte_rtpt();
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
gte_ldv0(&box[3]);
gte_rtps();
box[4].vx = mn; box[4].vy = my; box[4].vz = wz;
box[5].vx = mx; box[5].vy = my; box[5].vz = wz;
box[6].vx = mn; box[6].vy = my; box[6].vz = zh;
box[7].vx = mx; box[7].vy = my; box[7].vz = zh;
gte_stsxy(&sxy[3]);
gte_ldv3c(&box[4]);
gte_rtpt();
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
gte_ldv0(&box[7]);
gte_rtps();
gte_stsxy(&sxy[7]);
gte_stszotz(&g.otz);
if (lim >= g.otz) {
xa32 = sxy[0].vx;
xb32 = sxy[1].vx;
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
t32 = sxy[2].vx;
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
t32 = sxy[3].vx;
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
xa32 = sxy[4].vx;
xb32 = sxy[5].vx;
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
t32 = sxy[6].vx;
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
t32 = sxy[7].vx;
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
mnc = xmn1;
if (xmn2 < xmn1) mnc = xmn2;
mxc = xmx1;
if (mxc < xmx2) mxc = xmx2;
if ((s16)mxc >= -0xA0 && (s16)mnc < 0xA1) {
xa32 = sxy[0].vy;
xb32 = sxy[1].vy;
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
t32 = sxy[2].vy;
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
t32 = sxy[3].vy;
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
xa32 = sxy[4].vy;
xb32 = sxy[5].vy;
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
t32 = sxy[6].vy;
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
t32 = sxy[7].vy;
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
mnc = xmn1;
if (xmn2 < xmn1) mnc = xmn2;
mxc = xmx1;
if (mxc < xmx2) mxc = xmx2;
if ((s16)mxc >= -0x6E && (s16)mnc < 0x6F) {
prim = (Prim *)part->prim;
nprim = part->nprim;
for (i = 0; i < nprim; i++, prim++) {
w = prim->w1;
va = vtx + (w & 0xFFFF);
vb = vtx + (w >> 16);
w = prim->w2;
vc = vtx + (w & 0xFFFF);
w = w >> 16;
vbuf[0] = *(V8 *)va;
vbuf[1] = *(V8 *)vb;
vbuf[2] = *(V8 *)vc;
gte_ldv3c(vbuf);
gte_rtpt();
gte_stflg(&g.flag);
if (!(g.flag & 0x7F85E000)) {
gte_nclip();
code = w & 7;
vd = vtx + (w & 0xFFF8);
gte_stopz(&g.opz);
if (g.opz > 0) {
switch (code) {
case 6:
case 7:
/* ---------------- TRI (FT3) ---------------- */
gte_stsxy3_ft3(pkt);
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
if (((Ft3_35C *)pkt)->x0 > ((Ft3_35C *)pkt)->x1) {
mx = ((Ft3_35C *)pkt)->x0; mn = ((Ft3_35C *)pkt)->x1;
} else {
mn = ((Ft3_35C *)pkt)->x0; mx = ((Ft3_35C *)pkt)->x1;
}
if (((Ft3_35C *)pkt)->x2 > mx) mx = ((Ft3_35C *)pkt)->x2;
else if (((Ft3_35C *)pkt)->x2 < mn) mn = ((Ft3_35C *)pkt)->x2;
if (mx >= -0xA0 && mn < 0xA1) {
if (((Ft3_35C *)pkt)->y0 > ((Ft3_35C *)pkt)->y1) {
my = ((Ft3_35C *)pkt)->y0; mny = ((Ft3_35C *)pkt)->y1;
} else {
mny = ((Ft3_35C *)pkt)->y0; my = ((Ft3_35C *)pkt)->y1;
}
if (((Ft3_35C *)pkt)->y2 > my) my = ((Ft3_35C *)pkt)->y2;
else if (((Ft3_35C *)pkt)->y2 < mny) mny = ((Ft3_35C *)pkt)->y2;
if (my >= -0x6E && mny < 0x6F) {
u32 *otp;
if (g.sz0 > g.sz1) { za = g.sz0; if (za < g.sz2) za = g.sz2; g.opz = za; }
else { za = g.sz1; if (za < g.sz2) za = g.sz2; g.opz = za; }
if (code == 7) g.opz = za + 0x50;
oz = g.opz;
d = oz - 400;
if (d < 0) d = 0;
d = (d >> 8) << 22;
tp = (u32 *)prim->w0;
((Ft3_35C *)pkt)->rgbc = tp[0];
((Ft3_35C *)pkt)->uvc0 = tp[1] + d;
((Ft3_35C *)pkt)->uvp1 = tp[2];
((Ft3_35C *)pkt)->uv2 = tp[3];
otp = (u32 *)(((oz >> 2) << 2) + ot);
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
pkt += 0x28;
}
}
break;
case 2:
case 3:
/* ---------------- QUAD (FT4) ---------------- */
gte_stsxy3c(&tmpxy[0]);
vdbuf = *(V8 *)vd;
gte_ldv0(&vdbuf);
gte_rtps();
if (tmpxy[0].vx > tmpxy[1].vx) { mx = tmpxy[0].vx; mn = tmpxy[1].vx; }
else { mn = tmpxy[0].vx; mx = tmpxy[1].vx; }
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
if (tmpxy[0].vy > tmpxy[1].vy) { my = tmpxy[0].vy; mny = tmpxy[1].vy; }
else { mny = tmpxy[0].vy; my = tmpxy[1].vy; }
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
gte_stflg(&g.flag);
if (!(g.flag & 0x7F85E000)) {
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
gte_stsxy((long *)&((Ft4_35C *)pkt)->x3);
if (((Ft4_35C *)pkt)->x3 < mn) mn = ((Ft4_35C *)pkt)->x3;
else if (mx < ((Ft4_35C *)pkt)->x3) mx = ((Ft4_35C *)pkt)->x3;
if (mx >= -0xA0 && mn < 0xA1) {
if (((Ft4_35C *)pkt)->y3 < mny) mny = ((Ft4_35C *)pkt)->y3;
else if (my < ((Ft4_35C *)pkt)->y3) my = ((Ft4_35C *)pkt)->y3;
if (my >= -0x6E && mny < 0x6F) {
u32 *otp;
zb = g.sz2;
if (zb < g.sz3) zb = g.sz3;
za = g.sz0;
if (za < g.sz1) za = g.sz1;
if (za < zb) za = zb;
g.opz = za;
if (code == 3) g.opz = za + 0x50;
oz = g.opz;
d = oz - 400;
if (d < 0) d = 0;
d = (d >> 8) << 22;
*(u32 *)&((Ft4_35C *)pkt)->x0 = *(u32 *)&tmpxy[0];
*(u32 *)&((Ft4_35C *)pkt)->x1 = *(u32 *)&tmpxy[1];
*(u32 *)&((Ft4_35C *)pkt)->x2 = *(u32 *)&tmpxy[2];
tp = (u32 *)prim->w0;
((Ft4_35C *)pkt)->rgbc = tp[0];
((Ft4_35C *)pkt)->uvc0 = tp[1] + d;
((Ft4_35C *)pkt)->uvp1 = tp[2];
uvw = tp[3];
((Ft4_35C *)pkt)->uv2 = uvw;
((Ft4_35C *)pkt)->uv3 = uvw >> 16;
otp = (u32 *)(((oz >> 2) << 2) + ot);
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
pkt += 0x28;
}
}
}
break;
}
}
}
}
}
}
}
}
D_800A5E60 = pkt;
}
@@ -0,0 +1,67 @@
# func_8017E35C (ov_SC06_000_jr_8017AE2C.c) — e12, P36 T7 S104
**Score: 58 (sweep best 48) -> 0, zero levers.** The `__asm__ __volatile__ ("" :: "r" (nparts))` keepalive is deleted;
ONE statement moved: `g.opz = za;` is written at the end of BOTH arms of the TRI (FT3) depth-max if/else instead of once
after it. Not a signature change (the keepalive is mid-function, on `nparts`, not a `v0` return keepalive).
## (a) Residual
Register-only (plus the spill/reload shape that follows): `nparts` and `&vbuf` swap between `$fp` and a stack slot
(target: nparts in `$fp`, `&vbuf` spilled to 0x108 and reloaded as `lw s4,264(sp)` before the `lwc2`s; free: the
reverse), and `&g.flag`/`&g.opz` (sp+236/sp+240) swap `$s5`/`$s6`. Count 720 vs 719 only because of the spill reload.
## (b) Pass and decision (PROVEN: scratch/dumps_free, dumps_tree, dumps_body; .lreg "used N times across L insns")
global.c `allocno_compare` (gcc-2.7.2 global.c:586-607): priority = `(int)(floor_log2(refs)*refs/live * 10000)`, ties by
allocno number. The four contenders are all live across the WHOLE outer loop:
| pseudo | what | refs | live free -> body | priority free -> body |
|---|---|---|---|---|
| r80 | nparts | 4 | 554 -> 555 | 144 -> 144 |
| r224 | &vbuf (loop-hoisted) | 4 | 551 -> 552 | 145 -> **144** (tie, r80 first) |
| r241 | &g.flag | 7 | 550 -> 551 | 254 -> 254 |
| r243 | &g.opz | 7 | 549 -> 550 | 255 -> **254** (tie, r241 first) |
The INTEGER truncation of the priority does it: one more insn inside the loop (live length +1 for every loop-live pseudo,
sched.c:3846-3861 recomputes lengths over the scheduled insns, :4946-4947 stores them) makes both pairs tie, and the tie
goes to the lower allocno. `.greg` order line: free `… 243 241 82 224 80 73`, body `… 241 243 82 80 224 73` = the tree's.
The keepalive worked the same way (its asm insn is the +1; its +2 refs on nparts are incidental). Diagnostic on bytes:
one empty `asm("")` anywhere in the loop nest -> 0; two -> 58; five -> 0 — exactly the arithmetic (k in {1,5,9,…}).
The +1 insn has to vanish from the output: the duplicated `g.opz = za;` store is a common TAIL of the two arms, which the
post-reload cross-jump pass re-merges (toplev.c:3142 `jump_optimize (insns, 1, 1, 0)`, `find_cross_jump` jump.c:2371) —
the target already shows the original's cross-jump of this same if/else (`j 3c70` into the shared
`if (za < g.sz2) za = g.sz2` tail). Pre-reload the loop is one insn longer; the bytes keep one store.
## (c) Move
```c
if (g.sz0 > g.sz1) { za = g.sz0; if (za < g.sz2) za = g.sz2; g.opz = za; }
else { za = g.sz1; if (za < g.sz2) za = g.sz2; g.opz = za; }
if (code == 7) g.opz = za + 0x50;
```
## (d) Generator proposal
When a keepalive/empty-asm lever's only effect is a global-alloc ORDER flip between loop-live pseudos whose integer
`allocno_compare` priorities differ by one unit, compute the live-length shifts k that tie them (all loop-live pseudos
shift together) and try source moves that add k pre-reload insns the post-reload cross-jump deletes: copy the statement
that FOLLOWS an if/else join into the end of both arms (and the inverse, hoist a duplicated arm tail out, for negative k).
## (e) What did not work (bytes)
~110 single spellings, all 58 or worse unless they change the insn count: declaration/statement reorders of nparts
(its birth cannot move far enough — the entry test `blez nparts` pins it; -2 at most, the tie needs -3), `continue`
forms, nested ifs, inlining the min/max temps, else-if splits (43-56, 718-719 ins), s16 cull extents (68-98), align-2
vertex types (58, same bytes — `SVec35C vbuf[3]` would be an equally-good spelling of the V8 copies). The FT4
depth-max as an if/else (`if (g.sz2 < g.sz3) zb = g.sz3; else zb = g.sz2;` and 23 other combinations) reaches 2: it also
adds the +1 insn (a copy) but the copy is not tied, so a real `move` remains.
## (f) Method
The allocation table (step 4) plus the integer truncation in allocno_compare was the whole story; the cheap diagnostic
that settled it was inserting an EMPTY asm at several places and counts (1/2/5) — a position-independent +k test the
method does not list. The "duplicate the join statement into both arms" move is S103 c6's cross-jump fact turned around
(c6 raised refs; here the duplicate raises the loop's insn count).
## (g) Structs
`g` already is a body-local struct; typing `vtx`/`prim` records or the vertex buffer (`SVec35C`) does not touch the
decision (58 unchanged, tested with three vertex types). The lever is an allocation-order tie, not an aliasing question.
## Stale header
The TU's comment block above the function ("THE FIVE DECISIVE LEVERS", item 5) describes the keepalive; with this body
item 5's first half is obsolete (the giv-order half, `prim` before `nprim`, still holds).
@@ -0,0 +1,21 @@
void func_80182560(void *arg0)
{
extern s32 D_801B20E0;
extern s32 D_8019FD8C;
extern s32 D_801AEBCC;
extern s32 D_801AEC60;
extern s16 D_801AEAFE;
extern void func_8017EF68(s32 a0, s32 a1, s32 a2);
s32 *p;
s32 *q;
p = &D_801AEBCC;
q = p - 7;
*q = 0;
*p = D_801AEAFE;
func_8017EF68((s32)&D_801B20E0, (s32)&D_8019FD8C, (s32)q);
if (D_801AEC60 != 0) {
((struct { u8 pad[2]; u16 f; } *)arg0)->f += 1;
}
}
@@ -0,0 +1,48 @@
# func_80182560 (ov_SC06_000_jr_8017AE2C.c) — e12, P36 T7 S104
**Score: 2 -> 0, zero levers** (the `la` asm deleted; plain C).
## (a) Residual
COUNT, one extra instruction: the store `p[-7] = 0` came out absolute (`lui at,%hi(D_801AEBCC-28); sw zero,%lo(..)(at)`)
where the target stores through the register that already holds `&D_801AEBCC` (`sw zero,-28(a2)`).
## (b) Pass and decision (PROVEN on the .cse dump, scratch/dumps_free vs scratch/dumps_c1)
cse1, `find_best_addr` (tools/reference/gcc-2.7.2/cse.c:2622):
- free text: the store's address is `(plus (reg p) -28)`, not a REG, so `fold_rtx` runs FIRST (cse.c:2662-2664); `p`'s
constant equivalent `(symbol_ref D_801AEBCC)` is substituted and the sum folds to `(const (plus sym -28))`. That is a
CONSTANT address (cheap-cost comparison never happens) -> the assembler macro `lui at; sw`. `.cse` insn 14 shows it.
- closed text: the store's address is `(reg q)` with `q = p - 7`. A REG address is not folded; the lookup of `q`'s class
finds `(plus (reg p) -28)` with the SAME `ADDRESS_COST` as a REG (1, config/mips/mips.h:2895, mips.c:1652-1653) and a
higher rtx cost, which the tie-break PREFERS (cse.c:2711-2721, "(p->cost + 1) >> 1 > best_rtx_cost"); the symbolic
constant costs 2 (mips.c:1631, SYMBOL_REF_FLAG clear under -G0) and loses. `.cse` insn 17 shows
`(mem (plus (reg 73) -28))`; `q` survives only as the call argument, which sched puts in the `jal` delay slot
(`addiu a2,a2,-28`) exactly as the target.
## (c) The move
Name the derived pointer: `p = &D_801AEBCC; q = p - 7; *q = 0; *p = D_801AEAFE; func_8017EF68(.., .., (s32)q);`
(The `(s32)&D_801AEBCC` cast on the pointer assignment in body_free.c also dropped — cosmetic.)
## (d) Generator proposal
When an `la` lever feeds a pointer `p` that is then indexed with a NEGATIVE/nonzero constant (`p[-k] = ..`) and the free
residual is `lui at; sw/lw ..(at)` in place of `sw ..,-4k(reg)`, introduce `q = p - k` before the first such access and
rewrite `p[-k]` (and every later `p - k` expression) as `*q` / `q` — find_best_addr turns a REG address back into
`reg+const` but folds a written `reg+const` to a constant.
## (e) What did not work
Nothing else was needed: the first hypothesis scored 0. The sweep's R7/R9/R10/R18 moves all stay at 2 because none of
them changes the address from `(plus p K)` to a REG.
## (f) Method
Step 1 (whole objdump, count first) settled it in one look: 30 vs 31, one `lui at` — a folded constant address, not a
register problem. The residual_moves table has no row for "REG address un-folded by find_best_addr's tie-break"; it is
worth one (it is the inverse of S103 c11's re-association, and the same function: find_best_addr).
## (g) Structs
A struct would NOT help here and could hurt: `S.f0 = 0; S.f7 = x; f(&S)` gives constant addresses (CONSTANT_ADDRESS_P,
cse.c:2656, never replaced by a register) -> two `lui at` stores. The target's shape needs a POINTER variable whose
first access is through a REG address; a struct POINTER `q` (`q->f0 = 0; q->f7 = ..`) would put the base on `&f0`
(0x801AEBB0), not on 0x801AEBCC as the target has it. Not tested on bytes (the plain-pointer text already closes).
## Copies
Same TU: func_8018270C closes with the identical text (its own pack). See scratch/copies.txt for the la-lever
copies elsewhere.
@@ -0,0 +1,23 @@
void func_8018270C(void) {
extern s32 D_801B20E0;
extern s32 D_8019FD8C;
extern s32 D_80197B60;
extern s32 D_801AEC08;
extern s32 D_801AEBCC;
extern s32 D_801AEC60;
extern s16 D_801AEAFE;
extern void func_8013373C(s16 a0);
extern void func_8017EF68(s32 a0, s32 a1, s32 a2);
s32 *p;
s32 *q;
p = &D_801AEBCC;
q = p - 7;
*q = 0;
*p = D_801AEAFE;
func_8017EF68((s32)&D_801B20E0, (s32)&D_8019FD8C, (s32)q);
func_8017EF68((s32)&D_801B20E0, (s32)&D_80197B60, (s32)&D_801AEC08);
D_801AEC60 = 2;
func_8013373C(0);
}
@@ -0,0 +1,27 @@
# func_8018270C (ov_SC06_000_jr_8017AE2C.c) — e12, P36 T7 S104
**Score: 2 -> 0, zero levers** (the `la` asm deleted; plain C).
Identical mechanism to func_80182560 (full text in ../ov_SC06_000__func_80182560/mechanism.md, dumps proven there).
## (a) Residual
COUNT +1: `p[-7] = 0` stored absolute (`lui at; sw zero,-28(at)`) instead of `sw zero,-28(v0)` through `&D_801AEBCC`.
## (b) Pass and decision
cse1 `find_best_addr` (gcc-2.7.2 cse.c:2622): a non-REG address `(plus (reg p) -28)` is `fold_rtx`ed first
(cse.c:2662-2664) into the constant `(const (plus D_801AEBCC -28))`; a REG address `(reg q)` is not folded and the
equal-ADDRESS_COST tie-break (cse.c:2711-2721; mips.c:1652 = 1 = REG) swaps in `(plus (reg p) -28)` instead.
## (c) Move
`q = p - 7; *q = 0; *p = D_801AEAFE; func_8017EF68(.., .., (s32)q);`
## (d) Generator proposal
When an `la`-lever pointer is accessed at a nonzero constant index and the free residual is an extra `lui at` on that
access, introduce `q = p + k` and access `*q` (pass `q` wherever `p + k` was written).
## (e) Did not work / (f) method
First try closed; the sweep's block/swap/bystander moves cannot turn a `reg+const` address into a REG.
## (g) Structs
No: struct field accesses on the global give constant addresses (cse.c:2656 never replaces them) — the opposite of the
target. The close needs the pointer variable.
@@ -0,0 +1,13 @@
void func_80184A68(void) {
u8 *p;
u8 *q;
u8 *r;
p = &D_801AECC5;
do { q = p - 1; r = p + 1; } while (0); // !FAKE: do-while — its NOTE_INSN_LOOP_END ends cse1's block before the uses (cse.c:8054-8056, ignored after_loop), so cse2 not cse1 rewrites *q/*r to p-relative (find_best_addr cse.c:2711-2721) (P36 S104 e12 minimum-lever)
if (*p < 0xF8U) {
*p += 4;
*q += 6;
*r += 4;
}
}
@@ -0,0 +1,56 @@
# func_80184A68 (ov_SC06_000_jr_8017AE2C.c) — e12, P36 T7 S104
**Score: 9 -> 0.** Levers: 1 `asm` launder -> 0 asm, 1 marked `do { } while (0)` (step 8's allowed-but-marked construct).
NOT a strict plain-C close: every do-while-free spelling I found stays at 9 (see (e)).
## (a) Residual
COUNT, 20 vs 16: the two neighbour-byte accesses `a0[-1]`, `a0[1]` (load and store each) come out ABSOLUTE
(`lui v0; lbu v0,%lo(D_801AECC5-1)(v0)`, `lui at; sb v0,..(at)`, same for +1) where the target addresses them off the
register that already holds `&D_801AECC5` (`lbu v0,-1(a0)`, `sb v1,1(a0)`). Four `lui`s extra.
## (b) Pass and decision (PROVEN on dumps: scratch/dumps_c1 = derived pointers without the barrier, scratch/dumps_body)
Two cse passes, one function (`find_best_addr`, gcc-2.7.2 cse.c:2622):
1. A written `p[-1]` is `(plus (reg p) -1)`: not a REG, so `fold_rtx` runs first (cse.c:2662-2664) and folds it with p's
known constant into `(const (plus D_801AECC5 -1))` — a CONSTANT address, never replaced again (cse.c:2656).
2. A REG address `(mem (reg q))`, `q = p - 1`, is not folded; the lookup of q's class finds `(plus (reg p) -1)` at the
SAME address cost as a REG (1: mips.h:2895, mips.c:1652-1653) and a higher rtx cost, which the tie-break prefers
(cse.c:2711-2721); the symbolic constant (cost 2, mips.c:1631) loses. That gives `-1(a0)`.
3. But if the rewrite in 2. happens in **cse1**, `q` is dead afterwards (flow deletes its set) and **cse2** sees the
written `(plus (reg p) -1)` again and folds it as in 1. (dumps_c1: `.cse` has `(plus 72 -1)`, `.cse2` has
`(const (plus D_801AECC5 -1))`). In func_80182560 the same rewrite survives cse2 only because `q` is ALSO the call
argument, so `q`'s set is still live and its class still holds `(plus p -28)` in cse2.
4. The close: cse1 must NOT see `q`'s equivalence, cse2 must. The only boundary that differs between the two passes is
`NOTE_INSN_LOOP_END`: `cse_end_of_basic_block` ends the block there only when `! after_loop` (cse.c:8054-8056).
A `do { q = p - 1; r = p + 1; } while (0);` puts a LOOP_END between the sets and the uses: `.cse` processes
"block from 2 to 25" then "29 to 57" and leaves `(mem (reg 73))`; `.cse2` processes "2 to 57" as one block and
rewrites to `(mem (plus (reg 72) -1))`; flow then deletes the dead `q`/`r` sets. Byte-identical.
## (c) Moves
- name the neighbour pointers: `q = p - 1; r = p + 1;` and access `*q`, `*r` instead of `p[-1]`, `p[1]`;
- put their definitions in a `do { … } while (0)` (marked `// !FAKE: do-while — …`), exactly the shape of a
`#define`-style macro body in the original source. Both variants (definitions inside the do-while, or an empty
do-while after them, or p's set inside too — scratch/c3, c4, c5) score 0.
## (d) Generator proposal
When a launder/`la` pointer's constant-offset accesses come out absolute (`lui` + `%lo(SYM±k)`) and the target uses
`±k(reg)`: introduce one derived pointer per offset (`q = p + k`, access `*q`); if the derived pointer has another
live use (a call argument) that alone closes it, else wrap the derived-pointer definitions in a marked
`do { } while (0)` so cse1 stops at LOOP_END and only cse2 does the REG->`reg+k` rewrite.
## (e) What did not work (bytes)
- derived pointers alone (scratch/c1 top-level, c2 declared inside the if): 9 — cse1 rewrites, q dies, cse2 folds.
- body_free.c and the sweep's R7/R9 moves: 9 (they keep `p[k]`, which fold_rtx folds in either pass).
- A structured/goto rewrite does not apply: a CODE_LABEL ends the block in BOTH passes; only LOOP_END differs.
- I found no plain-C construct other than a loop that puts LOOP_END in the insn stream; an always-false/always-true
test that cse1 folds away (so jump deletes a label before cse2) would be the refused invented-condition kind.
## (f) Method
Counting first (20 vs 16, four `lui`s) + reading func_80182560's close gave the idea; the `.cse` vs `.cse2` dumps were
decisive — the residual alone cannot show that the fold happens in the SECOND cse pass. The sibling func_801851CC
(same shape, `-=`) is FOLDED in the target (absolute CC4/CC6), which fits: the original spelled the two differently.
## (g) Structs
A struct over the three bytes (`struct { u8 b, g, r; } D_801AECC4`) does not help: field accesses on a global are
constant addresses (cse.c:2656), and through a pointer `s = &D_801AECC4` the base register would hold CC4 with offsets
0/1/2 — the target's base is CC5 with -1/0/+1. The deciding fact is the cse1/cse2 boundary, not aliasing, so the
expr.c:4568 aggregate channel is not in play. Not tested on bytes.
+177 -177
View File
@@ -1,7 +1,7 @@
{
"head": "c16813709",
"head": "9a075c815",
"stamp": "15956e4a96c4",
"generated": "2026-09-11 02:15",
"generated": "2026-09-11 02:22",
"aliases": [
"main",
"ov_SC03_014",
@@ -21,206 +21,206 @@
"main": {
"objects": 85,
"identical": 85,
"seconds": 6.379999999999999,
"mean_s": 0.075
"seconds": 6.564999999999999,
"mean_s": 0.077
},
"ov_SC03_014": {
"objects": 32,
"identical": 32,
"seconds": 4.468000000000001,
"mean_s": 0.14
"seconds": 4.3549999999999995,
"mean_s": 0.136
},
"ov_SC03_015": {
"objects": 32,
"identical": 32,
"seconds": 4.294999999999999,
"mean_s": 0.134
"seconds": 4.36,
"mean_s": 0.136
},
"ov_SC04_011": {
"objects": 28,
"identical": 28,
"seconds": 3.6829999999999994,
"mean_s": 0.132
"seconds": 3.7150000000000003,
"mean_s": 0.133
}
},
"per_object_seconds": {
"build/src/800.o": 0.674,
"build/src/800_b.o": 0.101,
"build/src/800_b_2.o": 0.294,
"build/src/800_b_o0a.o": 0.068,
"build/src/800_c.o": 0.192,
"build/src/800b2.o": 0.078,
"build/src/apicard1.o": 0.057,
"build/src/apicard2.o": 0.056,
"build/src/apicard3.o": 0.059,
"build/src/apicard4.o": 0.068,
"build/src/apicard5.o": 0.09,
"build/src/apicard6.o": 0.07,
"build/src/apicard7.o": 0.059,
"build/src/boot.o": 0.093,
"build/src/gap.o": 0.063,
"build/src/libapi1.o": 0.061,
"build/src/libapi2.o": 0.054,
"build/src/libc2_1.o": 0.06,
"build/src/libc2_2.o": 0.06,
"build/src/libcd1.o": 0.07,
"build/src/libcd2.o": 0.061,
"build/src/libetc.o": 0.061,
"build/src/libgpu.o": 0.049,
"build/src/libgpu2.o": 0.073,
"build/src/libgs1.o": 0.06,
"build/src/libgs2.o": 0.064,
"build/src/libgs3.o": 0.051,
"build/src/libgs4.o": 0.062,
"build/src/libgs5.o": 0.061,
"build/src/libgs6.o": 0.068,
"build/src/libgs7.o": 0.054,
"build/src/libgs8.o": 0.059,
"build/src/libgte1.o": 0.059,
"build/src/libgte10.o": 0.064,
"build/src/libgte11.o": 0.054,
"build/src/libgte12.o": 0.062,
"build/src/libgte13.o": 0.065,
"build/src/libgte14.o": 0.057,
"build/src/libgte15.o": 0.066,
"build/src/libgte16.o": 0.064,
"build/src/libgte17.o": 0.064,
"build/src/libgte18.o": 0.064,
"build/src/libgte19.o": 0.064,
"build/src/libgte2.o": 0.06,
"build/src/libgte20.o": 0.064,
"build/src/libgte21.o": 0.06,
"build/src/libgte22.o": 0.065,
"build/src/libgte23.o": 0.059,
"build/src/libgte24.o": 0.063,
"build/src/libgte25.o": 0.069,
"build/src/libgte26.o": 0.054,
"build/src/libgte27.o": 0.057,
"build/src/libgte28.o": 0.063,
"build/src/libgte29.o": 0.064,
"build/src/libgte3.o": 0.058,
"build/src/libgte30.o": 0.06,
"build/src/libgte4.o": 0.061,
"build/src/libgte5.o": 0.058,
"build/src/libgte6.o": 0.069,
"build/src/libgte7.o": 0.061,
"build/src/libgte8.o": 0.069,
"build/src/libgte9.o": 0.056,
"build/src/800.o": 0.734,
"build/src/800_b.o": 0.075,
"build/src/800_b_2.o": 0.304,
"build/src/800_b_o0a.o": 0.09,
"build/src/800_c.o": 0.184,
"build/src/800b2.o": 0.08,
"build/src/apicard1.o": 0.066,
"build/src/apicard2.o": 0.098,
"build/src/apicard3.o": 0.081,
"build/src/apicard4.o": 0.084,
"build/src/apicard5.o": 0.079,
"build/src/apicard6.o": 0.059,
"build/src/apicard7.o": 0.087,
"build/src/boot.o": 0.065,
"build/src/gap.o": 0.071,
"build/src/libapi1.o": 0.083,
"build/src/libapi2.o": 0.057,
"build/src/libc2_1.o": 0.063,
"build/src/libc2_2.o": 0.055,
"build/src/libcd1.o": 0.067,
"build/src/libcd2.o": 0.063,
"build/src/libetc.o": 0.069,
"build/src/libgpu.o": 0.062,
"build/src/libgpu2.o": 0.078,
"build/src/libgs1.o": 0.058,
"build/src/libgs2.o": 0.067,
"build/src/libgs3.o": 0.046,
"build/src/libgs4.o": 0.093,
"build/src/libgs5.o": 0.047,
"build/src/libgs6.o": 0.075,
"build/src/libgs7.o": 0.06,
"build/src/libgs8.o": 0.061,
"build/src/libgte1.o": 0.061,
"build/src/libgte10.o": 0.066,
"build/src/libgte11.o": 0.066,
"build/src/libgte12.o": 0.056,
"build/src/libgte13.o": 0.062,
"build/src/libgte14.o": 0.059,
"build/src/libgte15.o": 0.062,
"build/src/libgte16.o": 0.063,
"build/src/libgte17.o": 0.061,
"build/src/libgte18.o": 0.056,
"build/src/libgte19.o": 0.059,
"build/src/libgte2.o": 0.056,
"build/src/libgte20.o": 0.058,
"build/src/libgte21.o": 0.064,
"build/src/libgte22.o": 0.063,
"build/src/libgte23.o": 0.062,
"build/src/libgte24.o": 0.053,
"build/src/libgte25.o": 0.06,
"build/src/libgte26.o": 0.07,
"build/src/libgte27.o": 0.059,
"build/src/libgte28.o": 0.06,
"build/src/libgte29.o": 0.063,
"build/src/libgte3.o": 0.053,
"build/src/libgte30.o": 0.063,
"build/src/libgte4.o": 0.06,
"build/src/libgte5.o": 0.061,
"build/src/libgte6.o": 0.072,
"build/src/libgte7.o": 0.064,
"build/src/libgte8.o": 0.061,
"build/src/libgte9.o": 0.061,
"build/src/libmcrd1.o": 0.073,
"build/src/libmcrd2.o": 0.06,
"build/src/libpad1.o": 0.065,
"build/src/libpad2.o": 0.069,
"build/src/sgap.o": 0.062,
"build/src/sgap_2.o": 0.056,
"build/src/sgap_3.o": 0.066,
"build/src/sgap_4.o": 0.062,
"build/src/sgap_5.o": 0.056,
"build/src/libmcrd2.o": 0.054,
"build/src/libpad1.o": 0.06,
"build/src/libpad2.o": 0.065,
"build/src/sgap.o": 0.06,
"build/src/sgap_2.o": 0.064,
"build/src/sgap_3.o": 0.064,
"build/src/sgap_4.o": 0.07,
"build/src/sgap_5.o": 0.063,
"build/src/sgap_6.o": 0.068,
"build/src/sgap_8.o": 0.068,
"build/src/snd1.o": 0.07,
"build/src/snd1.o": 0.06,
"build/src/snd10.o": 0.062,
"build/src/snd11.o": 0.062,
"build/src/snd12.o": 0.06,
"build/src/snd2.o": 0.075,
"build/src/snd3.o": 0.062,
"build/src/snd4.o": 0.062,
"build/src/snd5.o": 0.06,
"build/src/snd6.o": 0.064,
"build/src/snd7.o": 0.064,
"build/src/snd8.o": 0.06,
"build/src/snd9.o": 0.071,
"build/src/ov_SC03_014/ov_SC03_014.o": 0.118,
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.513,
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.362,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.059,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.055,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.122,
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.156,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.114,
"build/src/snd11.o": 0.058,
"build/src/snd12.o": 0.064,
"build/src/snd2.o": 0.068,
"build/src/snd3.o": 0.057,
"build/src/snd4.o": 0.065,
"build/src/snd5.o": 0.074,
"build/src/snd6.o": 0.063,
"build/src/snd7.o": 0.068,
"build/src/snd8.o": 0.059,
"build/src/snd9.o": 0.063,
"build/src/ov_SC03_014/ov_SC03_014.o": 0.115,
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.497,
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.367,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.054,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.069,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.127,
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.151,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.111,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.078,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.07,
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.181,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.068,
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.184,
"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.172,
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.088,
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.063,
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.169,
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.098,
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.06,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.064,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.089,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.458,
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.254,
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.099,
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.202,
"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.095,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.064,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.163,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.181,
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.052,
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.237,
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.048,
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.059,
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.054,
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.068,
"build/src/ov_SC03_015/ov_SC03_015.o": 0.106,
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.48,
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.368,
"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.045,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.119,
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.137,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.098,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.069,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.083,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.412,
"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.09,
"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.096,
"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.146,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.171,
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.046,
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.259,
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.054,
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.048,
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.052,
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.059,
"build/src/ov_SC03_015/ov_SC03_015.o": 0.118,
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.485,
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.385,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.052,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.05,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.108,
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.151,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.111,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.072,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.058,
"build/src/ov_SC03_015/ov_SC03_015_jr_80140608.o": 0.17,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.067,
"build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.16,
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.096,
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.06,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.067,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.085,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.426,
"build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.247,
"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.2,
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.048,
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.091,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.067,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.156,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.061,
"build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.158,
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.087,
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.058,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.068,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.079,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.441,
"build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.232,
"build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.097,
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.197,
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.055,
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.1,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.061,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.152,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.191,
"build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.048,
"build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.265,
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.06,
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.052,
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.052,
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.069,
"build/src/ov_SC04_011/ov_SC04_011.o": 0.124,
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.398,
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.327,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.051,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.045,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.093,
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.148,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.099,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.077,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.063,
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.168,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.058,
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.155,
"build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.071,
"build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.059,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.067,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.082,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.348,
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.221,
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.091,
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.15,
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.056,
"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.06,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.091,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.404,
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.042,
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.053
"build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.052,
"build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.273,
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.059,
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.055,
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.058,
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.066,
"build/src/ov_SC04_011/ov_SC04_011.o": 0.121,
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.414,
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.322,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.05,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.053,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.111,
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.14,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.105,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.075,
"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.169,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.065,
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.152,
"build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.086,
"build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.063,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.064,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.094,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.333,
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.212,
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.095,
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.166,
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.047,
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.085,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.057,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.086,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.4,
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.04,
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.049
},
"ok": true,
"seconds": 2.2
File diff suppressed because one or more lines are too long
+6 -4
View File
@@ -7227,11 +7227,13 @@ void func_80182560(void *arg0)
extern void func_8017EF68(s32 a0, s32 a1, s32 a2);
s32 *p;
__asm__("la %0, D_801AEBCC" : "=r"(p)); // !FAKE: instruction la — NEEDED DIFFERS (P36 rung B tus7)
s32 *q;
p = &D_801AEBCC;
q = p - 7;
p[-7] = 0;
p[0] = D_801AEAFE;
func_8017EF68((s32)&D_801B20E0, (s32)&D_8019FD8C, (s32)(p - 7));
*q = 0;
*p = D_801AEAFE;
func_8017EF68((s32)&D_801B20E0, (s32)&D_8019FD8C, (s32)q);
if (D_801AEC60 != 0) {
((struct { u8 pad[2]; u16 f; } *)arg0)->f += 1;
}