From cf2f8b444cfb92aabb9a1b22d90491bad4b75619 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Fri, 11 Sep 2026 02:22:26 -0600 Subject: [PATCH] =?UTF-8?q?phase-36:=20S104=20s104=5Fe12=20=E2=80=94=20fun?= =?UTF-8?q?c=5F80182560=20banked=20at=200=20through=20the=20whole-object?= =?UTF-8?q?=20gate=20+=20propagated=20=E2=80=94=20la=20lever=20=E2=86=92?= =?UTF-8?q?=200:=20a=20named=20derived=20pointer=20q=20=3D=20p=20-=207=20(?= =?UTF-8?q?find=5Fbest=5Faddr=20keeps=20a=20REG=20address,=20cse.c:2656-27?= =?UTF-8?q?21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agents/ov_SC06_000__func_8017E35C/body.c | 258 +++++++++++++ .../ov_SC06_000__func_8017E35C/mechanism.md | 67 ++++ .../agents/ov_SC06_000__func_80182560/body.c | 21 ++ .../ov_SC06_000__func_80182560/mechanism.md | 48 +++ .../agents/ov_SC06_000__func_8018270C/body.c | 23 ++ .../ov_SC06_000__func_8018270C/mechanism.md | 27 ++ .../agents/ov_SC06_000__func_80184A68/body.c | 13 + .../ov_SC06_000__func_80184A68/mechanism.md | 56 +++ .run/P36/delever/calibration.json | 354 +++++++++--------- .run/P36/delever/ledger.jsonl | 1 + src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c | 10 +- 11 files changed, 697 insertions(+), 181 deletions(-) create mode 100644 .run/P36/agents/ov_SC06_000__func_8017E35C/body.c create mode 100644 .run/P36/agents/ov_SC06_000__func_8017E35C/mechanism.md create mode 100644 .run/P36/agents/ov_SC06_000__func_80182560/body.c create mode 100644 .run/P36/agents/ov_SC06_000__func_80182560/mechanism.md create mode 100644 .run/P36/agents/ov_SC06_000__func_8018270C/body.c create mode 100644 .run/P36/agents/ov_SC06_000__func_8018270C/mechanism.md create mode 100644 .run/P36/agents/ov_SC06_000__func_80184A68/body.c create mode 100644 .run/P36/agents/ov_SC06_000__func_80184A68/mechanism.md diff --git a/.run/P36/agents/ov_SC06_000__func_8017E35C/body.c b/.run/P36/agents/ov_SC06_000__func_8017E35C/body.c new file mode 100644 index 0000000000..8baff60295 --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_8017E35C/body.c @@ -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; +} diff --git a/.run/P36/agents/ov_SC06_000__func_8017E35C/mechanism.md b/.run/P36/agents/ov_SC06_000__func_8017E35C/mechanism.md new file mode 100644 index 0000000000..ca5937660e --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_8017E35C/mechanism.md @@ -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). diff --git a/.run/P36/agents/ov_SC06_000__func_80182560/body.c b/.run/P36/agents/ov_SC06_000__func_80182560/body.c new file mode 100644 index 0000000000..0e7c5fd46a --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_80182560/body.c @@ -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; + } +} diff --git a/.run/P36/agents/ov_SC06_000__func_80182560/mechanism.md b/.run/P36/agents/ov_SC06_000__func_80182560/mechanism.md new file mode 100644 index 0000000000..84b34ebcc6 --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_80182560/mechanism.md @@ -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. diff --git a/.run/P36/agents/ov_SC06_000__func_8018270C/body.c b/.run/P36/agents/ov_SC06_000__func_8018270C/body.c new file mode 100644 index 0000000000..5b213fe224 --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_8018270C/body.c @@ -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); +} diff --git a/.run/P36/agents/ov_SC06_000__func_8018270C/mechanism.md b/.run/P36/agents/ov_SC06_000__func_8018270C/mechanism.md new file mode 100644 index 0000000000..820ed5d348 --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_8018270C/mechanism.md @@ -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. diff --git a/.run/P36/agents/ov_SC06_000__func_80184A68/body.c b/.run/P36/agents/ov_SC06_000__func_80184A68/body.c new file mode 100644 index 0000000000..5d023774c6 --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_80184A68/body.c @@ -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; + } +} diff --git a/.run/P36/agents/ov_SC06_000__func_80184A68/mechanism.md b/.run/P36/agents/ov_SC06_000__func_80184A68/mechanism.md new file mode 100644 index 0000000000..0d36a443cc --- /dev/null +++ b/.run/P36/agents/ov_SC06_000__func_80184A68/mechanism.md @@ -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. diff --git a/.run/P36/delever/calibration.json b/.run/P36/delever/calibration.json index bc43c0bb6d..3d3df9b44b 100644 --- a/.run/P36/delever/calibration.json +++ b/.run/P36/delever/calibration.json @@ -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 diff --git a/.run/P36/delever/ledger.jsonl b/.run/P36/delever/ledger.jsonl index d21962a98c..56a9d04f99 100644 --- a/.run/P36/delever/ledger.jsonl +++ b/.run/P36/delever/ledger.jsonl @@ -29422,3 +29422,4 @@ {"ts": "2026-09-11 02:14:49", "label": "s104_e11", "rung": "E", "calib": {"head": "5c561effc", "stamp": "15956e4a96c4"}, "tu": "src/ov_SC04_011/ov_SC04_011_jr_8017D494.c", "fn": "func_801833D4", "addr": 2149069780, "aliases": null, "header": false, "includers": 0, "nhash_before": "53a80b2309991ab845ecee69f6e966dbea153eb0", "nhash_after": "7237bad38ed38d5ab7c303ba6f5ebb1663ec4ab9", "source": ".run/P36/agents/ov_SC04_011__func_801833D4/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.383, "objects": ["build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o"], "before_text": "s32 impl_801833D4(s32 a0, s32 a1)\n{\n /* $a1 is call-saved across func_801852BC/func_801853D0/func_80185648 until its one use\n far below; gcc puts its param->hardreg move in the branch's delay slot rather than up\n front. A plain local didn't reproduce that ordering vs. the s4=0 init -- pin it to $19\n ($s3, its natural hardreg) so the mid-fn scheduling matches (cookbook lever B/pin). */\n register s32 r1 __asm__(\"$19\") = a1; // !FAKE: pin $19 \u2014 NEEDED DIFFERS (P36 rung B t3_tus1)\n u16 s0;\n s32 obj;\n s32 s4;\n /* v[2..4] is a 3-word (vel-like x/y/z) struct passed by address to func_800484EC; the\n real local apparently has 2 leading words of other data ahead of it in the frame (its\n address-taken struct forces gcc to reserve stack starting 2 words earlier than our x\n field) -- v[0]/v[1] are unused padding needed only to reproduce the frame layout. */\n s32 v[5];\n\n s0 = D_801EFD20;\n s4 = 0;\n obj = aFC4C[s0];\n\n if (D_801EFD40 & 0x4) {\n func_801852BC(s0);\n func_801853D0(s0);\n func_80185648(s0);\n\n v[3] = 0;\n v[2] = 0;\n if (D_801EFD40 & 0x20) {\n v[4] = 0xFFD80000;\n } else {\n v[4] = 0xFFEC0000;\n }\n\n func_800484EC(*(s32 *)(obj + 0x20) + 0x34, (s32)&v[2], (s32)&v[2]);\n\n *(s32 *)(obj + 0x4) += v[2];\n *(s32 *)(obj + 0x8) += v[3];\n *(s32 *)(obj + 0xC) += v[4];\n\n *(u16 *)(*(s32 *)(obj + 0x20) + 0x14) =\n *(u16 *)(*(s32 *)(obj + 0x20) + 0x14) + r1;\n func_80183BF0(a0);\n\n *(u16 *)(*(s32 *)(obj + 0x20) + 0x10) =\n *(u16 *)(a0 + 0xFE) + *(u16 *)(a0 + 0x102);\n\n if (func_801836D4((void *)a0, (void *)obj) != 0) {\n s4 = 1;\n } else {\n if (D_801EFD40 & 0x20) {\n s0 = 0x40;\n } else {\n s0 = 0x20;\n }\n func_80185960(*(s16 *)(a0 + 0x106), (u16 *)(*(s32 *)(obj + 0x20) + 0x12), s0);\n func_80185960(*(s16 *)(a0 + 0x100), (u16 *)(a0 + 0xFE), s0);\n }\n }\n\n return s4;\n}\n", "after_text": "s32 impl_801833D4(s32 a0, s32 a1)\n{\n /* $a1 is call-saved across func_801852BC/func_801853D0/func_80185648 until its one use\n far below; gcc puts its param->hardreg move in the branch's delay slot rather than up\n front. The copy is a STATEMENT after the first load, not the declaration's initialiser:\n an initialiser sits right after the parameter copy, cse retargets that copy\n (cse.c:7454-7480) and sched1 never moves it (sched.c:3188-3205); after a real insn,\n combine folds the parameter copy into it and it is scheduled like any other insn\n (P36 S104 e11, the $19 pin removed). */\n s32 r1;\n u16 s0;\n s32 obj;\n s32 s4;\n /* v[2..4] is a 3-word (vel-like x/y/z) struct passed by address to func_800484EC; the\n real local apparently has 2 leading words of other data ahead of it in the frame (its\n address-taken struct forces gcc to reserve stack starting 2 words earlier than our x\n field) -- v[0]/v[1] are unused padding needed only to reproduce the frame layout. */\n s32 v[5];\n\n s0 = D_801EFD20;\n s4 = 0;\n r1 = a1;\n obj = aFC4C[s0];\n\n if (D_801EFD40 & 0x4) {\n func_801852BC(s0);\n func_801853D0(s0);\n func_80185648(s0);\n\n v[3] = 0;\n v[2] = 0;\n if (D_801EFD40 & 0x20) {\n v[4] = 0xFFD80000;\n } else {\n v[4] = 0xFFEC0000;\n }\n\n func_800484EC(*(s32 *)(obj + 0x20) + 0x34, (s32)&v[2], (s32)&v[2]);\n\n *(s32 *)(obj + 0x4) += v[2];\n *(s32 *)(obj + 0x8) += v[3];\n *(s32 *)(obj + 0xC) += v[4];\n\n *(u16 *)(*(s32 *)(obj + 0x20) + 0x14) =\n *(u16 *)(*(s32 *)(obj + 0x20) + 0x14) + r1;\n func_80183BF0(a0);\n\n *(u16 *)(*(s32 *)(obj + 0x20) + 0x10) =\n *(u16 *)(a0 + 0xFE) + *(u16 *)(a0 + 0x102);\n\n if (func_801836D4((void *)a0, (void *)obj) != 0) {\n s4 = 1;\n } else {\n if (D_801EFD40 & 0x20) {\n s0 = 0x40;\n } else {\n s0 = 0x20;\n }\n func_80185960(*(s16 *)(a0 + 0x106), (u16 *)(*(s32 *)(obj + 0x20) + 0x12), s0);\n func_80185960(*(s16 *)(a0 + 0x100), (u16 *)(a0 + 0xFE), s0);\n }\n }\n\n return s4;\n}\n"} {"ts": "2026-09-11 02:15:08", "label": "s104_e11", "rung": "E", "calib": {"head": "ef0c5858b", "stamp": "15956e4a96c4"}, "tu": "src/ov_SC04_011/ov_SC04_011_jr_8017D494.c", "fn": "func_80185214", "addr": 2149077524, "aliases": null, "header": false, "includers": 0, "nhash_before": "3a610935cbfa17f47edb4aac9e566bcadfa907f1", "nhash_after": "7991489631ed49c0259f333bcf27ca118a7a2fa8", "source": ".run/P36/agents/ov_SC04_011__func_80185214/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.383, "objects": ["build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o"], "before_text": "void func_80185214(s32 a0)\n{\n extern s32 D_801EFC48;\n extern u8 D_80194724[];\n extern void func_80185A18(s32 idx, s32 val);\n register s32 s0 __asm__(\"$16\"); // !FAKE: pin $16 \u2014 NEEDED DIFFERS (P36 rung B t3_tus1)\n s32 s1;\n s32 s2;\n s32 c;\n\n s2 = a0;\n s0 = *(s32 *)(D_801EFC48 + 0xCC);\n s1 = s0 + 0x28;\n do {\n c = *(u8 *)(s0 + 6);\n if (c < 0x15 && D_80194724[c] == 0) {\n func_80185A18(c, (s16)(*(u16 *)(s0 + 2) + s2));\n }\n if (*(s16 *)(s0 + 6) & 0x8000) {\n break;\n }\n s0 += 8;\n } while (s0 < s1);\n}\n", "after_text": "void func_80185214(s32 a0)\n{\n extern s32 D_801EFC48;\n extern u8 D_80194724[];\n extern void func_80185A18(s32 idx, s32 val);\n s32 p;\n s32 i;\n s32 c;\n\n p = *(s32 *)(D_801EFC48 + 0xCC);\n for (i = 0; i < 5; i++) {\n c = *(u8 *)(p + i * 8 + 6);\n if (c < 0x15 && D_80194724[c] == 0) {\n func_80185A18(c, (s16)(*(u16 *)(p + i * 8 + 2) + a0));\n }\n if (*(s16 *)(p + i * 8 + 6) & 0x8000) {\n break;\n }\n }\n}\n"} {"ts": "2026-09-11 02:15:26", "label": "s104_e11", "rung": "E", "calib": {"head": "c16813709", "stamp": "15956e4a96c4"}, "tu": "src/ov_SC04_011/ov_SC04_011_jr_8017D494.c", "fn": "func_80186020", "addr": 2149081120, "aliases": null, "header": false, "includers": 0, "nhash_before": "f5149a8b2501cac26293307bf99fa9427341289f", "nhash_after": "babf22e204f7c1e0eac00cc9de2d8f0fe99f6696", "source": ".run/P36/agents/ov_SC04_011__func_80186020/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.39, "objects": ["build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o"], "before_text": "void func_80186020(void *a0) {\n s32 p;\n u16 x;\n /* $v0 pin (cookbook \"register pin\" lever): without it sched1's birthing boost\n hands $v0 to the wrong temp and the two lhu's swap registers (residual 12). */\n register u16 y __asm__(\"$2\"); // !FAKE: pin $2 \u2014 NEEDED DIFFERS (P36 rung B t3_tus1)\n\n if ((D_801EFD40 & 2) != 0) {\n if ((s16)D_801EFD48 >= 0x120) {\n *(s16 *)&D_801EFD4C = -0x60;\n } else if ((s16)D_801EFD48 < -0x5F) {\n *(s16 *)&D_801EFD4C = 0x60;\n }\n x = D_801EFD48;\n y = D_801EFD4C;\n p = *(s32 *)((s32)a0 + 0x20);\n x = x + y;\n y = D_801EFD44;\n D_801EFD48 = x;\n y = y + x;\n *(u16 *)(p + 0x10) = y;\n } else {\n if ((D_801EFD40 & 1) != 0) {\n if ((s16)D_801EFD48 >= 0x120) {\n return;\n }\n y = (s16)D_801EFD48 + 0x60;\n } else {\n if ((s16)D_801EFD48 < -0x5F) {\n return;\n }\n y = (s16)D_801EFD48 - 0x60;\n }\n x = D_801EFD44;\n p = *(s32 *)((s32)a0 + 0x20);\n D_801EFD48 = y;\n x = x + y;\n *(u16 *)(p + 0x10) = x;\n }\n}\n", "after_text": "void func_80186020(void *a0) {\n s32 p;\n\n if ((D_801EFD40 & 2) != 0) {\n s32 a;\n s32 b;\n\n a = (s16)D_801EFD48;\n if (a >= 0x120) {\n *(s16 *)&D_801EFD4C = -0x60;\n } else if (a < -0x5F) {\n *(s16 *)&D_801EFD4C = 0x60;\n }\n a = D_801EFD48;\n b = D_801EFD4C;\n p = *(s32 *)((s32)a0 + 0x20);\n a = a + b;\n b = D_801EFD44;\n D_801EFD48 = a;\n b = b + a;\n *(u16 *)(p + 0x10) = b;\n } else {\n u16 x;\n u16 y;\n\n if ((D_801EFD40 & 1) != 0) {\n x = D_801EFD48;\n if ((s16)x >= 0x120) {\n return;\n }\n y = x + 0x60;\n } else {\n x = D_801EFD48;\n if ((s16)x < -0x5F) {\n return;\n }\n y = x - 0x60;\n }\n x = D_801EFD44;\n p = *(s32 *)((s32)a0 + 0x20);\n D_801EFD48 = y;\n x = x + y;\n *(u16 *)(p + 0x10) = x;\n }\n}\n"} +{"ts": "2026-09-11 02:22:25", "label": "s104_e12", "rung": "E", "calib": {"head": "9a075c815", "stamp": "15956e4a96c4"}, "tu": "src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c", "fn": "func_80182560", "addr": 2149066080, "aliases": null, "header": false, "includers": 0, "nhash_before": "a51e1771c803292f3d6aaaec35049832764d172b", "nhash_after": "e5bbd049e4c03172cade0e9604b6ca62962c5499", "source": ".run/P36/agents/ov_SC06_000__func_80182560/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.272, "objects": ["build/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.o"], "before_text": "void func_80182560(void *arg0)\n{\n extern s32 D_801B20E0;\n extern s32 D_8019FD8C;\n extern s32 D_801AEBCC;\n extern s32 D_801AEC60;\n extern s16 D_801AEAFE;\n extern void func_8017EF68(s32 a0, s32 a1, s32 a2);\n\n s32 *p;\n __asm__(\"la %0, D_801AEBCC\" : \"=r\"(p)); // !FAKE: instruction la \u2014 NEEDED DIFFERS (P36 rung B tus7)\n\n p[-7] = 0;\n p[0] = D_801AEAFE;\n func_8017EF68((s32)&D_801B20E0, (s32)&D_8019FD8C, (s32)(p - 7));\n if (D_801AEC60 != 0) {\n ((struct { u8 pad[2]; u16 f; } *)arg0)->f += 1;\n }\n}\n", "after_text": "void func_80182560(void *arg0)\n{\n extern s32 D_801B20E0;\n extern s32 D_8019FD8C;\n extern s32 D_801AEBCC;\n extern s32 D_801AEC60;\n extern s16 D_801AEAFE;\n extern void func_8017EF68(s32 a0, s32 a1, s32 a2);\n\n s32 *p;\n s32 *q;\n p = &D_801AEBCC;\n q = p - 7;\n\n *q = 0;\n *p = D_801AEAFE;\n func_8017EF68((s32)&D_801B20E0, (s32)&D_8019FD8C, (s32)q);\n if (D_801AEC60 != 0) {\n ((struct { u8 pad[2]; u16 f; } *)arg0)->f += 1;\n }\n}\n"} diff --git a/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c b/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c index 57454c372d..fa67762874 100644 --- a/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c +++ b/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c @@ -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; }