phase-36: S104 s104_e34 — func_800D1B80 banked at 0 through the whole-object gate + propagated — → 0: the method pointer called with its object (sched.c:2488-2545; local-alloc.c:700; jump.c:425-462)

This commit is contained in:
Drew T
2026-09-11 04:44:01 -06:00
parent 5ddd32662e
commit bc0e4888ec
13 changed files with 1053 additions and 196 deletions
@@ -0,0 +1,203 @@
s32 func_800D128C(s32 arg0, s32 arg1) {
s16 ret = 3;
s32 flag = 1;
s32 id = 0;
s32 obj = (s32)&D_80126B58;
s32 val;
/* func_8014BB24 under a second declaration: cross-jump compares call targets by the
* symbol-name POINTER (rtx_renumbered_equal_p, jump.c:3991-3992), so case 117's call stays
* apart from case 1's (METHOD step 3 declaration alias; same bytes, same relocation). */
extern void func_8014BB24_alt(s32, s32, s32) __asm__("func_8014BB24");
switch ((u8)arg0) {
case 9:
func_8014BD24(obj, 5);
val = 0;
ret = 1;
break;
case 106:
func_8014BB24(obj, 0x12C, 1);
val = 0x12C;
break;
case 1:
func_8014BB24(obj, 0x96, 1);
goto set96;
case 2:
func_8014BCC0(obj, 5);
ret = 4;
/* fallthrough */
case 13:
lab1334:
val = 0x19;
break;
case 3:
func_8014BCC0(obj, 0x19);
ret = 5;
goto lab1334;
case 17:
func_8014BCC0(obj, 5);
ret = 4;
val = 0xA;
break;
case 18:
func_8014BCC0(obj, 0xA);
ret = 5;
val = 0xA;
break;
case 12:
func_8014BCC0(obj, 5);
ret = 5;
val = 2;
break;
case 11:
func_8014BB24(obj, 0x1E, 1);
val = 0xA;
break;
case 8:
func_8014B944(obj, 0x500000, 1);
val = 5;
ret = 2;
break;
case 109:
func_8014B944(obj, 0x900000, 1);
val = 5;
ret = 2;
break;
case 4:
ret = 7;
/* fallthrough */
case 15:
val = 0x50;
break;
case 5:
ret = 7;
/* fallthrough */
case 16:
set96:
val = 0x96;
break;
case 107:
if ((s16)arg1 >= 0x13) {
val = 0x14;
} else {
val = (s16)arg1 + 2;
}
val = val * 25;
func_8014BD24(obj, val);
ret = 7;
break;
case 6:
func_8014BD24(obj, 5);
ret = 7;
val = 0xFA;
break;
case 7:
func_8014BD24(obj, 5);
ret = 7;
val = 0x3E7;
break;
case 83:
func_8014BB24(obj, 0xA, 1);
val = 0xA;
break;
case 84:
func_8014BCC0(obj, 5);
ret = 5;
val = 5;
break;
case 85:
func_8014BB24(obj, 0x32, 1);
val = 0x32;
break;
case 112:
func_8014BC0C(obj, 0x19);
ret = 7;
val = 0x3E7;
break;
case 76:
case 113:
ret = 7;
val = 5;
break;
case 114:
func_8014BB24(obj, 0x64, 1);
/* fallthrough */
case 14:
val = 0x32;
break;
case 115:
func_8014BB24(obj, 0x96, 1);
/* fallthrough */
case 105:
val = 0x64;
break;
case 116:
func_8014BB24(obj, 0x96, 1);
val = 0xC8;
break;
case 117:
func_8014BB24_alt(obj, 0xC8, 1);
goto set96;
case 118:
func_8014BB24(obj, 0xFA, 1);
/* fallthrough */
case 104:
val = 0x12C;
break;
case 119:
func_8014BB24(obj, 0x1F4, 1);
val = 0x1F4;
break;
case 87:
val = 0xA;
ret = 1;
break;
default:
ret = 0;
break;
}
switch (ret) {
case 0:
id = 0x45F;
flag = 0;
break;
case 1:
id = 0x464;
func_8014B2A8();
func_8014BB24(obj, val, 1);
break;
case 2:
func_8014BD24(obj, val);
id = 0x464;
break;
case 3:
func_8014BD24(obj, val);
id = 0x45C;
break;
case 4:
func_8014BD24(obj, val);
id = 0x463;
break;
case 5:
func_8014BD24(obj, val);
id = 0x465;
break;
case 7:
func_8014BB24(obj, val, 1);
id = 0x45C;
break;
case 8:
func_8014BCC0(obj, val);
id = 0x45C;
break;
default:
flag = 0;
break;
}
if ((u16)id != 0) {
func_8002D4C8((u16)id, 0);
}
return flag;
}
@@ -0,0 +1,200 @@
s32 func_800D128C(s32 arg0, s32 arg1) {
s16 ret = 3;
s32 flag = 1;
s32 id = 0;
s32 obj = (s32)&D_80126B58;
s32 val;
switch ((u8)arg0) {
case 9:
func_8014BD24(obj, 5);
val = 0;
ret = 1;
break;
case 106:
func_8014BB24(obj, 0x12C, 1);
val = 0x12C;
break;
case 1:
val = 0x96;
func_8014BB24(obj, 0x96, 1);
break;
case 2:
func_8014BCC0(obj, 5);
ret = 4;
/* fallthrough */
case 13:
lab1334:
val = 0x19;
break;
case 3:
func_8014BCC0(obj, 0x19);
ret = 5;
goto lab1334; /* §162: the backward j is a source goto */
case 17:
func_8014BCC0(obj, 5);
ret = 4;
val = 0xA;
break;
case 18:
func_8014BCC0(obj, 0xA);
ret = 5;
val = 0xA;
break;
case 12:
func_8014BCC0(obj, 5);
ret = 5;
val = 2;
break;
case 11:
func_8014BB24(obj, 0x1E, 1);
val = 0xA;
break;
case 8:
func_8014B944(obj, 0x500000, 1);
val = 5;
ret = 2;
break;
case 109:
func_8014B944(obj, 0x900000, 1);
val = 5;
ret = 2;
break;
case 4:
ret = 7;
/* fallthrough */
case 15:
val = 0x50;
break;
case 5:
ret = 7;
/* fallthrough */
case 16:
val = 0x96;
break;
case 107:
if ((s16)arg1 >= 0x13) {
val = 0x14;
} else {
val = (s16)arg1 + 2;
}
val = val * 25;
func_8014BD24(obj, val);
ret = 7;
break;
case 6:
func_8014BD24(obj, 5);
ret = 7;
val = 0xFA;
break;
case 7:
func_8014BD24(obj, 5);
ret = 7;
val = 0x3E7;
break;
case 83:
func_8014BB24(obj, 0xA, 1);
val = 0xA;
break;
case 84:
func_8014BCC0(obj, 5);
ret = 5;
val = 5;
break;
case 85:
func_8014BB24(obj, 0x32, 1);
val = 0x32;
break;
case 112:
func_8014BC0C(obj, 0x19);
ret = 7;
val = 0x3E7;
break;
case 76:
case 113:
ret = 7;
val = 5;
break;
case 114:
func_8014BB24(obj, 0x64, 1);
/* fallthrough */
case 14:
val = 0x32;
break;
case 115:
func_8014BB24(obj, 0x96, 1);
/* fallthrough */
case 105:
val = 0x64;
break;
case 116:
func_8014BB24(obj, 0x96, 1);
val = 0xC8;
break;
case 117:
func_8014BB24(obj, 0xC8, 1);
val = 0x96;
break;
case 118:
func_8014BB24(obj, 0xFA, 1);
/* fallthrough */
case 104:
val = 0x12C;
break;
case 119:
func_8014BB24(obj, 0x1F4, 1);
val = 0x1F4;
break;
case 87:
val = 0xA;
ret = 1;
break;
default:
ret = 0;
break;
}
switch (ret) {
case 0:
id = 0x45F;
flag = 0;
break;
case 1:
id = 0x464;
func_8014B2A8();
func_8014BB24(obj, val, 1);
break;
case 2:
func_8014BD24(obj, val);
id = 0x464;
break;
case 3:
func_8014BD24(obj, val);
id = 0x45C;
break;
case 4:
func_8014BD24(obj, val);
id = 0x463;
break;
case 5:
func_8014BD24(obj, val);
id = 0x465;
break;
case 7:
func_8014BB24(obj, val, 1);
id = 0x45C;
break;
case 8:
func_8014BCC0(obj, val);
id = 0x45C;
break;
default:
flag = 0;
break;
}
if ((u16)id != 0) {
func_8002D4C8((u16)id, 0);
}
return flag;
}
@@ -0,0 +1,203 @@
s32 func_800D128C(s32 arg0, s32 arg1) {
s16 ret = 3;
s32 flag = 1;
s32 id = 0;
s32 obj = (s32)&D_80126B58;
s32 val;
/* func_8014BB24 under a second declaration: cross-jump compares call targets by the
* symbol-name POINTER (rtx_renumbered_equal_p, jump.c:3991-3992), so case 117's call stays
* apart from case 1's (METHOD step 3 declaration alias; same bytes, same relocation). */
extern void func_8014BB24_alt(s32, s32, s32) __asm__("func_8014BB24"); // !FAKE: alias case 117 call — find_cross_jump jump.c:2371, SYMBOL_REF by pointer jump.c:3992 (P36 S104 e34 minimum-lever)
switch ((u8)arg0) {
case 9:
func_8014BD24(obj, 5);
val = 0;
ret = 1;
break;
case 106:
func_8014BB24(obj, 0x12C, 1);
val = 0x12C;
break;
case 1:
func_8014BB24(obj, 0x96, 1);
goto set96;
case 2:
func_8014BCC0(obj, 5);
ret = 4;
/* fallthrough */
case 13:
lab1334:
val = 0x19;
break;
case 3:
func_8014BCC0(obj, 0x19);
ret = 5;
goto lab1334;
case 17:
func_8014BCC0(obj, 5);
ret = 4;
val = 0xA;
break;
case 18:
func_8014BCC0(obj, 0xA);
ret = 5;
val = 0xA;
break;
case 12:
func_8014BCC0(obj, 5);
ret = 5;
val = 2;
break;
case 11:
func_8014BB24(obj, 0x1E, 1);
val = 0xA;
break;
case 8:
func_8014B944(obj, 0x500000, 1);
val = 5;
ret = 2;
break;
case 109:
func_8014B944(obj, 0x900000, 1);
val = 5;
ret = 2;
break;
case 4:
ret = 7;
/* fallthrough */
case 15:
val = 0x50;
break;
case 5:
ret = 7;
/* fallthrough */
case 16:
set96:
val = 0x96;
break;
case 107:
if ((s16)arg1 >= 0x13) {
val = 0x14;
} else {
val = (s16)arg1 + 2;
}
val = val * 25;
func_8014BD24(obj, val);
ret = 7;
break;
case 6:
func_8014BD24(obj, 5);
ret = 7;
val = 0xFA;
break;
case 7:
func_8014BD24(obj, 5);
ret = 7;
val = 0x3E7;
break;
case 83:
func_8014BB24(obj, 0xA, 1);
val = 0xA;
break;
case 84:
func_8014BCC0(obj, 5);
ret = 5;
val = 5;
break;
case 85:
func_8014BB24(obj, 0x32, 1);
val = 0x32;
break;
case 112:
func_8014BC0C(obj, 0x19);
ret = 7;
val = 0x3E7;
break;
case 76:
case 113:
ret = 7;
val = 5;
break;
case 114:
func_8014BB24(obj, 0x64, 1);
/* fallthrough */
case 14:
val = 0x32;
break;
case 115:
func_8014BB24(obj, 0x96, 1);
/* fallthrough */
case 105:
val = 0x64;
break;
case 116:
func_8014BB24(obj, 0x96, 1);
val = 0xC8;
break;
case 117:
func_8014BB24_alt(obj, 0xC8, 1);
goto set96;
case 118:
func_8014BB24(obj, 0xFA, 1);
/* fallthrough */
case 104:
val = 0x12C;
break;
case 119:
func_8014BB24(obj, 0x1F4, 1);
val = 0x1F4;
break;
case 87:
val = 0xA;
ret = 1;
break;
default:
ret = 0;
break;
}
switch (ret) {
case 0:
id = 0x45F;
flag = 0;
break;
case 1:
id = 0x464;
func_8014B2A8();
func_8014BB24(obj, val, 1);
break;
case 2:
func_8014BD24(obj, val);
id = 0x464;
break;
case 3:
func_8014BD24(obj, val);
id = 0x45C;
break;
case 4:
func_8014BD24(obj, val);
id = 0x463;
break;
case 5:
func_8014BD24(obj, val);
id = 0x465;
break;
case 7:
func_8014BB24(obj, val, 1);
id = 0x45C;
break;
case 8:
func_8014BCC0(obj, val);
id = 0x45C;
break;
default:
flag = 0;
break;
}
if ((u16)id != 0) {
func_8002D4C8((u16)id, 0);
}
return flag;
}
@@ -0,0 +1,71 @@
# func_800D128C — e34 (P36 T7 S104) — score 46 -> 0; levers 3 -> 0 asm (one METHOD-step-3 declaration alias left)
Files: `body.c` (0; the alias with an explanatory comment), `body_minlever.c` (0; the same text with the alias
line marked `// !FAKE: alias` — use it if the alias is ruled a lever: 3 -> 1), `body_leverfree_nearmiss.c`
(8; no alias, no asm).
## (a) Residual (counted on the whole objdump, scratch/target.txt vs scratch/free_dis.txt)
COUNT 238 vs 243, three independent defects:
1. switch-2 index copy `move v1,s1` missing (1 ins) — the tree's `sel` launder.
2. case 1's `[li a2,1][jal BB24][li s0,150][j]` tail cross-jumped into case 117's identical tail (3 ins).
3. case 16's `[label16][li s0,150][j]` cross-jumped into the same tail (1 ins) — the tree's second barrier.
## (b) Passes and decisions
1. Index copy. `switch (ret)` on an `s32 ret`: expand_end_case uses ret's pseudo as the index, no copy.
On an `s16 ret` the index is `sign_extend:SI (reg:HI ret)` = an `ashift 16`/`ashiftrt 16` pair; combine's
`simplify_shift_const` (`combine.c:7926-7942`) sees more than 16 sign-bit copies in ret (every set of ret is a
small constant) and reduces the pair to `(set (reg:SI 96) (subreg:SI (reg:HI ret)))` — a real copy into a new
single-block pseudo, which local-alloc puts in `$v1` (PROVEN: scratch/dumps_body/body.i.combine insn 653).
2+3. Cross-jump runs AFTER sched2 (`toplev.c:3142`, `jump_optimize (insns, 1, 1, 0)`), unconditional-jump arm
`jump.c:1965-2000`: each `j L2` is compared with every other jump to L2 (jump_chain, reverse insn order) by
`find_cross_jump` (`jump.c:2371-2527`, minimum 2 insns; 1 against the code before the label). A CODE_LABEL met on
the moved stream lowers the minimum (`jump.c:2406-2410`), so case 16's `[label; s0=150; j]` merges into ANY other
arm ending `[s0=150; j L2]`. sched2 cannot separate them: a hard-reg set after a call always depends on the call
(`sched.c:1704`, the `call_used_regs[i]` test indexes the NREGS counter, i.e. `$0`, which is call-used).
The target's bytes are reachable only if, at jump2 time, NO arm other than case 16 ends in `[s0=150; j L2]`:
cases 1 and 117 end in `[call; j L16]` (a source goto to case 16's assignment, like the file's existing
`goto lab1334` for case 3). reorg then rebuilds the target: the `j L16`'s slot cannot be filled from behind (the
filled `jal` is a SEQUENCE, `reorg.c:675-700` stop_search_p), so it steals `li s0,150` from L16 and threads the
jump on to L2 — `j 2c0; li s0,150`, byte-identical to a private tail. Case 5 -> 16 keeps its own block.
But cases 1 and 117 now both jump to L16 after `[li a2,1][jal func_8014BB24]` — two equal insns, the minimum:
they merge (scratch/c/g1.c: 41). They stay apart only if the two call insns are not `rtx_renumbered_equal_p`:
SYMBOL_REF compares the name string BY POINTER (`jump.c:3991-3992`), and an `__asm__("func_8014BB24")` declaration gets its own
`*`-prefixed, freshly allocated name string (`varasm.c:478-485`) — the METHOD step-3 declaration alias (g2/g3/body.c: 0).
A return-type cast `((s32 (*)(s32, s32, s32))func_8014BB24)(obj, 0xC8, 1)` also works (call_value vs call
pattern; scratch/c/k1.c: 0). Nothing in plain C makes two identical `(obj, K, 1)` calls to one declared void
function differ in RTL.
## (c) The moves (all four in body.c)
1. `s16 ret = 3;` and `switch (ret)` — the `sel` variable and its launder deleted (1 lever).
2. case 1: `func_8014BB24(obj, 0x96, 1); goto set96;` and case 117: `...(obj, 0xC8, 1); goto set96;` with
`set96:` on case 16's `val = 0x96;` — both asm barriers deleted (2 levers).
3. case 117's call through `func_8014BB24_alt` (body-local `extern void func_8014BB24_alt(s32, s32, s32)
__asm__("func_8014BB24");`) — zero bytes, same relocation symbol, the .o is identical before linking.
(1) alone: 43 (u16 sel variant) -> the index copy fixed; (2) without (3): 41; (2)+(3): 0.
## (d) Generator proposals
- When a `switch (x)` target has an extra `move vN,sK` before `sltiu`, declare the switch variable `s16`
(combine turns its sign extension into a surviving SUBREG copy) instead of adding a copy variable.
- When the target has N arms whose tails are byte-identical `[.. jal F][j L; li sK,C]` that the candidate
cross-jumps, and one arm is a bare `[label][li sK,C][j]`: rewrite the other arms as `goto` to that arm's
assignment; if two of the goto arms end in the same call, route one call through a body-local asm-named
declaration of the same symbol. Detect by: target `j` delay slot holds an insn equal to the first insn at a
label elsewhere (reorg's steal-from-target signature).
## (e) What did not work (bytes)
- `val = 0x96` before the call in case 1 or case 117 (x1/x2: 9/8): sched2 keeps it before the jal and reorg fills
the `j` slot from L2's `move v1,s1` instead.
- one goto only (g4/g5: 43/41): the remaining `[s0=150; j L2]` tail swallows case 16 through the label rule.
- `switch ((u16)ret)`, `(ret & 0xFFFF)`, `u16 ret`, `u8 ret`, `(u8)ret`: 1 each (a zero-extend, `andi`).
`switch ((s16)ret)` with `s32 ret`: 0 too — the declaration spelling reads better.
## (f) Where the method fell short
Steps 12-16 list "goto chains -> structured C"; this is the INVERSE: the target needed MORE gotos (two arms
jumping into a third arm's tail, reorg's steal-from-target rebuilding the private-looking tail). The residual
shows it as "arms merged that the target keeps apart", which reads like "add a barrier"; the tree's header had
concluded exactly that. The reorg signature (a `j` slot equal to another arm's first insn) should be a residual
class of its own.
## (g) Structs
No. The deciding facts are jump2's insn equality and reorg's slot filling; `obj` (`&D_80126B58`) as a struct
pointer would not change either. The remaining alias is a symbol-identity question, not an aggregate access.
@@ -0,0 +1,27 @@
s16 func_800D1658(s32 arg0) {
extern int func_800291B4(int);
extern void func_800291A0(int, int);
extern void func_8002D4C8(int, int);
extern s16 D_8010EDEC;
int v;
short ret;
int id;
int slot;
slot = (arg0 & 0xFF) + 0x2F;
id = func_800291B4(slot) & 0xFF;
if (id == 0) {
return 0;
}
v = *(s16 *)((u8 *)&D_8010EDEC + id * 0xC);
ret = v;
if (v > 0 || ((u16)ret == 0x8000 && id != 0x27)) {
func_800291A0(slot, 0);
func_8002D4C8(0x462, 0);
ret = 1;
} else {
ret = 0;
func_8002D4C8(0x45F, 0);
}
return ret;
}
@@ -0,0 +1,50 @@
# func_800D1658 — e34 (P36 T7 S104) — score 24 -> 0, levers 3 -> 0 (plain C, structured, no goto)
## (a) Residual
COUNT, 43 vs 47 ins. Mine never copies the loaded value into `ret` (the target's `move s0,v0` in the `bgtz` slot),
reads the `& 0xffff` test off the load register, and so `ret` (only constants left) shares `$s0` with `slot`:
one callee-saved register fewer (no `$s1` save/restore, frame 24 vs 32), no `move s0,zero` in the `beq` slot,
and a plain `move v0,s0` instead of the target's `sll/sra 16` sign extension on return.
## (b) Pass and decision (PROVEN on the .cse/.combine dumps, scratch/dumps_{d1,d5})
`t = ret & 0xFFFF` with `ret` a `short`: C promotes `ret` by SIGN extension, which on MIPS gcc 2.7.2 expands to
`(ashift:SI (subreg:SI (reg:HI ret) 0) 16)` + `ashiftrt 16` + `and 0xffff`. The first cse pass folds the
PARADOXICAL `(subreg:SI (reg:HI ret))` to `(reg:SI v)` because ret's class holds `(subreg:HI v)` — `fold_rtx`'s
SUBREG case, `cse.c:4850-4869` (lookup of the inner reg, `return copy_rtx (SUBREG_REG (elt->exp))`). The d5 .cse
dump shows insn 61 as `(ashift:SI (reg/v:SI 73) 16)`; combine then turns the triple into
`(zero_extend:SI (subreg:HI (reg:SI 73)))`. `ret = v` is dead, flow deletes it, and `ret`'s range no longer
overlaps `slot`'s — both get `$s0`.
`(u16)ret` expands to `(zero_extend:SI (reg:HI ret))` — a single `zero_extendhisi2` pattern with no paradoxical
SUBREG, so fold_rtx has nothing to resolve; the read stays on `ret` (`andi v1,s0,0xffff`), `ret = v` survives,
`ret` conflicts with `slot` (`$s1`), and the HImode `ret` is sign-extended on return.
## (c) The moves that closed it
1. The narrow test as a CAST, not a mask: `(u16)ret == 0x8000` instead of `(ret & 0xFFFF)` (the one that matters;
the goto spelling with only this change, scratch/c/d1.c, is already 0).
2. The goto chain as one structured condition: `if (v > 0 || ((u16)ret == 0x8000 && id != 0x27)) { ok } else
{ bad }` — also 0 (scratch/c/e1.c, delivered). `v` stays an `int` temp for the `lh`; `ret > 0` instead of
`v > 0` is also 0 (e3).
Two pins (`$2`, `$3`) were never needed; the `$16` pin was standing in for the missing `ret = v` copy.
## (d) Generator proposal
When a `short`/`s16` local is masked `x & 0xFFFF` (or `& 0xFF` for a char) and the residual shows that local's copy
missing (a COUNT residual with one callee-saved register fewer), rewrite the mask as the unsigned cast
`(u16)x` / `(u8)x` — it expands to a zero_extend with no paradoxical SUBREG for cse's fold_rtx to see through.
## (e) What did not work (bytes)
- `ret = load; if (ret > 0) …; if ((ret & 0xFFFF) != 0x8000)` -> 22 (no int temp; ret read through the subreg).
- `ret = load` with `(u16)ret` -> 15: TWO loads (`lh` for the test, `lhu` for ret) and an extra frame slot —
the int temp `v` is what keeps one load.
- `s16 v` -> 15 (same double load). `(u16)(ret = v) != 0x8000` -> 22. `(ret & 0xFFFF)` with `ret = v` -> 24.
- `u16 t; (t = ret) != 0x8000` -> 0 too (the same zero_extend channel; not delivered — the cast reads better).
## (f) Where the method fell short
Steps 12-16 have the width moves (c4, d8, d13) but not "a mask is a SIGN extension followed by an AND": the
paradoxical-SUBREG fold is a cse channel that deletes a user copy. The generators' R12 width moves changed
declarations; this needed an expression-level cast (like d13's `(s16)t >> 6`, the same family — cast one operand
at the use, never the declaration).
## (g) Structs
No. `D_8010EDEC` is a 12-byte record table (`+0` s16 flags, `+4` u16 qty per other TUs' comments); a struct type
would turn `*(s16 *)((u8 *)&D_8010EDEC + id * 0xC)` into `D_8010EDEC[id].flags` — readability only. The deciding
fact is how `ret`'s narrow read is expanded (sign- vs zero-extension), which a struct cannot change.
@@ -0,0 +1,11 @@
s32 aF800D1984(u8 *arg0) {
extern s32 func_800D19DC();
s32 (*fp)(u8 *);
fp = *(s32 (**)(u8 *)) (arg0 + 0xC);
if (fp(arg0) != 0) {
arg0[0x14]++;
return func_800D19DC(arg0);
}
return 0;
}
@@ -0,0 +1,29 @@
# func_800D1984 (aF800D1984) — e34 (P36 T7 S104) — score 1 -> 0, levers 1 -> 0 (plain C)
Byte-twin of func_800D1B80 (same TU; only the tail callee differs: func_800D19DC vs DsMix). The full reading, with
the dump evidence, is in `../resident__func_800D1B80/mechanism.md`; summary:
(a) Residual: `sb v0,20(s0)` vs the target's `sb v0,20(a0)` — the store base, nothing missing (22 = 22 ins).
(b) Pass: sched1 `adjust_priority` (`sched.c:2507-2545`) boosts func_800D19DC's argument copy `a0 = arg0` to
max priority because `birthing_insn_p` (`sched.c:2469-2491`) sees `reg_n_sets[$a0] == 1` (`:2488-2489`); the
copy lands after the store. With it before the store, `optimize_reg_copy_1` (`local-alloc.c:700`, called at
`:1003-1007`) rewrites the store base from arg0's pseudo to `$a0`. Proven on the .sched/.lreg dumps of the twin.
(c) Move: call the method pointer with its object, `fp(arg0)` (`s32 (*fp)(u8 *)`) — the second set of `$a0`
kills the birth boost. The extra `move a0,s0` before `jalr` is deleted after reload as a no-op-by-history copy
(`jump.c:425-462`), 0 bytes. `arg0[0x14]++` written directly (no `p`).
(d) Generator: when the only residual is a store base `$sN -> $aK` just before a call taking that value as arg K,
pass the same value as argument K to an EARLIER call (the method pointer read off that object) — raises
`reg_n_sets[$aK]` above 1.
(e) Didn't work: every `p = arg0` spelling (cse merges it), `fp()` with the store written via `++` (1).
(f) Method gap: no step names `birthing_insn_p`'s `reg_n_sets == 1` test on a hard argument register.
(g) Structs: no — a struct for arg0 would read better (`arg0->fn(arg0); arg0->f14++;`) but the decision is a set
count of `$a0`, not an aggregate-vs-scalar access question.
Name note: the definition stays `aF800D1984` with the file's `__asm__("func_800D1984")` label (func_800D1938's
`extern void func_800D1984(S800D1938 *)` prototype earlier in the TU conflicts with the `u8 *`/`s32` definition).
@@ -0,0 +1,11 @@
s32 func_800D1B80(u8 *arg0) {
extern s32 DsMix();
s32 (*fp)(u8 *);
fp = *(s32 (**)(u8 *)) (arg0 + 0xC);
if (fp(arg0) != 0) {
arg0[0x14]++;
return DsMix(arg0);
}
return 0;
}
@@ -0,0 +1,54 @@
# func_800D1B80 — e34 (P36 T7 S104) — score 1 -> 0, levers 1 -> 0 (plain C, no pin/asm/volatile)
Twin: func_800D1984 (aF800D1984) — same text with func_800D19DC for DsMix, same close (its own pack).
## (a) Residual
One register: the `sb v0,20(..)` base is `$s0` in mine, `$a0` in the target (22 = 22 ins). Nothing missing;
the load reads `$s0`, the store reads `$a0` — the copy `a0 = arg0` was placed BEFORE the store in the target.
## (b) Pass and decision (PROVEN on the .sched/.lreg dumps, scratch/dumps_{good,free})
1. sched1, `adjust_priority` (`sched.c:2507-2545`) boosts an insn with no deaths to `max_priority` when
`birthing_insn_p` (`sched.c:2469-2491`) says it births its destination: `bb_live_regs & bit` AND
`reg_n_sets[REGNO] == 1` (`sched.c:2488-2489`). In the lever-free body the ONLY set of hard `$a0` in the
function is DsMix's argument copy (insn 32), so it is a "birthing" insn: priority 7f000001, scheduled first in
the backward list (T-3), i.e. LAST in forward order, after the store (free .sched: `ready list at T-3: 29 (2) 32
(7f000001), now 32 29`).
2. With the copy after the store, arg0's pseudo dies in the copy and the store keeps it (`$s0`).
When the copy precedes the store, `update_equiv_regs` calls `optimize_reg_copy_1` (`local-alloc.c:1003-1007`,
body `:700-800`) on `a0 = r72` (r72 not dead there): r72 dies in the store a few insns later, so the store's
base is rewritten to `$a0` (good .lreg: `insn 30 (set (mem/s:QI (plus:SI (reg:SI 4 a0) ...`).
3. The extra `a0 = s0` before the `jalr` costs 0 bytes: after reload it is `s0 = a0; ...; a0 = s0` with neither
changed, and jump2's no-op-move deletion removes it (`jump.c:425-462`, the S103 c10/c35 channel).
## (c) The move that closed it
Call the method pointer WITH ITS OBJECT — `fp(arg0)` with `fp` typed `s32 (*)(u8 *)` — i.e. at the handler's real
arity (it is `obj->fn(obj)`). That adds a second set of `$a0` (`reg_n_sets[4] == 2`), `birthing_insn_p` fails for
DsMix's argument copy, its priority stays 1, the store (priority 2) is emitted after it, and
`optimize_reg_copy_1` re-bases the store on `$a0`. `arg0[0x14]++` and `arg0[0x14] = arg0[0x14] + 1` both score 0;
the delivered body uses `++`.
## (d) Generator proposal
When the only residual is a store/load base `$sN -> $aK` right before a `jal` whose argument K is that same value,
and the function makes an earlier indirect call through a field of that pointer (`*(fn **)(p + K)`), re-type the
call as `fn(p)` (pass the object to the method) — generally: add the value the caller already holds in `$aK` as an
extra argument to an EARLIER call (it raises `reg_n_sets[$aK]` and kills sched1's birth boost for the later copy);
this is R19's "pass the argument the caller already holds" applied to the first call instead of the last.
## (e) What did not work (bytes)
- `v = arg0[0x14] + 1; p = arg0; p[0x14] = v; return DsMix(p);` -> 1 (cse re-canonicalises p to arg0).
- `arg0[0x14]++; return DsMix(arg0);` with `fp()` (no argument) -> 1.
- `p = arg0; p[0x14] = arg0[0x14] + 1;` with the call inlined in the `if` -> 1.
The tree header's theory (a second pointer pseudo `p` that cse must not merge, the `$0`-add opaque copy) was a
correct description of the final RTL but the wrong source: the `$a0` store is a local-alloc copy optimisation fed
by a sched1 order, not a surviving user variable.
## (f) Where the method fell short
Nothing in steps 8-16 names this channel: `birthing_insn_p`'s `reg_n_sets == 1` test on a HARD argument register.
It is the same arity family as S103 c3/c12/c35 (R19), but it acts through sched1 + `optimize_reg_copy_1`, so a
reader of `alloc_table.py` would never see it. Worth a cookbook line: "a store base `$aN` = the copy for the next
call scheduled before the store; count the sets of `$aN` in the function".
## (g) Structs
No. The deciding count is `reg_n_sets` of hard `$a0`; a struct type for arg0 (`f0C` method pointer, `u8 f14`)
would make the text nicer (`arg0->fn(arg0); arg0->f14++;`) but does not change sched1's birth test or
`optimize_reg_copy_1`. The close is a call-arity fact, not an aggregate-access one.
+188 -188
View File
@@ -1,7 +1,7 @@
{
"head": "f1a4328bb",
"head": "5ddd32662",
"stamp": "15956e4a96c4",
"generated": "2026-09-11 04:42",
"generated": "2026-09-11 04:43",
"aliases": [
"main",
"ov_SC03_014",
@@ -21,207 +21,207 @@
"main": {
"objects": 85,
"identical": 85,
"seconds": 9.711,
"mean_s": 0.114
"seconds": 6.617000000000001,
"mean_s": 0.078
},
"ov_SC03_014": {
"objects": 32,
"identical": 32,
"seconds": 6.379000000000002,
"mean_s": 0.199
"seconds": 4.514,
"mean_s": 0.141
},
"ov_SC03_015": {
"objects": 32,
"identical": 32,
"seconds": 5.904999999999999,
"mean_s": 0.185
"seconds": 4.311,
"mean_s": 0.135
},
"ov_SC04_011": {
"objects": 28,
"identical": 28,
"seconds": 5.137,
"mean_s": 0.183
"seconds": 3.7189999999999994,
"mean_s": 0.133
}
},
"per_object_seconds": {
"build/src/800.o": 0.875,
"build/src/800_b.o": 0.085,
"build/src/800_b_2.o": 0.435,
"build/src/800_b_o0a.o": 0.121,
"build/src/800_c.o": 0.227,
"build/src/800b2.o": 0.091,
"build/src/apicard1.o": 0.099,
"build/src/apicard2.o": 0.09,
"build/src/apicard3.o": 0.069,
"build/src/apicard4.o": 0.12,
"build/src/apicard5.o": 0.12,
"build/src/apicard6.o": 0.1,
"build/src/apicard7.o": 0.115,
"build/src/boot.o": 0.125,
"build/src/gap.o": 0.141,
"build/src/libapi1.o": 0.098,
"build/src/libapi2.o": 0.079,
"build/src/libc2_1.o": 0.084,
"build/src/libc2_2.o": 0.079,
"build/src/libcd1.o": 0.081,
"build/src/libcd2.o": 0.089,
"build/src/libetc.o": 0.071,
"build/src/libgpu.o": 0.111,
"build/src/libgpu2.o": 0.085,
"build/src/libgs1.o": 0.119,
"build/src/libgs2.o": 0.085,
"build/src/libgs3.o": 0.072,
"build/src/libgs4.o": 0.086,
"build/src/libgs5.o": 0.12,
"build/src/libgs6.o": 0.1,
"build/src/libgs7.o": 0.082,
"build/src/libgs8.o": 0.089,
"build/src/libgte1.o": 0.069,
"build/src/libgte10.o": 0.104,
"build/src/libgte11.o": 0.131,
"build/src/libgte12.o": 0.101,
"build/src/libgte13.o": 0.084,
"build/src/libgte14.o": 0.093,
"build/src/libgte15.o": 0.107,
"build/src/libgte16.o": 0.084,
"build/src/libgte17.o": 0.118,
"build/src/libgte18.o": 0.097,
"build/src/libgte19.o": 0.07,
"build/src/libgte2.o": 0.094,
"build/src/libgte20.o": 0.086,
"build/src/libgte21.o": 0.107,
"build/src/libgte22.o": 0.083,
"build/src/libgte23.o": 0.146,
"build/src/libgte24.o": 0.081,
"build/src/libgte25.o": 0.1,
"build/src/libgte26.o": 0.102,
"build/src/libgte27.o": 0.097,
"build/src/libgte28.o": 0.113,
"build/src/libgte29.o": 0.088,
"build/src/libgte3.o": 0.124,
"build/src/libgte30.o": 0.097,
"build/src/libgte4.o": 0.115,
"build/src/libgte5.o": 0.091,
"build/src/libgte6.o": 0.084,
"build/src/libgte7.o": 0.13,
"build/src/libgte8.o": 0.089,
"build/src/libgte9.o": 0.123,
"build/src/libmcrd1.o": 0.16,
"build/src/libmcrd2.o": 0.074,
"build/src/libpad1.o": 0.078,
"build/src/libpad2.o": 0.157,
"build/src/sgap.o": 0.148,
"build/src/sgap_2.o": 0.086,
"build/src/sgap_3.o": 0.121,
"build/src/sgap_4.o": 0.094,
"build/src/sgap_5.o": 0.107,
"build/src/sgap_6.o": 0.116,
"build/src/sgap_8.o": 0.129,
"build/src/snd1.o": 0.077,
"build/src/snd10.o": 0.096,
"build/src/snd11.o": 0.079,
"build/src/snd12.o": 0.07,
"build/src/snd2.o": 0.088,
"build/src/snd3.o": 0.081,
"build/src/snd4.o": 0.081,
"build/src/snd5.o": 0.077,
"build/src/snd6.o": 0.129,
"build/src/snd7.o": 0.097,
"build/src/snd8.o": 0.112,
"build/src/snd9.o": 0.103,
"build/src/ov_SC03_014/ov_SC03_014.o": 0.158,
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.693,
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.496,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.085,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.083,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.153,
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.215,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.153,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.103,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.095,
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.222,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.137,
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.185,
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.134,
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.109,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.096,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.158,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.577,
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.368,
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.123,
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.291,
"build/src/ov_SC03_014/ov_SC03_014_jr_801789AC.o": 0.077,
"build/src/ov_SC03_014/ov_SC03_014_jr_80178D40.o": 0.127,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.138,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.227,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.237,
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.11,
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.377,
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.093,
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.081,
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.136,
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.142,
"build/src/ov_SC03_015/ov_SC03_015.o": 0.137,
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.571,
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.522,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.054,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.108,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.142,
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.172,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.159,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.118,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.098,
"build/src/ov_SC03_015/ov_SC03_015_jr_80140608.o": 0.202,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.1,
"build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.211,
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.144,
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.126,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.078,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.148,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.54,
"build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.331,
"build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.131,
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.258,
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.063,
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.137,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.086,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.227,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.234,
"build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.067,
"build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.354,
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.106,
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.086,
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.076,
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.119,
"build/src/ov_SC04_011/ov_SC04_011.o": 0.207,
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.565,
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.427,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.094,
"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.146,
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.17,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.187,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.117,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.123,
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.204,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.103,
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.195,
"build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.141,
"build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.094,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.108,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.125,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.431,
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.274,
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.114,
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.216,
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.077,
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.122,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.072,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.128,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.486,
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.075,
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.068
"build/src/800.o": 0.728,
"build/src/800_b.o": 0.063,
"build/src/800_b_2.o": 0.275,
"build/src/800_b_o0a.o": 0.076,
"build/src/800_c.o": 0.193,
"build/src/800b2.o": 0.066,
"build/src/apicard1.o": 0.073,
"build/src/apicard2.o": 0.074,
"build/src/apicard3.o": 0.059,
"build/src/apicard4.o": 0.062,
"build/src/apicard5.o": 0.063,
"build/src/apicard6.o": 0.07,
"build/src/apicard7.o": 0.078,
"build/src/boot.o": 0.102,
"build/src/gap.o": 0.072,
"build/src/libapi1.o": 0.073,
"build/src/libapi2.o": 0.058,
"build/src/libc2_1.o": 0.059,
"build/src/libc2_2.o": 0.06,
"build/src/libcd1.o": 0.065,
"build/src/libcd2.o": 0.061,
"build/src/libetc.o": 0.07,
"build/src/libgpu.o": 0.058,
"build/src/libgpu2.o": 0.073,
"build/src/libgs1.o": 0.059,
"build/src/libgs2.o": 0.049,
"build/src/libgs3.o": 0.059,
"build/src/libgs4.o": 0.06,
"build/src/libgs5.o": 0.061,
"build/src/libgs6.o": 0.068,
"build/src/libgs7.o": 0.055,
"build/src/libgs8.o": 0.061,
"build/src/libgte1.o": 0.061,
"build/src/libgte10.o": 0.058,
"build/src/libgte11.o": 0.055,
"build/src/libgte12.o": 0.07,
"build/src/libgte13.o": 0.081,
"build/src/libgte14.o": 0.05,
"build/src/libgte15.o": 0.06,
"build/src/libgte16.o": 0.058,
"build/src/libgte17.o": 0.069,
"build/src/libgte18.o": 0.061,
"build/src/libgte19.o": 0.059,
"build/src/libgte2.o": 0.058,
"build/src/libgte20.o": 0.062,
"build/src/libgte21.o": 0.06,
"build/src/libgte22.o": 0.065,
"build/src/libgte23.o": 0.063,
"build/src/libgte24.o": 0.063,
"build/src/libgte25.o": 0.081,
"build/src/libgte26.o": 0.062,
"build/src/libgte27.o": 0.06,
"build/src/libgte28.o": 0.068,
"build/src/libgte29.o": 0.067,
"build/src/libgte3.o": 0.065,
"build/src/libgte30.o": 0.061,
"build/src/libgte4.o": 0.063,
"build/src/libgte5.o": 0.062,
"build/src/libgte6.o": 0.065,
"build/src/libgte7.o": 0.079,
"build/src/libgte8.o": 0.063,
"build/src/libgte9.o": 0.062,
"build/src/libmcrd1.o": 0.072,
"build/src/libmcrd2.o": 0.081,
"build/src/libpad1.o": 0.062,
"build/src/libpad2.o": 0.094,
"build/src/sgap.o": 0.066,
"build/src/sgap_2.o": 0.065,
"build/src/sgap_3.o": 0.075,
"build/src/sgap_4.o": 0.073,
"build/src/sgap_5.o": 0.067,
"build/src/sgap_6.o": 0.064,
"build/src/sgap_8.o": 0.07,
"build/src/snd1.o": 0.071,
"build/src/snd10.o": 0.067,
"build/src/snd11.o": 0.064,
"build/src/snd12.o": 0.063,
"build/src/snd2.o": 0.067,
"build/src/snd3.o": 0.06,
"build/src/snd4.o": 0.076,
"build/src/snd5.o": 0.064,
"build/src/snd6.o": 0.075,
"build/src/snd7.o": 0.063,
"build/src/snd8.o": 0.074,
"build/src/snd9.o": 0.07,
"build/src/ov_SC03_014/ov_SC03_014.o": 0.128,
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.488,
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.408,
"build/src/ov_SC03_014/ov_SC03_014_jr_80135888.o": 0.076,
"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.125,
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.16,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.117,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.08,
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.082,
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.164,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.069,
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.163,
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.09,
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.057,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.065,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.086,
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.465,
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.265,
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.097,
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.201,
"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.077,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.063,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.149,
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.196,
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.054,
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.251,
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.054,
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.059,
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.053,
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.058,
"build/src/ov_SC03_015/ov_SC03_015.o": 0.108,
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.472,
"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.048,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.052,
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.123,
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.131,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.099,
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.057,
"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.166,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.058,
"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.088,
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.064,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.063,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.089,
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.439,
"build/src/ov_SC03_015/ov_SC03_015_jr_8016AB6C.o": 0.255,
"build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.093,
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.201,
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.057,
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.088,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.063,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.169,
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.201,
"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.266,
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.047,
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.058,
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.052,
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.066,
"build/src/ov_SC04_011/ov_SC04_011.o": 0.102,
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.407,
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.328,
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.048,
"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.116,
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.137,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.111,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.069,
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.059,
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.173,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.068,
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.153,
"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.061,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.06,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.088,
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.345,
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.211,
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.092,
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.158,
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.053,
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.092,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.064,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.089,
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.419,
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.044,
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.046
},
"ok": true,
"seconds": 2.9
"seconds": 2.2
}
File diff suppressed because one or more lines are too long
+5 -8
View File
@@ -847,15 +847,12 @@ s32 func_800D1B10(u8 *arg0) {
*/
s32 func_800D1B80(u8 *arg0) {
extern s32 DsMix();
register s32 zr __asm__("$0"); // !FAKE: pin $0 — NEEDED DIFFERS (P36 rung B tus10)
s32 (*fp)(void);
u8 *p;
s32 (*fp)(u8 *);
fp = *(s32 (**)(void)) (arg0 + 0xC);
if (fp() != 0) {
p = arg0 + zr;
p[0x14] = arg0[0x14] + 1;
return DsMix(p);
fp = *(s32 (**)(u8 *)) (arg0 + 0xC);
if (fp(arg0) != 0) {
arg0[0x14]++;
return DsMix(arg0);
}
return 0;
}