From c51e7d1711bf877ddb7ffee8eee80f631c26ea3c Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Fri, 11 Sep 2026 02:36:01 -0600 Subject: [PATCH] =?UTF-8?q?phase-36:=20S104=20s104=5Fe17=20=E2=80=94=20fun?= =?UTF-8?q?c=5F8018CC24=20banked=20at=200=20through=20the=20whole-object?= =?UTF-8?q?=20gate=20+=20propagated=20=E2=80=94=20$2=20pin=20=E2=86=92=200?= =?UTF-8?q?:=20every=20multi-death=20temp=20split=20at=20once=20(local-all?= =?UTF-8?q?oc.c:472;=20find=5Freg=20global.c:945-990)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agents/ov_SC04_011__func_8017E558/body.c | 55 +++ .../ov_SC04_011__func_8017E558/mechanism.md | 83 ++++ .../agents/ov_SC04_011__func_80188A30/body.c | 23 ++ .../ov_SC04_011__func_80188A30/mechanism.md | 54 +++ .../agents/ov_SC04_011__func_8018CC24/body.c | 24 ++ .../ov_SC04_011__func_8018CC24/mechanism.md | 56 +++ .../agents/ov_SC04_011__func_8018CCB8/body.c | 27 ++ .../ov_SC04_011__func_8018CCB8/mechanism.md | 35 ++ .run/P36/delever/calibration.json | 370 +++++++++--------- .run/P36/delever/ledger.jsonl | 1 + src/ov_SC04_011/ov_SC04_011_jr_8017D494.c | 44 +-- 11 files changed, 558 insertions(+), 214 deletions(-) create mode 100644 .run/P36/agents/ov_SC04_011__func_8017E558/body.c create mode 100644 .run/P36/agents/ov_SC04_011__func_8017E558/mechanism.md create mode 100644 .run/P36/agents/ov_SC04_011__func_80188A30/body.c create mode 100644 .run/P36/agents/ov_SC04_011__func_80188A30/mechanism.md create mode 100644 .run/P36/agents/ov_SC04_011__func_8018CC24/body.c create mode 100644 .run/P36/agents/ov_SC04_011__func_8018CC24/mechanism.md create mode 100644 .run/P36/agents/ov_SC04_011__func_8018CCB8/body.c create mode 100644 .run/P36/agents/ov_SC04_011__func_8018CCB8/mechanism.md diff --git a/.run/P36/agents/ov_SC04_011__func_8017E558/body.c b/.run/P36/agents/ov_SC04_011__func_8017E558/body.c new file mode 100644 index 000000000..8b293aa38 --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_8017E558/body.c @@ -0,0 +1,55 @@ +void func_8017E558(void *arg0) { + extern u8 D_801EEDC8[]; + s32 cnt2; + s32 i; + s32 j; + s32 base; + s32 p; + s32 vel; + s32 pos; + u16 life; + s32 f18; + + cnt2 = 0; + for (i = 0; i < 8; i++) { + base = (s32)&D_801EEDC8[i * 0x1D0]; + if (*(s16 *)(base) == 0) { + *(s32 *)(base + 0xC) = *(s32 *)(base + 0xC) + 0x10000; + } + for (j = 0; j < 16; j++) { + p = base + 0x10 + j * 0x1C; + switch (*(s16 *)(p)) { + case 0: + vel = *(s32 *)(p + 0xC) + *(s32 *)(p + 0x10); + pos = *(s32 *)(p + 0x14); + life = *(u16 *)(p + 2) - 1; + pos = pos + vel; + *(s32 *)(p + 0x14) = pos; + *(s32 *)(p + 0xC) = vel; + *(u16 *)(p + 2) = life; + if ((s16)life == -1) { + *(u16 *)(p) = *(u16 *)(p) + 1; + } + *(u16 *)(p + 4) = *(u16 *)(p + 4) + *(u16 *)(p + 6); + *(u16 *)(p + 0xA) = *(u16 *)(p + 0xA) + 0x10; + break; + case 1: + *(u16 *)(p + 4) = *(u16 *)(p + 4) + 0x80; + f18 = *(s32 *)(p + 0x18) - 8; + *(s32 *)(p + 0x18) = f18; + if (f18 < 0) { + *(s32 *)(p + 0x18) = 0; + *(u16 *)(p) = *(u16 *)(p) + 1; + } + break; + case 2: + cnt2 = cnt2 + 1; + break; + } + } + func_8017E6EC(arg0, base); + } + if (cnt2 == 0x80) { + ((void (*)(u8 *))func_80146C3C)(arg0); + } +} diff --git a/.run/P36/agents/ov_SC04_011__func_8017E558/mechanism.md b/.run/P36/agents/ov_SC04_011__func_8017E558/mechanism.md new file mode 100644 index 000000000..a35ba196f --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_8017E558/mechanism.md @@ -0,0 +1,83 @@ +# func_8017E558 (ov_SC04_011_jr_8017D494.c): mechanism (P36 T7 S104, agent e17) + +**Result: score 0 in plain C.** No pin, no asm, no added volatile. Levers go from 2 to 0 (the `$5` pin on `base` and the +`$2` pin on `sym`). Signature unchanged. **The same two moves close five copies in other TUs (10 more levers), all at 0**: +`scratch/copies/LIST.txt` lists them with their files (`func_8017D994` ov_SC03_105, `func_8017F278` ov_SC03_028, +`func_8017E1D4` ov_SC05_010, `func_8017E7E8` ov_SC07_002, `func_8017DDE0` ov_SC06_029). + +## (a) The residual in one sentence +Two defects stacked. First a COUNT one (99 vs 101): mine hoists `&D_801EEDC8` out of the outer loop and walks the group +pointer (`lui/addiu s0` before the loop, `addiu s0,s0,464`), where the target walks an OFFSET (`s1 += 464`) and rebuilds +the address every iteration (`lui v0; addiu v0; addu a1,s1,v0`). Under it, a REGISTER permutation of the four +caller-saved loop values: target base→`a1`, p→`a2`, the inner offset→`a3`, j→`t0`; mine gives p `a1` and base `t0`. + +## (b) The passes and the decisions (proven on the `-dL`/`.greg` dumps and bytes) +1. **loop.c keeps the symbol load in the loop only when its pseudo lives ONE insn.** `move_movables` hoists an invariant + only if `threshold * savings * lifetime >= insn_count` (`loop.c:1631`, threshold from `loop.c:532`). In the free body + the block-local `s32 sym = …;` is set, then the five-insn `i * 0x1D0` expansion runs, then the add: life 6, and the + `.loop` dump says `Insn 28: regno 83 (life 6), move-insn savings 1 moved to 296`. Once hoisted, `sym` is invariant and + `base = sym + i*464` is a giv (`Insn 40: giv … mult 464 add (reg/v:SI 83)`), reduced to a walked pointer (mine). + Written as ONE expression, `&D_801EEDC8[i * 0x1D0]`, the address is forced into a register right at the add: life 1, + `Insn 35: regno 89 (life 1), move-insn savings 1 not desirable`. It stays in the loop, is not invariant + (`n_times_set == 1`), so `simplify_giv_expr`'s REG case fails and `base` is NOT a giv. Only `i*464` is reduced + (`giv at 33 reduced to (reg:SI 135)` = `s1`). That is the target's count and shape (`scratch/v_a.c`, `v_c.c`: 101/101). +2. **The call takes `base` as its second argument.** `func_8017E6EC` is defined later in the TU as `(s32 a0, s32 a1)` and + its first act is `move s7,a1` (it reads `14(a1)`, `2(a1)`: the group record). The body called it with one argument + (the TU's no-prototype `extern void func_8017E6EC();` let it). Passing `base` adds the copy `(set (reg:SI 5) base)` + before the call. jump2 deletes it as a no-op once `base` sits in `a1`. global.c records the preference: the `.greg` + of `scratch/dumps_v_c2/` shows `r76 … prefers a1`. `find_reg`'s first pass skips registers that a conflicting allocno + prefers (`regs_someone_prefers`, built from the LATER conflicting allocnos' preferences at `global.c:864-880`, + applied at `global.c:945-953`), so `p` (r77, priority 98571, allocated first) passes over `a1` and + takes `a2`. The inner offset giv (r131) takes `a3`, `j` (r75) `t0`, and `base` gets its preferred `a1`. Dispositions: + `75 in 8 76 in 5 77 in 6 131 in 7`, exactly the target. + +## (c) The moves that closed it (joint; each alone scores worse) +```c + base = (s32)&D_801EEDC8[i * 0x1D0]; /* was: { s32 sym = (s32)D_801EEDC8; base = sym + i * 0x1D0; } */ + ... + func_8017E6EC(arg0, base); /* was: func_8017E6EC(arg0); the callee is (s32, s32) */ +``` +- Move 1 alone (`scratch/v_a.c`, `v_b.c`, `v_c.c`: the three one-expression spellings): 34, count right, registers wrong. +- Move 2 alone (`scratch/v_free2.c`): 56, worse than the start (53). +- Both: `v_a2.c` (`(s32)D_801EEDC8 + i * 0x1D0`), `v_b2.c` (`i * 0x1D0 + (s32)D_801EEDC8`), `v_c2.c` = `body.c`, and + `v_f2.c` (`(s32)((u8 *)D_801EEDC8 + i * 0x1D0)`): all 0. +- The offset split into its own statement (`base = i * 0x1D0; base += (s32)D_801EEDC8;`, `v_d2.c`/`v_e2.c`): 8, 102 ins. + A self-updating `base` is two sets, so it is no longer the single-expression shape. + +## (d) Generator proposals +- (count) When the target rebuilds a `lui/addiu` of a symbol INSIDE a loop and adds a walked offset (`addu rB,sOff,v0`) + but mine hoists the symbol and walks a pointer: fold every `T sym = &SYM; … x = sym + i*K;` into the one expression + `x = (s32)&SYM[i*K]` (and delete the temp). The symbol pseudo's lifetime must be 1 insn for `loop.c:1631` to refuse the + hoist. +- (register) When a call's callee is defined in the same TU with MORE parameters than the call passes (`extern void f();` + with no prototype, the definition `f(s32, s32)`), and the target has a loop-carried value sitting in the next argument + register at the call: pass that value as the missing argument. This is METHOD step 3's first bullet ("a dropped call + argument") with a way to find it: compare the callee's DEFINITION arity with the call. + +## (e) What did NOT work +The sweep's best was 27 (R6 inline sym + R7 do-while); R6 inline sym alone reached 34, the same as my move 1. No generator +adds a call argument whose value is not already the next argument register's source. That is why move 2 was never +reached. + +## (f) Where the method fell short +- The tree's own header (`src/…_jr_8017D494.c:3153-3155`) says "the no-prototype forward decl is required so the + 1-argument call site here does not become a 2-argument call". That is an old lever's reasoning, written as a law, and + it is wrong: the 2-argument call IS the original. The header is now stale (pins and the 1-arg claim), and so are the + matching comments in the five twins (e.g. ov_SC06_029's "is called here with one argument"). +- What found move 2 was the `.greg` table: base had priority 5322 against p's 98571, so no order move could put it + first. The only other way for `a1` to go to the lower allocno is a hard-register preference, and a preference for `a1` + is a call's second argument. The callee's objdump (`move s7,a1` as its first act) confirmed it. +- Count first (METHOD step 2) worked. The count gap was a loop.c hoist, not a missing insn of mine, and the `-dL` dump's + "moved to" / "not desirable" lines named it in one compile. + +## (g) Structs question +Partly. The TU already has the struct (`GroupRec_801EB5C8_8017E3B0`, 0x1D0 bytes, 16 `SubRec` of 0x1C at +0x10, +block-scope in `func_8017E3B0`), and two twins declare their symbol with it. With the struct array, `base = (s32)&D[i];` +closes too (proven on ov_SC03_028 and ov_SC06_029, `scratch/copies/`). So a struct gives the natural single-expression +spelling for move 1 for free. It does not give move 2: the call argument is an allocation preference, not a memory-order +channel. The inner loop's `p = base + 0x10 + j*0x1C` would be `&grp->subs[j]` in the structs phase. Not tested here, and +it could change the inner loop's giv shape (today `16 + 28j` is the reduced giv and `base +` it is not, because +`simplify_giv_expr` cannot add a REG invariant to a constant, `loop.c` PLUS/USE case). Test it on bytes before assuming. + +Files: `body.c` (score 0), `scratch/v_*.c` (the variants above with their scores), `scratch/dumps_{free,v_a,v_c2}/`, +`scratch/copies/` (the five twins' ported bodies, their tree text, `LIST.txt`, `port.py`), `scratch/try.sh`. diff --git a/.run/P36/agents/ov_SC04_011__func_80188A30/body.c b/.run/P36/agents/ov_SC04_011__func_80188A30/body.c new file mode 100644 index 000000000..fb85d95c8 --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_80188A30/body.c @@ -0,0 +1,23 @@ +s32 func_80188A30(s32 a0) { + extern u16 D_80194814; + extern u16 D_80194816; + extern u16 D_801F161E; + extern s16 D_80126B98; + s16 in[3]; + s16 out[3]; + + in[1] = 0; + in[0] = 0; + out[1] = 0; + out[0] = 0; + in[2] = D_80194814; + out[2] = D_80194816; + if (func_8012DEB8((s32)a0, (s32)in, (s32)out) != 0) { + D_80126B98 = 0x18; + if (*(s16 *)((s32)a0 + 0x106) == 0) { + u16 cnt = D_801F161E; + *(s16 *)((s32)a0 + 0x106) = 1; + D_801F161E = cnt + 1; + } + } +} diff --git a/.run/P36/agents/ov_SC04_011__func_80188A30/mechanism.md b/.run/P36/agents/ov_SC04_011__func_80188A30/mechanism.md new file mode 100644 index 000000000..862fe0e7b --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_80188A30/mechanism.md @@ -0,0 +1,54 @@ +# func_80188A30 (ov_SC04_011_jr_8017D494.c): mechanism (P36 T7 S104, agent e17) + +**Result: score 0 in plain C with a SIGNATURE change — PARKED.** The return type is `s32` instead of `void`, the body is the +lever-free `body_free.c` unchanged, and the function falls off the end (no `return` statement, like a K&R implicit-int +function). No pin, no asm, no added volatile. Levers go from 1 to 0 (the `"memory"` barrier at tree line 11065). +It needs the TU's later prototype changed too: line 13461 `extern void func_80188A30(s32 a0);` becomes +`extern s32 func_80188A30(s32 a0);`. The whole-TU candidate is `scratch/tu_ret.c` (scored WITHOUT `--body`: 0). Its only +caller, `func_8018C260` (line 13485, ignores the result), is also byte-identical under the new prototype (0). +`body.c` alone does NOT compile with `--body` (the unchanged `extern void` conflicts); score it with the whole TU. + +## (a) The residual in one sentence +One instruction missing (36 vs 37). The target leaves the delay slot of `beqz v0,` (the call-result test) +EMPTY (`nop`). Mine fills it with `li v0,24`, the first insn of the fall-through arm (`D_80126B98 = 0x18`). + +## (b) The pass and the decision (source read; proven on bytes) +reorg, `fill_eager_delay_slots` → `fill_slots_from_thread` (`reorg.c:3270-3380`). For a conditional branch it steals from +the fall-through thread only an insn that does not set anything live on the OPPOSITE thread (`reorg.c:3375`, +`! insn_sets_resource_p (trial, &opposite_needed, 1)`). The opposite thread is the jump target, the function end, so +`opposite_needed` comes from `mark_target_live_regs` (`:3293`), which returns `end_of_function_needs` there (`:2458`). +`init_resource_info` seeds that set with the return-value register when `current_function_return_rtx` is a REG +(`reorg.c:4274-4277`). In a `void` function it is not, `$v0` is dead at the epilogue, and `li v0,24` is stolen. In an +`s32` function `$v0` is live at the epilogue, `li v0,24` sets it, the steal is refused, and the slot stays `nop`. +This is cookbook §162f1 ("a non-void return type is observable in delay slots") exactly: `li v1,1` in the second +epilogue-bound `bnez` slot is still filled in both, because it does not set `$v0`. + +## (c) The move that closed it +`void func_80188A30(s32 a0)` → `s32 func_80188A30(s32 a0)` (and the extern at 13461). Nothing else. The function emits no +extra instruction: no path gains a `move v0,…`. + +## (d) Generator proposal +When the only residual is an EMPTY delay slot (`nop`) on a branch to the epilogue where mine fills it with an insn that +sets `$v0`, flip the function's return type from `void` to `s32` (and its prototypes in the TU); if a caller uses no result +the callers' bytes do not change (§162f1). This is a signature change, so the generator should emit it as a parked +candidate with the prototype edits listed. + +## (e) What did NOT work +- The sweep (R7 blocks, R9 swaps, R10 param copy, R18 bystanders): 2 on every move; no generator touches the return type. +- I know of no plain-C `void` spelling that reaches this (reasoned, not enumerated): in a void function `$v0` is not live at the end + (`current_function_return_rtx == 0`), and the fall-through's first insn is the constant load in every order the target + allows (the target's order is `li v0,24; lui at; sh`, the same as mine). The fallback, if the signature change is refused, + is the tree's body (1 marked barrier lever, the minimum). + +## (f) Where the method fell short +Nothing blocked. Reading the whole objdump (METHOD step 1) showed the missing insn is a `nop` in a slot mine fills with a +`$v0` write before an epilogue branch. That shape is already in the cookbook (§162f1, found by grepping +`end_of_function_needs`), but neither PROMPT nor METHOD lists "empty slot before the epilogue → return type". Add it to +METHOD step 3's list of what emits a missing instruction. + +## (g) Structs question +No. The decision is reorg's liveness at the function end, set by the return type. No memory access is involved. (`a0` is an +actor; `+0x106` is an s16 "already triggered" flag, and a struct would not change this.) + +Files: `body.c` (the `s32` definition), `scratch/tu_ret.c` (whole TU with the prototype changed: 0 for `func_80188A30` and +for its caller `func_8018C260`), `scratch/free.o` (the free body's object, 36 ins). diff --git a/.run/P36/agents/ov_SC04_011__func_8018CC24/body.c b/.run/P36/agents/ov_SC04_011__func_8018CC24/body.c new file mode 100644 index 000000000..43379b6f3 --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_8018CC24/body.c @@ -0,0 +1,24 @@ +void func_8018CC24(s32 arg0) { + s32 a0; + s32 a1; + u16 val; + + func_8012AD80(arg0); + + a0 = *(s32 *)(arg0 + 0x20); + *(u16 *)(a0 + 0x10) = *(u16 *)(a0 + 0x10) + (*(u16 *)(arg0 + 0x106)); + + a1 = *(s32 *)(arg0 + 0x20); + val = *(u16 *)(arg0 + 0x108); + *(u16 *)(a1 + 0x14) = *(u16 *)(a1 + 0x14) + val; + + if ((*(s32 *)(arg0 + 0x1C) & 0x3) == 0) { + func_8018A7E8(arg0); + } + + *(s32 *)(arg0 + 0x1C) = *(s32 *)(arg0 + 0x1C) + 1; + + if (*(s16 *)(arg0 + 0xA) >= -0x3FF) { + func_8012C218((void *)arg0); + } +} diff --git a/.run/P36/agents/ov_SC04_011__func_8018CC24/mechanism.md b/.run/P36/agents/ov_SC04_011__func_8018CC24/mechanism.md new file mode 100644 index 000000000..e5d32dafa --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_8018CC24/mechanism.md @@ -0,0 +1,56 @@ +# func_8018CC24 (ov_SC04_011_jr_8017D494.c): mechanism (P36 T7 S104, agent e17) + +**Result: score 0 in plain C, on the first `--try`.** No pin, no asm, no added volatile. Levers go from 1 to 0 (the `$2` +pin on `v0`). Signature unchanged. The same edit closes `func_8018CCB8` (the next function, same shape plus a `Blk8` +stack copy and a different callee); no copy of the class exists in another TU (grep of +`v1_sign = *(s16 *)(s0 + 0xA);` finds only these two). + +## (a) The residual in one sentence +Same count (37/37). A pure v0/v1 permutation: the decompiler variable `v0` (the field sums and the `+0x1C` counter) is in +`v1` in mine and in `v0` in the target, and `v1`/`v1_sign` take the other register. + +## (b) The pass and the decision (read on the `.lreg`/`.greg` dumps; proven on bytes) +- The free body REUSES `v0` for four values (two field sums, the `& 3` test's load, the counter) and `v1` for two. In the + `.lreg` of `scratch/dumps_free/`, `r75` (`v0`) "dies in 4 places" and `r74`/`r76` die in 2. local-alloc refuses a + pseudo that dies more than once (`local-alloc.c:472`), so all three become GLOBAL allocnos (`.greg` order `75 72 76 74`). +- global.c then takes them in priority order (`allocno_compare`, `global.c:594-610`). `r75` is first (35000) but it + CONFLICTS with hard `v0`: the local compare temps (`r82`, `r85`, `r77`, allocated to `v0` by local-alloc before global + runs) are live while `r75` is live, e.g. the `slti` of the final test is born before the counter's `sw`. `find_reg` + (`global.c:945-990`) therefore skips `v0` and gives `r75` `v1`; the later allocnos take `v0`. The pin forced `r75` into + `v0`. (`scratch/dumps_free/`, `tools/alloc_table.py free func_8018CC24 scratch`.) +- With one name per value every temp is born and dies in one block, local-alloc allocates it (`qty_compare`), and each + sum lands in `v0` next to the `v1` addend, exactly as the target and the lever-free sibling `func_8018CA04` have it. + +## (c) The move that closed it +One variable per value (S103 c1/c8, generator R23), applied to BOTH `v0` and `v1` at once. The delivered `body.c` is the +text of the lever-free same-TU sibling `func_8018CA04` (first entry of `related.txt`) with the `func_8012AD80` call moved +first (that is the only structural difference in the bytes): the sums written in place, +`*(u16 *)(a0 + 0x10) = *(u16 *)(a0 + 0x10) + *(u16 *)(arg0 + 0x106);`, the counter as +`*(s32 *)(arg0 + 0x1C) = *(s32 *)(arg0 + 0x1C) + 1;`, the test on `*(s16 *)(arg0 + 0xA)` directly. Also proven: +- `scratch/vA_split.c` (the free body with `x1,y1,x2,y2,c1,c2` as separate names, `s0 = a0` kept): 0. +- `scratch/vE_sharedptr.c` (the same with ONE pointer local reused for both `+0x20` loads): 0 — the pointer's reuse is + harmless, only the value temps matter. + +## (d) Generator proposal +When a register residual is a pure pair permutation and the `.lreg` shows two or more named temps that "die in N>1 +places", split EVERY such temp into one name per value in a single candidate (R23 splits one variable at a time and each +single split scores worse here: 10 and 19). + +## (e) What did NOT work (byte evidence) +- Splitting only `v0` (`scratch/vC_splitv0only.c`): 10 (a `v1`/`a0` swap remains). +- Splitting only `v1` (`scratch/vD_splitv1only.c`): 19. +- The sweep (R12 widths, R6/R8/R9/R10/R18, R4, R7): best 2, all COUNT-class. No generator produces the joint split. + +## (f) Where the method fell short +Nothing blocked. `related.txt`'s first entry (`func_8018CA04`, 3 shared callees) is the same function with the call in a +different place; reading it and matching the call position closed it on the first `--try`. The sweep should try +"port the top related.txt body" before any generator. + +## (g) Structs question +No. The lever was a local-alloc/global-alloc decision about register temps reused across statement groups; no memory +access order is involved. `arg0` is clearly an actor struct (`+0x0A` s16 y?, `+0x1C` frame counter, `+0x20` child +pointer with u16 fields at `+0x10`/`+0x14`, `+0x106`/`+0x108` u16 deltas), and a struct would make the text readable, +but it would not change this allocation. + +Files: `body.c` (score 0), `scratch/vA_split.c`, `scratch/vE_sharedptr.c` (0), `scratch/vC_splitv0only.c` (10), +`scratch/vD_splitv1only.c` (19), `scratch/dumps_free/`. diff --git a/.run/P36/agents/ov_SC04_011__func_8018CCB8/body.c b/.run/P36/agents/ov_SC04_011__func_8018CCB8/body.c new file mode 100644 index 000000000..0d5270043 --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_8018CCB8/body.c @@ -0,0 +1,27 @@ +void func_8018CCB8(s32 arg0) { + s32 a0; + s32 a1; + u16 val; + Blk8 sp10; + + sp10 = D_801ED9AC[0]; + + func_8012AD80(arg0); + + a0 = *(s32 *)(arg0 + 0x20); + *(u16 *)(a0 + 0x10) = *(u16 *)(a0 + 0x10) + (*(u16 *)(arg0 + 0x106)); + + a1 = *(s32 *)(arg0 + 0x20); + val = *(u16 *)(arg0 + 0x108); + *(u16 *)(a1 + 0x14) = *(u16 *)(a1 + 0x14) + val; + + if ((*(s32 *)(arg0 + 0x1C) & 0x3) == 0) { + func_8018B0B0((void *)arg0, &sp10, (void *)0, 8); + } + + *(s32 *)(arg0 + 0x1C) = *(s32 *)(arg0 + 0x1C) + 1; + + if (*(s16 *)(arg0 + 0xA) >= -0x77F) { + func_8012C218((void *)arg0); + } +} diff --git a/.run/P36/agents/ov_SC04_011__func_8018CCB8/mechanism.md b/.run/P36/agents/ov_SC04_011__func_8018CCB8/mechanism.md new file mode 100644 index 000000000..56dc61cb9 --- /dev/null +++ b/.run/P36/agents/ov_SC04_011__func_8018CCB8/mechanism.md @@ -0,0 +1,35 @@ +# func_8018CCB8 (ov_SC04_011_jr_8017D494.c): mechanism (P36 T7 S104, agent e17) + +**Result: score 0 in plain C, on the first `--try`.** No pin, no asm, no added volatile. Levers go from 1 to 0 (the `$2` +pin on `v0`). Signature unchanged. + +This is the same class as `func_8018CC24` (the function just before it): identical body plus a `Blk8 sp10 = D_801ED9AC[0];` +stack copy, `func_8018B0B0(arg0, &sp10, 0, 8)` in place of `func_8018A7E8`, and `-0x77F` in the last test. The full reading +is in `../ov_SC04_011__func_8018CC24/mechanism.md`; in short: + +## (a) The residual +Same count (53/53), a pure v0/v1 permutation (`v1->v0 x14, v0->v1 x8`). + +## (b) The pass +The free body reuses `v0` for four values and `v1` for two; each dies in several places, so local-alloc refuses them +(`local-alloc.c:472`) and they go global. The counter/sum pseudo conflicts with hard `v0` (the local compare temps sit in +`v0` while it is live), so `find_reg` (`global.c:945-990`) gives it `v1`. + +## (c) The move +One name per value, both variables at once. Delivered as the lever-free sibling text (`func_8018CA04`'s spelling, the call +first, the sums and the counter written in place). `scratch/vA_split.c` (free body, `x1,y1,x2,y2,c1,c2` split, `s0`/`ptr` +kept): 0 too. + +## (d) Generator proposal +Split every multi-death temp named in `.lreg` in ONE candidate (R23 splits one at a time). + +## (e) What did not work +The sweep: best 2 (R12 width `v0` s32->s16). Single splits were measured on the twin (10 and 19). + +## (f) Method +`related.txt`'s top entry gave the text. + +## (g) Structs question +No; a register-allocation decision about reused temps. `sp10` is an 8-byte struct copy (`Blk8`), already typed. + +Files: `body.c` (score 0), `scratch/vA_split.c` (0). diff --git a/.run/P36/delever/calibration.json b/.run/P36/delever/calibration.json index 4155d9c05..a7bc650ad 100644 --- a/.run/P36/delever/calibration.json +++ b/.run/P36/delever/calibration.json @@ -1,7 +1,7 @@ { - "head": "23f7c80df", + "head": "99355f672", "stamp": "15956e4a96c4", - "generated": "2026-09-11 02:34", + "generated": "2026-09-11 02:35", "aliases": [ "main", "ov_SC03_014", @@ -21,207 +21,207 @@ "main": { "objects": 85, "identical": 85, - "seconds": 6.543, - "mean_s": 0.077 + "seconds": 8.41, + "mean_s": 0.099 }, "ov_SC03_014": { "objects": 32, "identical": 32, - "seconds": 4.599, - "mean_s": 0.144 + "seconds": 5.496000000000001, + "mean_s": 0.172 }, "ov_SC03_015": { "objects": 32, "identical": 32, - "seconds": 4.349000000000001, - "mean_s": 0.136 + "seconds": 5.25, + "mean_s": 0.164 }, "ov_SC04_011": { "objects": 28, "identical": 28, - "seconds": 3.790000000000001, - "mean_s": 0.135 + "seconds": 4.578000000000001, + "mean_s": 0.164 } }, "per_object_seconds": { - "build/src/800.o": 0.729, - "build/src/800_b.o": 0.095, - "build/src/800_b_2.o": 0.264, - "build/src/800_b_o0a.o": 0.064, - "build/src/800_c.o": 0.195, - "build/src/800b2.o": 0.075, - "build/src/apicard1.o": 0.062, - "build/src/apicard2.o": 0.063, - "build/src/apicard3.o": 0.07, - "build/src/apicard4.o": 0.064, - "build/src/apicard5.o": 0.067, - "build/src/apicard6.o": 0.066, - "build/src/apicard7.o": 0.065, - "build/src/boot.o": 0.092, - "build/src/gap.o": 0.049, - "build/src/libapi1.o": 0.084, - "build/src/libapi2.o": 0.058, - "build/src/libc2_1.o": 0.066, - "build/src/libc2_2.o": 0.057, - "build/src/libcd1.o": 0.066, - "build/src/libcd2.o": 0.056, - "build/src/libetc.o": 0.061, - "build/src/libgpu.o": 0.051, - "build/src/libgpu2.o": 0.07, - "build/src/libgs1.o": 0.066, - "build/src/libgs2.o": 0.059, - "build/src/libgs3.o": 0.058, - "build/src/libgs4.o": 0.06, - "build/src/libgs5.o": 0.059, - "build/src/libgs6.o": 0.071, - "build/src/libgs7.o": 0.084, - "build/src/libgs8.o": 0.064, - "build/src/libgte1.o": 0.063, - "build/src/libgte10.o": 0.064, + "build/src/800.o": 0.865, + "build/src/800_b.o": 0.111, + "build/src/800_b_2.o": 0.376, + "build/src/800_b_o0a.o": 0.069, + "build/src/800_c.o": 0.226, + "build/src/800b2.o": 0.123, + "build/src/apicard1.o": 0.072, + "build/src/apicard2.o": 0.076, + "build/src/apicard3.o": 0.071, + "build/src/apicard4.o": 0.086, + "build/src/apicard5.o": 0.088, + "build/src/apicard6.o": 0.082, + "build/src/apicard7.o": 0.112, + "build/src/boot.o": 0.12, + "build/src/gap.o": 0.096, + "build/src/libapi1.o": 0.061, + "build/src/libapi2.o": 0.071, + "build/src/libc2_1.o": 0.093, + "build/src/libc2_2.o": 0.072, + "build/src/libcd1.o": 0.083, + "build/src/libcd2.o": 0.101, + "build/src/libetc.o": 0.093, + "build/src/libgpu.o": 0.077, + "build/src/libgpu2.o": 0.105, + "build/src/libgs1.o": 0.076, + "build/src/libgs2.o": 0.082, + "build/src/libgs3.o": 0.071, + "build/src/libgs4.o": 0.074, + "build/src/libgs5.o": 0.074, + "build/src/libgs6.o": 0.087, + "build/src/libgs7.o": 0.076, + "build/src/libgs8.o": 0.078, + "build/src/libgte1.o": 0.065, + "build/src/libgte10.o": 0.086, "build/src/libgte11.o": 0.069, - "build/src/libgte12.o": 0.061, - "build/src/libgte13.o": 0.065, - "build/src/libgte14.o": 0.077, - "build/src/libgte15.o": 0.055, - "build/src/libgte16.o": 0.054, - "build/src/libgte17.o": 0.067, - "build/src/libgte18.o": 0.062, - "build/src/libgte19.o": 0.062, - "build/src/libgte2.o": 0.064, - "build/src/libgte20.o": 0.067, - "build/src/libgte21.o": 0.06, - "build/src/libgte22.o": 0.068, - "build/src/libgte23.o": 0.057, - "build/src/libgte24.o": 0.065, - "build/src/libgte25.o": 0.064, - "build/src/libgte26.o": 0.068, - "build/src/libgte27.o": 0.06, - "build/src/libgte28.o": 0.063, - "build/src/libgte29.o": 0.067, - "build/src/libgte3.o": 0.051, - "build/src/libgte30.o": 0.06, - "build/src/libgte4.o": 0.061, - "build/src/libgte5.o": 0.077, - "build/src/libgte6.o": 0.062, - "build/src/libgte7.o": 0.072, - "build/src/libgte8.o": 0.06, - "build/src/libgte9.o": 0.056, - "build/src/libmcrd1.o": 0.07, - "build/src/libmcrd2.o": 0.063, + "build/src/libgte12.o": 0.098, + "build/src/libgte13.o": 0.072, + "build/src/libgte14.o": 0.089, + "build/src/libgte15.o": 0.123, + "build/src/libgte16.o": 0.077, + "build/src/libgte17.o": 0.092, + "build/src/libgte18.o": 0.082, + "build/src/libgte19.o": 0.092, + "build/src/libgte2.o": 0.082, + "build/src/libgte20.o": 0.092, + "build/src/libgte21.o": 0.071, + "build/src/libgte22.o": 0.078, + "build/src/libgte23.o": 0.071, + "build/src/libgte24.o": 0.072, + "build/src/libgte25.o": 0.111, + "build/src/libgte26.o": 0.1, + "build/src/libgte27.o": 0.083, + "build/src/libgte28.o": 0.073, + "build/src/libgte29.o": 0.094, + "build/src/libgte3.o": 0.1, + "build/src/libgte30.o": 0.067, + "build/src/libgte4.o": 0.076, + "build/src/libgte5.o": 0.073, + "build/src/libgte6.o": 0.074, + "build/src/libgte7.o": 0.08, + "build/src/libgte8.o": 0.07, + "build/src/libgte9.o": 0.089, + "build/src/libmcrd1.o": 0.091, + "build/src/libmcrd2.o": 0.111, "build/src/libpad1.o": 0.071, - "build/src/libpad2.o": 0.071, - "build/src/sgap.o": 0.077, - "build/src/sgap_2.o": 0.067, - "build/src/sgap_3.o": 0.059, - "build/src/sgap_4.o": 0.068, - "build/src/sgap_5.o": 0.058, - "build/src/sgap_6.o": 0.065, - "build/src/sgap_8.o": 0.067, - "build/src/snd1.o": 0.07, - "build/src/snd10.o": 0.062, - "build/src/snd11.o": 0.061, - "build/src/snd12.o": 0.061, - "build/src/snd2.o": 0.072, - "build/src/snd3.o": 0.064, - "build/src/snd4.o": 0.064, - "build/src/snd5.o": 0.065, - "build/src/snd6.o": 0.076, - "build/src/snd7.o": 0.069, - "build/src/snd8.o": 0.062, - "build/src/snd9.o": 0.07, - "build/src/ov_SC03_014/ov_SC03_014.o": 0.121, - "build/src/ov_SC03_014/ov_SC03_014_after.o": 0.54, - "build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.4, - "build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.057, - "build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.057, - "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.116, - "build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.081, - "build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.085, - "build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.175, - "build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.087, - "build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.179, - "build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.099, - "build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.066, - "build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.076, - "build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.092, - "build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.434, - "build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.248, - "build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.094, - "build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.183, - "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.097, - "build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.061, - "build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.164, - "build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.19, - "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.28, - "build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.054, - "build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.057, - "build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.058, - "build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.062, - "build/src/ov_SC03_015/ov_SC03_015.o": 0.116, - "build/src/ov_SC03_015/ov_SC03_015_after.o": 0.491, - "build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.362, - "build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.046, - "build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.047, - "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.138, - "build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.104, - "build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.069, - "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.171, - "build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.068, - "build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.151, - "build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.078, - "build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.056, - "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.094, - "build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.444, - "build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.248, - "build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.104, - "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.052, - "build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.093, - "build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.07, - "build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.165, - "build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.198, - "build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.049, - "build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.271, - "build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.054, - "build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.051, - "build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.048, + "build/src/libpad2.o": 0.083, + "build/src/sgap.o": 0.108, + "build/src/sgap_2.o": 0.081, + "build/src/sgap_3.o": 0.068, + "build/src/sgap_4.o": 0.11, + "build/src/sgap_5.o": 0.088, + "build/src/sgap_6.o": 0.093, + "build/src/sgap_8.o": 0.079, + "build/src/snd1.o": 0.081, + "build/src/snd10.o": 0.087, + "build/src/snd11.o": 0.085, + "build/src/snd12.o": 0.072, + "build/src/snd2.o": 0.108, + "build/src/snd3.o": 0.074, + "build/src/snd4.o": 0.085, + "build/src/snd5.o": 0.063, + "build/src/snd6.o": 0.079, + "build/src/snd7.o": 0.097, + "build/src/snd8.o": 0.071, + "build/src/snd9.o": 0.077, + "build/src/ov_SC03_014/ov_SC03_014.o": 0.175, + "build/src/ov_SC03_014/ov_SC03_014_after.o": 0.579, + "build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.448, + "build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.068, + "build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.114, + "build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.141, + "build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.198, + "build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.126, + "build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.112, + "build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.077, + "build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.2, + "build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.092, + "build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.226, + "build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.126, + "build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.077, + "build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.099, + "build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.099, + "build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.529, + "build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.299, + "build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.112, + "build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.238, + "build/src/ov_SC03_014/ov_SC03_014_jr_801789AC.o": 0.062, + "build/src/ov_SC03_014/ov_SC03_014_jr_80178D40.o": 0.128, + "build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.086, + "build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.199, + "build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.223, + "build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.062, + "build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.318, + "build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.066, + "build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.065, + "build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.063, + "build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.089, + "build/src/ov_SC03_015/ov_SC03_015.o": 0.138, + "build/src/ov_SC03_015/ov_SC03_015_after.o": 0.558, + "build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.437, + "build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.058, + "build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.066, + "build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.126, + "build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.155, + "build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.121, + "build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.103, + "build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.064, + "build/src/ov_SC03_015/ov_SC03_015_jr_80140608.o": 0.206, + "build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.085, + "build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.209, + "build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.099, + "build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.074, + "build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.075, + "build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.118, + "build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.528, + "build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.31, + "build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.122, + "build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.248, + "build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.065, + "build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.115, + "build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.076, + "build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.199, + "build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.256, + "build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.058, + "build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.309, + "build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.068, + "build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.067, + "build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.067, "build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.07, - "build/src/ov_SC04_011/ov_SC04_011.o": 0.125, - "build/src/ov_SC04_011/ov_SC04_011_after.o": 0.414, - "build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.335, - "build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.052, - "build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.047, - "build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.108, - "build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.15, - "build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.101, - "build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.072, - "build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.062, - "build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.161, - "build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.074, - "build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.165, - "build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.081, - "build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.067, - "build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.071, - "build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.099, - "build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.342, - "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.088, - "build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.153, - "build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.052, - "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.094, - "build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.414, - "build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.054, - "build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.055 + "build/src/ov_SC04_011/ov_SC04_011.o": 0.138, + "build/src/ov_SC04_011/ov_SC04_011_after.o": 0.475, + "build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.401, + "build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.062, + "build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.068, + "build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.139, + "build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.176, + "build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.135, + "build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.088, + "build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.099, + "build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.205, + "build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.094, + "build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.196, + "build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.1, + "build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.074, + "build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.081, + "build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.107, + "build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.401, + "build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.251, + "build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.107, + "build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.199, + "build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.071, + "build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.111, + "build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.084, + "build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.12, + "build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.466, + "build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.063, + "build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.067 }, "ok": true, - "seconds": 2.2 + "seconds": 2.6 } diff --git a/.run/P36/delever/ledger.jsonl b/.run/P36/delever/ledger.jsonl index 3d619924d..d9c4e2447 100644 --- a/.run/P36/delever/ledger.jsonl +++ b/.run/P36/delever/ledger.jsonl @@ -29437,3 +29437,4 @@ {"ts": "2026-09-11 02:33:39", "label": "s104_e16", "rung": "E", "calib": {"head": "75cb21c7a", "stamp": "15956e4a96c4"}, "tu": "src/800_b_2.c", "fn": "func_80031B7C", "addr": 2147687292, "aliases": null, "header": false, "includers": 0, "nhash_before": "8f624471b712925ea0ce21cf7c81daca74f2a648", "nhash_after": "5e673e4ddb1b5d50721a3283be3f74f19c7997bb", "source": ".run/P36/agents/main__func_80031B7C/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.173, "objects": ["build/src/800_b_2.o"], "before_text": "void func_80031B7C() {\n s32 a0 = 0;\n u8 a2 = 1;\n u16 a1 = 0x7FFF;\n register u8 *v1 asm(\"$3\"); // !FAKE: pin $3 \u2014 NEEDED DIFFERS (P36 rung B tus9)\n\n v1 = D_800A49D2;\n\n do {\n if (v1[4] && !v1[2] && v1[3]) {\n v1[2] = a2;\n *(u16 *)v1 = a1;\n }\n v1 += 0x54;\n a0++;\n } while (a0 < 8);\n}\n", "after_text": "void func_80031B7C(void) {\n s32 i = 0;\n s32 one = 1;\n s32 full = 0x7FFF;\n u8 *p = D_800A49D2;\n\nloop:\n if (p[4] && !p[2] && p[3]) {\n p[2] = one;\n *(u16 *)p = full;\n }\n p += 0x54;\n i++;\n if (i < 8) goto loop;\n}\n"} {"ts": "2026-09-11 02:33:56", "label": "s104_e16", "rung": "E", "calib": {"head": "2b6f30ed7", "stamp": "15956e4a96c4"}, "tu": "src/800_b_2.c", "fn": "func_800336A8", "addr": 2147694248, "aliases": null, "header": false, "includers": 0, "nhash_before": "db30363bd1e9d49ed72a11334cab07cfa3e26f9a", "nhash_after": "44f377d040ba1dcacdee3fba3ddd7694958c6ae5", "source": ".run/P36/agents/main__func_800336A8/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.175, "objects": ["build/src/800_b_2.o"], "before_text": "void func_800336A8(Req336A8 *arg)\n{\n Chan336A8 *ch;\n Voice336A8 *vo;\n u16 *p;\n const u16 *q;\n u32 m;\n u32 n;\n u32 v;\n s32 i;\n s32 j;\n\n for (i = 0; i < 8; i++) {\n if (arg->unk3A[i] == 0) {\n continue;\n }\n ch = (Chan336A8 *)(D_800A4988 + i * 0x54);\n vo = (Voice336A8 *)(D_800A4988 + 0x2A0 + i * 0x48);\n vo->unk00 = D_80073140[ch->unk0A];\n m = ch->unk34;\n m = D_8006AA30[m];\n m = m * *(s16 *)(D_800A4988 + 0x572);\n m = m >> 7;\n if (arg->unk16 != 0) {\n m = m * arg->unk18;\n m = m >> 15;\n }\n p = arg->unk1C;\n for (j = 2; j >= 0; j--, p += 4) {\n m = m * *p;\n m = m >> 14;\n }\n n = ch->unk35;\n if (n == 0) {\n v = m;\n vo->unk0A = v;\n vo->unk08 = v;\n } else {\n if (arg->unk38 != 0) {\n n += arg->unk38;\n if (n >= 0x42) {\n n -= 0x40;\n if (n >= 0x80) {\n n = 0x7F;\n }\n } else {\n n = 1;\n }\n }\n ch->unk52 = n;\n if (D_800A4F19 != 0) {\n /* zero-byte dbr fence: ASM_INPUT stops reorg's fallthrough trial scan\n * (stop_search_p), so the beqz above keeps its `nop` delay slot. */\n __asm__ __volatile__(\"\"); // !FAKE: barrier \u2014 NEEDED DIFFERS (P36 rung B tus9)\n v = (m * D_8007319E[n]) >> 14;\n vo->unk0A = v;\n q = D_8007319E + 1;\n v = (m * q[0x7F - n]) >> 14;\n vo->unk08 = v;\n } else {\n v = (m * D_8007321E) >> 14;\n vo->unk0A = v;\n vo->unk08 = v;\n }\n }\n vo->unk40 = ch->unk0A;\n if (vo->unk44 != 0) {\n vo->unk04 |= 3;\n } else {\n vo->unk04 = 3;\n vo->unk44 = 1;\n }\n }\n}\n", "after_text": "void func_800336A8(Req336A8 *arg)\n{\n Chan336A8 *ch;\n Voice336A8 *vo;\n u16 *p;\n const u16 *q;\n u32 m;\n u32 n;\n u32 v;\n s32 i;\n s32 j;\n\n for (i = 0; i < 8; i++) {\n if (arg->unk3A[i] == 0) {\n continue;\n }\n ch = (Chan336A8 *)(D_800A4988 + i * 0x54);\n vo = (Voice336A8 *)(D_800A4988 + 0x2A0 + i * 0x48);\n vo->unk00 = D_80073140[ch->unk0A];\n m = ch->unk34;\n m = D_8006AA30[m];\n m = m * *(s16 *)(D_800A4988 + 0x572);\n m = m >> 7;\n if (arg->unk16 != 0) {\n m = m * arg->unk18;\n m = m >> 15;\n }\n p = arg->unk1C;\n for (j = 2; j >= 0; j--, p += 4) {\n m = m * *p;\n m = m >> 14;\n }\n n = ch->unk35;\n if (n != 0) {\n if (arg->unk38 != 0) {\n n += arg->unk38;\n if (n >= 0x42) {\n n -= 0x40;\n if (n >= 0x80) {\n n = 0x7F;\n }\n } else {\n n = 1;\n }\n }\n ch->unk52 = n;\n if (D_800A4F19 != 0) {\n v = (m * D_8007319E[n]) >> 14;\n vo->unk0A = v;\n q = D_8007319E + 1;\n v = (m * q[0x7F - n]) >> 14;\n vo->unk08 = v;\n } else {\n v = (m * D_8007321E) >> 14;\n vo->unk0A = v;\n vo->unk08 = v;\n }\n } else {\n v = m;\n vo->unk0A = v;\n vo->unk08 = v;\n }\n vo->unk40 = ch->unk0A;\n if (vo->unk44 != 0) {\n vo->unk04 |= 3;\n } else {\n vo->unk04 = 3;\n vo->unk44 = 1;\n }\n }\n}\n"} {"ts": "2026-09-11 02:34:13", "label": "s104_e16", "rung": "E", "calib": {"head": "23f7c80df", "stamp": "15956e4a96c4"}, "tu": "src/800_b_2.c", "fn": "func_80034314", "addr": 2147697428, "aliases": null, "header": false, "includers": 0, "nhash_before": "1392bbf02f6c83a88fd559cbd37e6ef4b7e6a0e8", "nhash_after": "b3c96fad9d9e848b0e3b3e42922d89c3c9469476", "source": ".run/P36/agents/main__func_80034314/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.173, "objects": ["build/src/800_b_2.o"], "before_text": "s32 func_80034314(u32 arg0, u8 *p, u32 arg2) {\n u32 flags;\n Snd54 *e;\n Rec12 *rec;\n u8 *q;\n s16 *pa;\n register s32 idx __asm__(\"$3\"); // !FAKE: pin $3 \u2014 NEEDED DIFFERS (P36 rung B tus9)\n s32 ret;\n s32 i;\n s32 j;\n s32 b1;\n u32 x;\n u32 y;\n\n y = arg0 >> 16;\n flags = arg2;\n x = arg0;\n b1 = p[1];\n if (b1 == 0) {\n rec = &D_80068A54[p[3]];\n } else {\n if (D_800A4EE8 == 0) {\n return 0;\n }\n if (D_800A4EF0 != b1) {\n return 0;\n }\n rec = *(Rec12 **)((u8 *)D_800A4EE8 + 0x18) + p[3];\n }\n\n idx = func_800348A8(arg0);\n ret = idx;\n if (idx != 0) {\n idx = ret - 1;\n e = (Snd54 *)((u8 *)D_800A46E8 + idx * 0x54);\n if (flags & 0x1000) {\n e->unk1C[0].unk06 = 1;\n e->unk1C[0].unk02 = 0x100;\n e->unk1C[0].unk04 = ((s32)(flags & 0x7F) * 0x3FFF) >> 7;\n if (flags & 0x2000) {\n e->unk38 = D_8006AED8[(flags >> 8) & 0xF];\n } else {\n e->unk38 = 0;\n e->unk39 = 0;\n }\n return ret;\n }\n if (e->unk08 != 0) {\n return 0;\n }\n func_80034650(e, 0);\n } else {\n idx = func_8003310C(rec->unk04);\n ret = idx;\n if (idx == 0) {\n return 0;\n }\n idx = ret - 1;\n e = (Snd54 *)((u8 *)D_800A46E8 + idx * 0x54);\n }\n\n /* dbr fence (zero-byte, non-volatile asm -> reorg stop_search_p): keeps the\n * `j .L800344B4` delay slot a nop; without it reorg eagerly steals + duplicates\n * the merge block's first store. */\n e->unk37 = rec->unk08;\n e->unk34 = b1;\n e->unk0C = rec->unk00;\n e->unk02 = rec->unk04;\n e->unk10 = e->unk0C;\n e->unk04 = x;\n e->unk06 = y;\n e->unk14 = 1;\n e->unk17 = p[2];\n e->unk16 = 0;\n e->unk18 = 0x7FFF;\n e->unk08 = rec->unk06;\n e->unk50 = 0;\n e->unk52 = 0;\n\n if (rec->unk08 & 0x10) {\n e->unk48 = 1;\n } else {\n e->unk48 = 0;\n }\n\n if (rec->unk08 & 4) {\n e->unk1A = 0x400;\n } else if (rec->unk08 & 8) {\n e->unk1A = 0x200;\n } else {\n e->unk1A = 0x5F;\n }\n e->unk36 = 0;\n /* sched fence: without it the two stores (memory-unit users) sink below the\n * whole loop preheader (potential_hazard beats the LUID tie-break). */\n\n pa = &e->unk1C[0].unk00;\n for (i = 0; i < 3; i++, pa = (s16 *)((u8 *)pa + 8)) {\n pa[1] = 0x100;\n *((u8 *)pa + 6) = 0;\n if (i != 0) {\n pa[0] = 0x3FFF;\n pa[2] = 0x3FFF;\n } else if (flags & 0x1000) {\n pa[0] = ((flags & 0x7F) * 0x3FFF) >> 7;\n pa[2] = ((flags & 0x7F) * 0x3FFF) >> 7;\n if (flags & 0x2000) {\n u8 tv = D_8006AED8[(flags >> 8) & 0xF];\n e->unk38 = tv;\n e->unk39 = tv;\n }\n } else {\n pa[0] = 0x3FFF;\n pa[2] = 0x3FFF;\n e->unk38 = 0;\n e->unk39 = 0;\n }\n }\n\n q = e->unk3A;\n for (j = 7; j >= 0; j--) {\n *q++ = 0;\n }\n\n e->unk00 = 5;\n return ret;\n}\n", "after_text": "s32 func_80034314(u32 arg0, u8 *p, u32 arg2) {\n u32 flags;\n Snd54 *e;\n Rec12 *rec;\n u8 *q;\n s16 *pa;\n s32 idx;\n s32 ret;\n s32 i;\n s32 j;\n s32 b1;\n u32 x;\n u32 y;\n\n y = arg0 >> 16;\n flags = arg2;\n x = arg0;\n b1 = p[1];\n if (b1 == 0) {\n rec = &D_80068A54[p[3]];\n } else {\n if (D_800A4EE8 == 0) {\n return 0;\n }\n if (D_800A4EF0 != b1) {\n return 0;\n }\n rec = *(Rec12 **)((u8 *)D_800A4EE8 + 0x18) + p[3];\n }\n\n idx = func_800348A8(arg0);\n if (idx != 0) {\n ret = idx;\n idx--;\n e = (Snd54 *)((u8 *)D_800A46E8 + idx * 0x54);\n if (flags & 0x1000) {\n e->unk1C[0].unk06 = 1;\n e->unk1C[0].unk02 = 0x100;\n e->unk1C[0].unk04 = ((s32)(flags & 0x7F) * 0x3FFF) >> 7;\n if (flags & 0x2000) {\n e->unk38 = D_8006AED8[(flags >> 8) & 0xF];\n } else {\n e->unk38 = 0;\n e->unk39 = 0;\n }\n return ret;\n }\n if (e->unk08 != 0) {\n return 0;\n }\n func_80034650(e, 0);\n } else {\n idx = func_8003310C(rec->unk04);\n if (idx == 0) {\n return 0;\n }\n ret = idx;\n idx--;\n e = (Snd54 *)((u8 *)D_800A46E8 + idx * 0x54);\n }\n\n e->unk37 = rec->unk08;\n e->unk34 = b1;\n e->unk0C = rec->unk00;\n e->unk02 = rec->unk04;\n e->unk10 = e->unk0C;\n e->unk04 = x;\n e->unk06 = y;\n e->unk14 = 1;\n e->unk17 = p[2];\n e->unk16 = 0;\n e->unk18 = 0x7FFF;\n e->unk08 = rec->unk06;\n e->unk50 = 0;\n e->unk52 = 0;\n\n if (rec->unk08 & 0x10) {\n e->unk48 = 1;\n } else {\n e->unk48 = 0;\n }\n\n if (rec->unk08 & 4) {\n e->unk1A = 0x400;\n } else if (rec->unk08 & 8) {\n e->unk1A = 0x200;\n } else {\n e->unk1A = 0x5F;\n }\n e->unk36 = 0;\n\n pa = &e->unk1C[0].unk00;\n for (i = 0; i < 3; i++, pa = (s16 *)((u8 *)pa + 8)) {\n pa[1] = 0x100;\n *((u8 *)pa + 6) = 0;\n if (i != 0) {\n pa[0] = 0x3FFF;\n pa[2] = 0x3FFF;\n } else if (flags & 0x1000) {\n pa[0] = ((flags & 0x7F) * 0x3FFF) >> 7;\n pa[2] = ((flags & 0x7F) * 0x3FFF) >> 7;\n if (flags & 0x2000) {\n u8 tv = D_8006AED8[(flags >> 8) & 0xF];\n e->unk38 = tv;\n e->unk39 = tv;\n }\n } else {\n pa[0] = 0x3FFF;\n pa[2] = 0x3FFF;\n e->unk38 = 0;\n e->unk39 = 0;\n }\n }\n\n q = e->unk3A;\n for (j = 7; j >= 0; j--) {\n *q++ = 0;\n }\n\n e->unk00 = 5;\n return ret;\n}\n"} +{"ts": "2026-09-11 02:36:00", "label": "s104_e17", "rung": "E", "calib": {"head": "99355f672", "stamp": "15956e4a96c4"}, "tu": "src/ov_SC04_011/ov_SC04_011_jr_8017D494.c", "fn": "func_8018CC24", "addr": 2149108772, "aliases": null, "header": false, "includers": 0, "nhash_before": "7ba96fef056069abdac8ea946a3faeb2d234d8fe", "nhash_after": "91fe764b39851dcb5b47daf0db1a6842c9231057", "source": ".run/P36/agents/ov_SC04_011__func_8018CC24/body.c", "verdict": "LEVER-FREE", "sites": [], "compiles": 1, "seconds": 0.42, "objects": ["build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o"], "before_text": "void func_8018CC24(s32 a0) {\n s32 s0;\n s32 a0_ptr;\n register s32 v0 __asm__(\"$2\"); // !FAKE: pin $2 \u2014 NEEDED DIFFERS (P36 rung B t3_tus1)\n s32 v1;\n s32 v1_sign;\n\n s0 = a0;\n\n func_8012AD80(a0);\n\n a0_ptr = *(s32 *)(s0 + 0x20);\n v1 = *(u16 *)(s0 + 0x106);\n v0 = *(u16 *)(a0_ptr + 0x10);\n v0 = v0 + v1;\n *(u16 *)(a0_ptr + 0x10) = (u16)v0;\n\n a0_ptr = *(s32 *)(s0 + 0x20);\n v1 = *(u16 *)(s0 + 0x108);\n v0 = *(u16 *)(a0_ptr + 0x14);\n v0 = v0 + v1;\n *(u16 *)(a0_ptr + 0x14) = (u16)v0;\n\n v0 = *(s32 *)(s0 + 0x1C);\n if ((v0 & 0x3) == 0) {\n func_8018A7E8(a0);\n }\n\n v0 = *(s32 *)(s0 + 0x1C);\n v1_sign = *(s16 *)(s0 + 0xA);\n v0++;\n\n *(s32 *)(s0 + 0x1C) = v0;\n\n if (v1_sign >= -0x3FF) {\n func_8012C218((void *)a0);\n }\n}\n", "after_text": "void func_8018CC24(s32 arg0) {\n s32 a0;\n s32 a1;\n u16 val;\n\n func_8012AD80(arg0);\n\n a0 = *(s32 *)(arg0 + 0x20);\n *(u16 *)(a0 + 0x10) = *(u16 *)(a0 + 0x10) + (*(u16 *)(arg0 + 0x106));\n\n a1 = *(s32 *)(arg0 + 0x20);\n val = *(u16 *)(arg0 + 0x108);\n *(u16 *)(a1 + 0x14) = *(u16 *)(a1 + 0x14) + val;\n\n if ((*(s32 *)(arg0 + 0x1C) & 0x3) == 0) {\n func_8018A7E8(arg0);\n }\n\n *(s32 *)(arg0 + 0x1C) = *(s32 *)(arg0 + 0x1C) + 1;\n\n if (*(s16 *)(arg0 + 0xA) >= -0x3FF) {\n func_8012C218((void *)arg0);\n }\n}\n"} diff --git a/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c b/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c index 03ce306f5..34faaa149 100644 --- a/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c +++ b/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c @@ -13948,42 +13948,28 @@ extern void func_8012AD80(s32 a0); extern void func_8012C218(void *a0); extern void func_8018A7E8(s32); -void func_8018CC24(s32 a0) { - s32 s0; - s32 a0_ptr; - register s32 v0 __asm__("$2"); // !FAKE: pin $2 — NEEDED DIFFERS (P36 rung B t3_tus1) - s32 v1; - s32 v1_sign; +void func_8018CC24(s32 arg0) { + s32 a0; + s32 a1; + u16 val; - s0 = a0; + func_8012AD80(arg0); - func_8012AD80(a0); + a0 = *(s32 *)(arg0 + 0x20); + *(u16 *)(a0 + 0x10) = *(u16 *)(a0 + 0x10) + (*(u16 *)(arg0 + 0x106)); - a0_ptr = *(s32 *)(s0 + 0x20); - v1 = *(u16 *)(s0 + 0x106); - v0 = *(u16 *)(a0_ptr + 0x10); - v0 = v0 + v1; - *(u16 *)(a0_ptr + 0x10) = (u16)v0; + a1 = *(s32 *)(arg0 + 0x20); + val = *(u16 *)(arg0 + 0x108); + *(u16 *)(a1 + 0x14) = *(u16 *)(a1 + 0x14) + val; - a0_ptr = *(s32 *)(s0 + 0x20); - v1 = *(u16 *)(s0 + 0x108); - v0 = *(u16 *)(a0_ptr + 0x14); - v0 = v0 + v1; - *(u16 *)(a0_ptr + 0x14) = (u16)v0; - - v0 = *(s32 *)(s0 + 0x1C); - if ((v0 & 0x3) == 0) { - func_8018A7E8(a0); + if ((*(s32 *)(arg0 + 0x1C) & 0x3) == 0) { + func_8018A7E8(arg0); } - v0 = *(s32 *)(s0 + 0x1C); - v1_sign = *(s16 *)(s0 + 0xA); - v0++; + *(s32 *)(arg0 + 0x1C) = *(s32 *)(arg0 + 0x1C) + 1; - *(s32 *)(s0 + 0x1C) = v0; - - if (v1_sign >= -0x3FF) { - func_8012C218((void *)a0); + if (*(s16 *)(arg0 + 0xA) >= -0x3FF) { + func_8012C218((void *)arg0); } }