mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
phase-36: T7 agent c42 — func_80186A8C and func_80182058 closed through cross-jump readings (10 bodies); related.txt requires evidence before calling a same-name body a variant (R22 218/218)
This commit is contained in:
@@ -7,10 +7,6 @@ s32 func_80182058(void *a0)
|
||||
u16 st;
|
||||
|
||||
if (func_8012BD14(*(s32 *)((s32)a0 + 0x64)) > 0x4000) {
|
||||
/* LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a).
|
||||
* Without it gcc's find_cross_jump merges this `move v0,0; j epi`
|
||||
* tail with the identical case-2 failure tail -> 58 ins instead of
|
||||
* 60, and the case-2 `beq` then loses its delay-slot fill. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,13 +17,13 @@ s32 func_80182058(void *a0)
|
||||
*(s16 *)((s32)p + 0x2) = 8;
|
||||
break;
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) != 1) {
|
||||
return 0;
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto hit;
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
hit:
|
||||
D_801EEAF0 = st;
|
||||
@@ -35,6 +31,9 @@ s32 func_80182058(void *a0)
|
||||
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x2) = 10;
|
||||
break;
|
||||
default:
|
||||
fail: /* the case-2/case-4 failures share this one `return 0`: a return
|
||||
* falling out of a conditional (as the first one does) is what
|
||||
* jump2's cross-jump would merge the early return into */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# func_80182058 (ov_SC03_001_jr_8017AE2C.c) — T7 agent c42 — score 10 -> 0, the barrier gone
|
||||
|
||||
## (a) The residual in one sentence
|
||||
COUNT 58 vs 60: the early `if (func_8012BD14(..) > 0x4000) return 0;` block (`j epi / move v0,zero`) is missing — mine
|
||||
branches `beqz v0` into the case-2 failure's `v0 = 0; j epi` block instead, and that block, now a join, loses the
|
||||
`move v0,zero` fill of the case-2 `beq` delay slot (a `nop` there). Every `j` offset after it shifts by 8.
|
||||
|
||||
## (b) The pass and the decision (read, then proven on `scratch/dumps_free`, `dumps_tree`, `dumps_w2` — `.greg` vs `.jump2`)
|
||||
Post-reload cross-jumping (`toplev.c:3142` `jump_optimize (insns, 1, 1, 0)`; `jump.c:1969-2000` simple jumps tried
|
||||
against every other jump to the same label, in chain order; `find_cross_jump` `jump.c:2371`, minimum 2).
|
||||
Every `return 0` is `(set v0 0)` + `(jump epi)`. Before jump2 the lever-free body has FOUR such blocks: A (the early
|
||||
return), B (case-2 failure), C (case-4 failure), D (the `default:`). A and C FALL OUT OF A CONDITIONAL JUMP whose label is
|
||||
right after them. A is processed first; against B: `v0=0` matches (1 insn, minimum 2->1), then both streams reach a
|
||||
JUMP_INSN (A's `if` jump 18 vs B's `beq` 54) that differ — and because jump 18's label follows A's own jump, the
|
||||
jump-around-jump discount fires (`jump.c:2516-2519`, `prev_real_insn (JUMP_LABEL (i1)) == e1`): minimum 0, A is MERGED
|
||||
INTO B (dumps_free `fn.jump2`: label 156 in front of B's insn 58, jump 18 retargeted there; C and D follow).
|
||||
The target (= the tree's barrier body, dumps_tree) merges everything INTO A instead: the asm insn before A's `v0=0` makes
|
||||
A's backward walk stop on an INSN-vs-JUMP code mismatch (`jump.c:2412`, no discount), so A finds no partner; D,
|
||||
preceded by its own label, then merges into A through the label discount (`jump.c:2406-2410`), and B follows once it is
|
||||
labelled. A survives in place, B becomes `beq hit / j A'` and reorg fills exactly as the target.
|
||||
|
||||
## (c) The move that closed it (10 -> 0, byte-proven)
|
||||
Route the case-2 and case-4 failures to the `default:` block's `return 0` instead of returning in place:
|
||||
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
hit: ...
|
||||
break;
|
||||
default:
|
||||
fail:
|
||||
return 0;
|
||||
|
||||
Now only TWO `v0=0; j epi` blocks reach jump2 (dumps_w2 `fn.greg`): A (after its conditional) and `fail` (after a
|
||||
barrier + label). A vs fail: 1 match, then JUMP_INSN vs BARRIER (the stream-2 walk skips the label) -> code mismatch,
|
||||
no discount, no merge. fail vs A: 1 match + its own label -> minimum 0 -> `fail` merged into A (dumps_w2 `fn.jump2`:
|
||||
new `code_label 150` before A's insn 22, jumps 115/121/62/70 all retargeted to 150). The target's jump graph exactly.
|
||||
No asm, no pin, no volatile, no invented term; the stale "LOAD-BEARING barrier" comment is dropped (refuted).
|
||||
|
||||
## (d) GENERATOR PROPOSAL
|
||||
When a `__asm__ __volatile__("")` cross-jump barrier sits before an early `if (..) return K;` and several OTHER
|
||||
`return K;` statements also fall out of conditionals (`if (..) return K;` inside switch cases / if-chains), rewrite those
|
||||
others as `goto fail;` to ONE labelled `return K;` (the switch `default:` if it already returns K, else a new label after
|
||||
the last statement): a labelled block can only be merged INTO the early return (label discount, `jump.c:2406`), never the
|
||||
reverse, while fall-out-of-conditional returns carry the jump-around-jump discount (`jump.c:2518`) that lets the FIRST
|
||||
return in insn order be merged away. Keep each branch's polarity: `if (ok) goto hit; goto fail;` (w1's
|
||||
`if (!ok) goto fail; goto hit;` scores 2 — the `beq`/`bne` inverts).
|
||||
|
||||
## (e) What did NOT work (byte evidence)
|
||||
* w1 (`if (x != 1) goto fail; goto hit;` in case 2): 2 — right jump graph, inverted case-2 branch (`bne ..,epi` + `j hit`).
|
||||
* w4 (case 2 via `fail`, case 4 keeps `return 0;`): 11 — C is still a fall-out-of-conditional return; A merges into C.
|
||||
* w6 (`fail:` as a trailing `return 0;` after the final return, default keeps its own): 11 — A merges again.
|
||||
* w3 (switch restructured so failures `break` to a `return 0` after the switch, successes `goto done`): 12 — layout moves.
|
||||
* The mechanical search (646 compiles, R7/R8/R10) has no move that re-targets a `return` to a shared label.
|
||||
|
||||
## (f) Where the method fell short
|
||||
* The METHOD's cross-jump entries (c6/c10/c15) speak of merges the target keeps apart and of SHAPES made to differ; this
|
||||
one is about merge DIRECTION: the same two blocks merge either way, and which survives is decided by which one owns
|
||||
the discount (`jump.c:2406` label vs `:2518` jump-around-jump) and by insn order. Reading `.greg` (pre-jump2) against
|
||||
`.jump2` for the surviving `code_label` settled it in one comparison — worth a METHOD line: "for a cross-jump
|
||||
residual, find the SURVIVOR label in `.jump2` for both the tree body and yours".
|
||||
* The TU/comment note ("LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a)") was a claim; refuted on bytes.
|
||||
|
||||
Paths: body `.run/P36/agents/ov_SC03_001__func_80182058/body.c`; dumps `scratch/dumps_free/`, `scratch/dumps_tree/`,
|
||||
`scratch/dumps_w2/`; variants `scratch/w1..w6.c`.
|
||||
@@ -6,7 +6,7 @@ Same 230 instructions; at both `func_8012B178(a0, t - 0x4000)` sites the target
|
||||
COUNT: 230 = 230, nothing missing — a pure ORDER residual of two insns, twice.
|
||||
|
||||
## (b) The passes and decisions (read, then proven on dumps `scratch/dumps_free`, `scratch/dumps_v1`)
|
||||
* `calls.c:1879-1889` (gcc-2.7.2): MIPS has no `PUSH_ROUNDING`, so `PUSH_ARGS_REVERSED` is NOT defined (`calls.c:38-44`); the
|
||||
* `calls.c:1860-1881` (gcc-2.7.2): MIPS has no `PUSH_ROUNDING`, so `PUSH_ARGS_REVERSED` is NOT defined (`calls.c:38-44`); the
|
||||
hard-register loads are emitted in argument order, `$4 = a0` then `$5 = value` (dumps_free `fn.rtl` insns 163, 165).
|
||||
* combine (`can_combine_p`, `combine.c:880-930`): the separate `av = t - 0x4000` insn (160) is folded into the `$5 = av`
|
||||
arg-move (165), which sits AFTER `$4 = a0` — so the subtract becomes the last insn before the call (dumps_free `fn.combine`).
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
void func_80183E3C(s32 a0) {
|
||||
|
||||
extern u8 D_800AF648;
|
||||
extern s32 D_801A73BC;
|
||||
extern s32 D_8019989C;
|
||||
extern s32 D_80199B70;
|
||||
extern u16 D_80126B62;
|
||||
/* sp+0x10 local block. Frame is 0x38 = 0x10 outgoing args + 0x20 vars +
|
||||
* 8 saved regs ($s0,$ra), so the vars block is 12 bytes larger than the
|
||||
* fields this function actually touches -> trailing `unused[3]`. */
|
||||
struct {
|
||||
s16 v[3]; /* sp+0x10 */
|
||||
s16 pad0; /* sp+0x16 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
s32 unused[1]; /* sp+0x24 */
|
||||
} L;
|
||||
s16 x;
|
||||
s32 y;
|
||||
|
||||
if (*(s32 *)(a0 + 0x94) == 0xD) {
|
||||
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
|
||||
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
|
||||
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
|
||||
/* The target loads &D_800AF648 afresh (lui/addiu $a0) for EACH call. The
|
||||
* second call names the object through a second declaration of the same
|
||||
* symbol: its SYMBOL_REF string is a different pointer, so cse does not
|
||||
* unify the two address pseudos into one callee-saved register. */
|
||||
func_8004914C(&D_800AF648);
|
||||
{
|
||||
extern u8 D_800AF648_b __asm__("D_800AF648");
|
||||
func_800491AC(&D_800AF648_b);
|
||||
}
|
||||
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
|
||||
if (L.flag >= 0 && (u32)((L.sxy[0] + 0x9F) & 0xFFFF) < 0x13F
|
||||
&& (u32)((L.sxy[1] + 0x77) & 0xFFFF) < 0xEF) {
|
||||
s32 vol = (s16)L.sxy[0];
|
||||
if (vol < 0) {
|
||||
vol = -vol;
|
||||
}
|
||||
vol = ((0xA0 - vol) * 127) / 160;
|
||||
func_8002D4C8(0x702, (vol | 0x1000) & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (func_8012BCCC(a0) <= 0x24000) {
|
||||
s16 c;
|
||||
c = *(u16 *)(a0 + 0x102) + 1;
|
||||
*(s16 *)(a0 + 0x102) = c;
|
||||
if (c >= 0x78) {
|
||||
if ((*(u16 *)(a0 + 0x100) & 0x2000) == 0) {
|
||||
func_8012A828(a0, (s32)&D_801A73BC);
|
||||
*(s16 *)(a0 + 0x2) = 10;
|
||||
*(s16 *)(a0 + 0x102) = 0;
|
||||
*(s32 *)(a0 + 0x58) = (s32)&D_8019989C | 0x40000000 | 0x20000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012B8E4(a0, 0x10);
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) &= 0xFFF;
|
||||
|
||||
x = *(s16 *)(a0 + 0xA);
|
||||
y = *(s16 *)&D_80126B62;
|
||||
if (x <= y - 0x100) {
|
||||
*(s16 *)(a0 + 0xA) = x + 0x8;
|
||||
} else if (x >= y - 0x80) {
|
||||
*(s16 *)(a0 + 0xA) = x - 0x8;
|
||||
}
|
||||
|
||||
func_8012B1B4(a0, (s32)&D_80199B70);
|
||||
func_8012CBCC(a0);
|
||||
}
|
||||
@@ -33,6 +33,7 @@ s16 y;
|
||||
u32 c;
|
||||
u16 bb;
|
||||
u32 c0;
|
||||
u32 w;
|
||||
|
||||
mk1 = 0xFFFFFF;
|
||||
cc1 = 0x74808080;
|
||||
@@ -50,10 +51,12 @@ s16 y;
|
||||
yt = y;
|
||||
c0 = yt + 1;
|
||||
c0 <<= 16;
|
||||
w = c0 | x1;
|
||||
__asm__("" : "=r"(w) : "0"(w)); // !FAKE: launder w — sched1 launches a single-set p[2] value right before its store (birthing_insn_p, sched.c:2469) and sched2 ties the or/ori at equal priority and falls back to sched1's order (sched.c:2385); the asm's second set of w keeps it ahead of the cl chain, no plain spelling reorders them (S103 c19) (P36 S103 c46 minimum-lever)
|
||||
c = v << 6;
|
||||
c |= 0x4016;
|
||||
cl = c << 16;
|
||||
p[2] = c0 | x1;
|
||||
p[2] = w;
|
||||
p[3] = cl | 0x1800;
|
||||
p += 5;
|
||||
p[0] = (((u32)(p - 5)) & mk1) | ca;
|
||||
|
||||
@@ -35,7 +35,7 @@ void func_8017D000(void *a0) {
|
||||
s32 t;
|
||||
|
||||
s16 *p;
|
||||
void *w;
|
||||
s16 *r;
|
||||
|
||||
if (cur != lo) {
|
||||
if (lo < cur) {
|
||||
@@ -72,7 +72,7 @@ void func_8017D000(void *a0) {
|
||||
|
||||
if (*(s16 *)((s32)a0 + 0xFC) == 0xB) {
|
||||
s32 f = *(s32 *)((s32)a0 + 0x1C);
|
||||
s32 v = -(f & 1) & 0xC0;
|
||||
u8 v = -(f & 1) & 0xC0;
|
||||
f = f + 1;
|
||||
*(s32 *)((s32)a0 + 0x1C) = f;
|
||||
D_801EED51 = v;
|
||||
@@ -100,6 +100,7 @@ void func_8017D000(void *a0) {
|
||||
u16 bs;
|
||||
s32 x;
|
||||
s16 y;
|
||||
s16 *s;
|
||||
t = (c - h) * 255 / h;
|
||||
q = &D_801EED4D;
|
||||
bs = (u16)D_801EED28;
|
||||
@@ -107,7 +108,8 @@ void func_8017D000(void *a0) {
|
||||
y = x - 4;
|
||||
D_801EED55 = 0xFF;
|
||||
*q = 0xFF;
|
||||
*(s16 *)(q + 0xF) = x;
|
||||
s = (s16 *)(q + 0xF);
|
||||
*s = x;
|
||||
D_801EED64 = bs + c;
|
||||
D_801EED30 = x;
|
||||
D_801EED6C = y;
|
||||
@@ -115,14 +117,13 @@ void func_8017D000(void *a0) {
|
||||
D_801EED74 = bs + c - 4;
|
||||
D_801EED88 = -t;
|
||||
D_801EED80 = -t;
|
||||
func_800176F0(q + 0xF);
|
||||
func_800176F0(s);
|
||||
}
|
||||
|
||||
p = &D_801EEDA8;
|
||||
D_801EED98 = *(u16 *)((s32)p - 0x18) + (u16)D_80193E88;
|
||||
r = p - 0xC;
|
||||
D_801EED98 = *(u16 *)r + (u16)D_80193E88;
|
||||
*p = D_801EED98 - 4;
|
||||
w = (void *)((s32)p - 0x80);
|
||||
p = (s16 *)((s32)p - 0x18);
|
||||
func_800176F0(w);
|
||||
func_800176F0(p);
|
||||
func_800176F0(p - 0x40);
|
||||
func_800176F0(r);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# func_8017D000 (ov_SC04_011, TU ov_SC04_011_jr_8017AE2C.c) — T7 agent c44
|
||||
|
||||
**Result: score 0, lever-free.** No register pin, no asm, no added volatile, no do-while, no invented term, no dead
|
||||
assignment. The fix is inside the function body only. Whole-object check on the `--try --keep` object: `objdump -drz` of the
|
||||
ENTIRE `.o` (every function, relocations included) is identical to `.run/P36/delever/baseline/src/ov_SC04_011/
|
||||
ov_SC04_011_jr_8017AE2C.o`, and `.text` compares equal with `cmp`. Candidates are in `scratch/` (`a1.c`, `b1.c`, `c1.c`,
|
||||
`d1.c` = `body.c`, `e1.c`) with their `.dis`; the pass dumps are in `scratch/dumps_free/` and `scratch/dumps_d1/`.
|
||||
|
||||
No lever-free copy existed elsewhere: `git grep` finds no other definition that touches `D_801EEDA8`, and
|
||||
`related.txt` listed no port candidate (the only `func_8017D000` in `src/shared/ov/` is an unrelated function with the same
|
||||
overlay address).
|
||||
|
||||
## (a) The residual in one sentence
|
||||
|
||||
COUNT 296 vs 293. There were three independent defects. (1) In the `== 0xB` arm, `f` and `v` had swapped registers and
|
||||
`f + 1; sw` was hoisted above `negu; andi 0xc0`. (2) In the else arm, `*(s16 *)(q + 0xF) = x` became an absolute
|
||||
`lui at; sh v0,15(at)` (+1) where the target writes `sh v0,15(a2)`. As a result `addiu a0,a2,15` left the `jal` delay
|
||||
slot (+1 `nop`). (3) In the tail, `*(u16 *)(p - 0x18)` became an absolute `lui v0; lhu v0,-24(v0)` (+1) where the target
|
||||
reads `lhu v0,-24(s0)`.
|
||||
|
||||
## (b) The passes and the decisions (all three proven on bytes and in dumps)
|
||||
|
||||
### Defects 2 and 3: cse folds a base+offset MEM address into an absolute address. A register address is not folded.
|
||||
|
||||
* `find_best_addr` (cse.c:2621). An address that is not a bare REG is first run through `fold_rtx` and accepted by
|
||||
`validate_change` with NO cost test (cse.c:2659-2662). `p` / `q` carry the constant equivalence `&SYM`, so
|
||||
`(plus p -24)` folds to `(const (plus SYM -24))`, which is a valid MIPS address (the assembler's `lui at` macro). This is
|
||||
why the tree needed the three launders.
|
||||
* A BARE REG address skips that fold. For a REG, cse looks up the register's equivalence class and takes the member with
|
||||
the lowest `ADDRESS_COST`, breaking ties by the higher `rtx_cost` (cse.c:2708-2735). `ADDRESS_COST(REG)=1`
|
||||
(mips.h:2895), `(plus reg small_int)`=1, and `(const (plus sym k))`=2 (`mips_address_cost`, mips.c:1615-1653). So
|
||||
for `s = q + 15; *s = x;` the class of `s` is {`s`, `(plus q 15)`, `(const D_801EED4D+15)`}. The tie at cost 1 goes to
|
||||
`(plus q 15)` (the higher rtx_cost). The constant, at cost 2, is never chosen. Dump proof: `dumps_d1/d1.i.rtl` insn 433
|
||||
is `(set (mem:HI (reg 240)) …)`, and `d1.i.cse` rewrites it as `(set (mem:HI (plus (reg 236) 15)) …)`. The tail
|
||||
behaves the same way: insn 485 becomes `(mem:HI (plus (reg 86) -24))`.
|
||||
* After that, the pointer temp's only other use is the call argument. The `(set s (plus q 15))` insn stays where the
|
||||
source put it, just before the call (it is kept as a PLUS because `rtx_cost` of the CONST is higher). So reorg puts
|
||||
`addiu a0,a2,15` back into the `jal` delay slot, and the tail's `r` ties to `p`'s `$s0` (`addiu s0,s0,-24` in the
|
||||
first `jal`'s delay slot), as in the target.
|
||||
|
||||
### Defect 1: sched1's `birthing_insn_p` boost. The `u8` width removes it.
|
||||
|
||||
* With `s32 v`, the last insn of the chain (`v = t & 0xC0`) is a SET of a REG that is live after it and set only once.
|
||||
`birthing_insn_p` (sched.c:2468-2499) returns 1 for it, and `adjust_priority` (sched.c:2539-2545) raises it to
|
||||
`max_priority` when it becomes ready in the backward list scheduler. So the `v` chain is placed right before its first
|
||||
`sb`, and `f + 1; sw` is scheduled above `negu/andi` (`dumps_free/free.i.lreg`: order 255 257 **262 265** 258 259 268).
|
||||
* With `u8 v` (the width of every destination it is stored to), combine folds the truncating move into the `and`, and
|
||||
that insn's destination becomes `(subreg:SI (reg:QI 191) 0)`. `birthing_insn_p` wants `GET_CODE (SET_DEST) == REG`,
|
||||
so it gets no boost, and sched1 keeps source order: 255 259 262 269 272 275 278 (`dumps_d1/d1.i.sched`). Local-alloc
|
||||
then gives `v` `$v0` and `f` `$v1`, as in the target. This is the same fact the tree's asm launder was forcing: an asm
|
||||
output is not a plain birthing SET of the chain.
|
||||
|
||||
## (c) The source moves that closed it (three, independent; the scores are additive)
|
||||
|
||||
1. `s32 v = -(f & 1) & 0xC0;` → `u8 v = …` (the width of the ten `u8` stores). 33 → 17 (`a1.c`).
|
||||
2. Else arm: `s16 *s = (s16 *)(q + 0xF); *s = x; … func_800176F0(s);` instead of `*(s16 *)(q + 0xF) = x; …
|
||||
func_800176F0(q + 0xF);`. On top of 1: 17 → 2 (`c1.c`).
|
||||
3. Tail: `r = p - 0xC; D_801EED98 = *(u16 *)r + (u16)D_80193E88; *p = D_801EED98 - 4; func_800176F0(p - 0x40);
|
||||
func_800176F0(r);` instead of the reassigned `p` + `w`. On top of 1: 17 → 15 (`b1.c`). 1+2+3: **0** (`d1.c`).
|
||||
Control: 2+3 without 1 = 16 (`e1.c`, MIXED), so move 1 is exactly defect 1.
|
||||
|
||||
## (d) GENERATOR PROPOSALS
|
||||
|
||||
* **COUNT +1 `lui at` / `lui vN` on an offset load/store where the target uses `k(reg)` of a pointer that holds `&SYM`:**
|
||||
name the offset address as a pointer local (`T *s = (T *)(base + k); *s = …`), and if the target also passes
|
||||
`base + k` to a call, pass `s` there. cse's `find_best_addr` keeps a register address as `(plus base k)` (cost tie,
|
||||
cse.c:2715-2721) but folds a written-out `base + k` to an absolute address (cse.c:2659). This is the plain-C
|
||||
replacement for the `__asm__("" : "=r"(p) : "0"(p))` launder whenever the pointer's other uses are call arguments.
|
||||
* **ORDER + swapped `$v0/$v1` where the target computes a value's whole chain before an unrelated `x+1; sw`:** if the
|
||||
value is only stored narrow (`sb`/`sh`), declare it with the store width (`u8`/`s16`). The subreg destination stops
|
||||
sched1's birthing boost (sched.c:2468-2545). Test: `.lreg` shows the chain's last insn scheduled right before its first
|
||||
use.
|
||||
|
||||
## (e) What did not work (byte evidence)
|
||||
|
||||
* `*(s32 *)(a0 + 0x1C) = f + 1;` with `f` not reassigned: 21 (`a2.c`). Worse, because the register swap stays.
|
||||
* `b1.c` (tail only, on top of move 1): 15. That fixes the tail's `lui`; the else arm's absolute `sh` + `nop` remain.
|
||||
* The mechanical search's best (15, a do-while + `R8 base tmp0`) never tried a pointer local on a MEM address. Its
|
||||
`R12 width t` moves narrowed `t`, not `v`.
|
||||
|
||||
## (f) Where the method fell short
|
||||
|
||||
* METHOD_S103's launder list (c11: "write the read relative to a DERIVED pointer") describes the case where the pointer
|
||||
is NOT known constant to cse. Here the pointer IS a known constant in the same block, and the answer is simpler:
|
||||
make the address itself a REGISTER. `find_best_addr` never folds a REG, only non-REG addresses (cse.c:2659 vs
|
||||
:2708-2735). This should be the FIRST launder move tried: it is one line and needs no pass-ordering conditions.
|
||||
* COUNT-first worked: the three extras were one `lui at`, one `nop`, and one `lui v0`, each visible only in the whole
|
||||
objdump (the hunk view split the `sh 15(a2)` across two hunks).
|
||||
@@ -0,0 +1,47 @@
|
||||
s32 func_80185578(s32 arg0, s32 arg1) {
|
||||
extern u8 D_801BD0C4[];
|
||||
extern s32 D_801BD2FC[];
|
||||
extern u8 D_800D3918[];
|
||||
extern void func_80187414(s32 a0, void *a1, void *a2, s32 a3);
|
||||
extern void func_801873B0(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5);
|
||||
extern void func_8001C924(s32 a0, void *a1);
|
||||
u8 buf[8];
|
||||
s16 y = arg1;
|
||||
s32 res;
|
||||
s16 state;
|
||||
s32 flags;
|
||||
|
||||
state = *(u16 *)(arg0 + 0x70) & 0xF;
|
||||
flags = *(u32 *)(arg0 + 0xE0);
|
||||
if (flags & 4) {
|
||||
return 0;
|
||||
}
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (flags & 1) {
|
||||
func_80187414(arg0, D_801BD0C4, buf, 0xC);
|
||||
res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_801873B0)(arg0, buf, 0x27F, (s16)arg1, 0, 0);
|
||||
*(s32 *)(arg0 + 0xD0) = res;
|
||||
*(u32 *)(arg0 + 0xE0) &= ~1;
|
||||
if (res != 0) {
|
||||
*(u16 *)(arg0 + 0xEE) = *(u16 *)(res + 0x36);
|
||||
}
|
||||
}
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
func_80187414(arg0, D_800D3918, buf, 0xB);
|
||||
res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_801873B0)(arg0, buf, 0x27F, (s16)(y | (state + 1)), 0, 0);
|
||||
*(s32 *)(arg0 + 0xCC) = res;
|
||||
*(u32 *)(arg0 + 0xE0) |= 4;
|
||||
func_8001C924(*(s32 *)(arg0 + 0x20), (void *)D_801BD2FC[state]);
|
||||
if (res != 0) {
|
||||
*(u16 *)(arg0 + 0xEC) = *(u16 *)(res + 0x36);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
# func_80185578 (ov_SC06_022, 6 copies): closed lever-free — it returns int, and `y` is an s16 (agent c43, S103)
|
||||
|
||||
**Result: score 0, and the whole object is byte-identical (`objdump -drz -s` diff empty), BUT THE CLOSE NEEDS A CHANGE
|
||||
OUTSIDE THE BODY.** The function returns a value, so its three in-TU declarations have to say `s32` instead of
|
||||
`void`:
|
||||
- `src/ov_SC06_022/ov_SC06_022_jr_80184A28.c:2998` `extern void func_80185578(s32 a0, s32 a1);` → `extern s32 ...`
|
||||
- `:3288` and `:3289` (the two "SIMULATION of real-TU context" rows right above the definition) → `extern s32 ...`
|
||||
|
||||
`PACK/body.c` is the definition (it gives `conflicting types` under `--body` while those rows still say void).
|
||||
`PACK/body_tu.c` is the whole TU with the three rows retyped, and scores 0 via `--try` without `--body`. The other two
|
||||
TUs that declare it (`ov_SC06_022_jr_80184304.c:2978`, `ov_SC06_022_jr_80182D08.c:3605`) are byte-identical either
|
||||
way (whole-object diffs empty with the rows retyped: `scratch/decl_*.c`), so they can be retyped for consistency or
|
||||
left alone. Their callers discard the result.
|
||||
|
||||
**Transfer: all 6 copies score 0, and each whole object is byte-identical**, with the same edit plus that TU's own
|
||||
declarations retyped (`scratch/xfer.py`; 3-4 rows per TU). The copies are ov_SC06_018 func_801874E4, SC06_020
|
||||
func_80181654, SC06_022 func_80185578, SC06_024 func_80187A50, SC06_032 func_80182288, SC06_033 func_80185F6C.
|
||||
|
||||
## (a) The residual (counted first: mine 90, target 94)
|
||||
Two independent defects:
|
||||
1. **A missing `move s3,s0`** (the `y = x` copy). The target keeps `x` in `$s0`, shared later with `res`, and `y` in
|
||||
`$s3`. Lever-free, `y` and `x` became ONE pseudo (`move s2,a1`), and every register downstream shifts. The tree's
|
||||
`addu y, x, $zero` asm faked that copy.
|
||||
2. **Missing `$v0` writes**: `move v0,zero` on the `flags & 4` path and `li v0,1` on the other paths. The function
|
||||
RETURNS 0 ("already set up", bit 2 of +0xE0) or 1. The tree declared it `void` and faked the return value with a
|
||||
keepalive asm `"r"(rv)` after an `epi:` label.
|
||||
|
||||
## (b) The passes (proved on dumps: `scratch/dumps_r6/` vs `scratch/dumps_r6s/`)
|
||||
1. The copy: with `s32 y`, `.rtl` insn 13 is `(set (reg:SI 74) (reg:SI 73))`, and cse1's `(set REG0 REG1)` case
|
||||
(cse.c:7440-7474, gate :7455 wants a REG source) retargets the previous insn: `.cse` insn 6 becomes
|
||||
`(set (reg 74) (reg:SI 5 a1))` and the copy disappears. With `s16 y`, the insn is
|
||||
`(set (reg:HI 74) (subreg:HI (reg:SI 73) 0))`. Its source is a SUBREG, not a REG, so the gate fails and the copy
|
||||
survives cse (`.cse` insn 13, `movhi_internal2`). It's a separate pseudo, so it gets `$s3` while `arg1` keeps
|
||||
`$s0` and dies into the case-0 call. This is METHOD c4's width mechanism exactly: there's no PROMOTE_MODE, so the
|
||||
s16 local is an HImode pseudo.
|
||||
2. The return value: `return 0` / `return 1` on an `s32` function sets `$2` on every path, which a void function
|
||||
can't do. No pass is involved; the bytes just prove the function has a return value.
|
||||
|
||||
What's proved on bytes: `r1` (s32 return, s32 y) = 16 [COUNT, 93 vs 94], which is the copy alone.
|
||||
`r2`/`r3`/`r5`/`r6` (s32 return plus u16/s16 y, in several spellings) = 0. `r6s` (r6 with `s32 y`) = 16.
|
||||
`r7` (no `y`, `arg1` used directly) = 16. history.txt's `y s32->u16` alone = 11, which is the width without the
|
||||
return value.
|
||||
|
||||
## (c) The moves (a JOINT close; neither alone reaches 0)
|
||||
- `void` → `s32`, with `return 0;` / `return 1;` in place of `rv = …; goto epi;` (plus the declarations above).
|
||||
- `s16 y = arg1;` replaces `s32 x = arg1; s32 y; y = x;`, and case 0 passes `(s16)arg1`. `x` goes away entirely:
|
||||
the parameter IS `x`.
|
||||
|
||||
## (d) GENERATOR PROPOSAL
|
||||
Two rules. (1) **When a `void` function's tree body ends in a keepalive `__asm__ volatile("" : : "r"(v))` on a
|
||||
0/1 (or constant) variable assigned before gotos to the end label, the function returns that value.** Retype the
|
||||
definition and every in-TU `extern void` row to `s32`, turn `v = K; goto end;` into `return K;`, and score the
|
||||
WHOLE TU (`--try` without `--body`). Callers that discard the result don't change bytes (checked in 2 TUs here).
|
||||
Sizing grep: `grep -rn '__asm__ volatile("" : : "r"(rv))' src` = 6 (exactly this class). The wider
|
||||
`grep -rn '__asm__ volatile("" : : "r"(' src | grep keepalive` = 19; not every one of those is a return value, so
|
||||
check each target for `$v0` writes before the epilogue. (2) When a `y = x` copy of a parameter is
|
||||
missing and `y` is only used under a `(s16)`/`(u16)` cast, declare `y` s16/u16 (R20) — AFTER rule 1, because a
|
||||
missing return value adds COUNT noise that hides whether the width move worked (history's `y->u16` scored 11 and
|
||||
the search stopped there).
|
||||
|
||||
## (e) Tried and did not work (bytes)
|
||||
- Every body-only variant: the return value can't be produced in a void function without a lever. I didn't try a
|
||||
`volatile` or asm.
|
||||
- `r1`: s32 return with `s32 y` = 16. `r7`: drop `y` = 16. Both lose the copy (the cse.c:7455 swap).
|
||||
|
||||
## (f) Where the method fell short
|
||||
- Counting first found it straight away: 4 missing = 1 copy + 3 `$v0` writes. But the brief's goal ("no change
|
||||
outside the body") is unreachable for any function the decomp mis-declared as `void`, and the `--body` scorer
|
||||
can't express the fix at all: it compiles `conflicting types`. The mechanical search (history.txt) ran 1,127
|
||||
compiles on body-only moves that could never have reached 0.
|
||||
- METHOD has no row for "keepalive asm = a missing return value". It should come FIRST in the COUNT branch: the
|
||||
`$v0` writes are the cheapest instructions to account for, and one look at the target (`move v0,zero` in a `j`
|
||||
delay slot, `li v0,1` before the epilogue) settles it.
|
||||
- The tree's rows at `:3287-3289` ("SIMULATION of real-TU context") are two duplicate `extern void` declarations.
|
||||
They are the lines that have to change, and the sibling TUs carry 3-4 such rows each.
|
||||
@@ -54,7 +54,7 @@
|
||||
},
|
||||
"kinds": {
|
||||
"asm-body/direct": 13,
|
||||
"barrier/direct": 1934,
|
||||
"barrier/direct": 1929,
|
||||
"barrier/via-macro": 2,
|
||||
"gte-lever/direct": 362,
|
||||
"gte-lever/via-macro": 100,
|
||||
@@ -72,26 +72,26 @@
|
||||
"binaries": 218,
|
||||
"classes": {
|
||||
"A": {
|
||||
"bodies": 2334,
|
||||
"distinct_bodies": 869,
|
||||
"bodies": 2329,
|
||||
"distinct_bodies": 868,
|
||||
"file_scope": 0,
|
||||
"in_bodies": 6910,
|
||||
"in_bodies": 6900,
|
||||
"kinds": {
|
||||
"pin": 6910
|
||||
"pin": 6900
|
||||
},
|
||||
"marked": 6910,
|
||||
"sites": 6910,
|
||||
"marked": 6900,
|
||||
"sites": 6900,
|
||||
"tus": 1416,
|
||||
"unmarked": 0
|
||||
},
|
||||
"B": {
|
||||
"bodies": 5024,
|
||||
"distinct_bodies": 857,
|
||||
"bodies": 5019,
|
||||
"distinct_bodies": 856,
|
||||
"file_scope": 13,
|
||||
"in_bodies": 14623,
|
||||
"in_bodies": 14618,
|
||||
"kinds": {
|
||||
"asm-body": 13,
|
||||
"barrier": 1936,
|
||||
"barrier": 1931,
|
||||
"gte": 6858,
|
||||
"gte-lever": 462,
|
||||
"gte-unsigned": 3,
|
||||
@@ -100,9 +100,9 @@
|
||||
"launder": 1801,
|
||||
"verbatim-body": 2682
|
||||
},
|
||||
"marked": 5359,
|
||||
"sites": 14636,
|
||||
"tus": 1599,
|
||||
"marked": 5354,
|
||||
"sites": 14631,
|
||||
"tus": 1596,
|
||||
"unmarked": 9277
|
||||
},
|
||||
"C": {
|
||||
@@ -207,9 +207,9 @@
|
||||
"coverage": {
|
||||
"asm": {
|
||||
"comment_dead": 6786,
|
||||
"live": 22548,
|
||||
"live": 22533,
|
||||
"macro_block": 194,
|
||||
"raw": 29528
|
||||
"raw": 29513
|
||||
},
|
||||
"attribute": {
|
||||
"comment_dead": 0,
|
||||
@@ -225,9 +225,9 @@
|
||||
},
|
||||
"register": {
|
||||
"comment_dead": 8565,
|
||||
"live": 6960,
|
||||
"live": 6950,
|
||||
"macro_block": 18,
|
||||
"raw": 15543
|
||||
"raw": 15533
|
||||
},
|
||||
"volatile": {
|
||||
"comment_dead": 2476,
|
||||
@@ -237,7 +237,7 @@
|
||||
}
|
||||
},
|
||||
"coverage_ok": true,
|
||||
"elapsed_s": 29.7,
|
||||
"elapsed_s": 31.0,
|
||||
"generated": "2026-09-10",
|
||||
"gte_levers": {
|
||||
"direct": 362,
|
||||
@@ -248,15 +248,15 @@
|
||||
"via_macro": 100,
|
||||
"what": "GTE ops whose clobbers exceed the canonical macro's (a scheduling steer): class-B levers INSIDE the headline number since T5 (2026-09-09), marked, 0 at the close"
|
||||
},
|
||||
"head": "321b540e7",
|
||||
"head": "2a4f28f83",
|
||||
"headers": 3181,
|
||||
"levers_AB": {
|
||||
"asm": 5093,
|
||||
"bodies": 3060,
|
||||
"distinct_bodies": 1160,
|
||||
"marked": 12003,
|
||||
"pins": 6910,
|
||||
"sites": 12003,
|
||||
"asm": 5088,
|
||||
"bodies": 3050,
|
||||
"distinct_bodies": 1158,
|
||||
"marked": 11988,
|
||||
"pins": 6900,
|
||||
"sites": 11988,
|
||||
"unmarked": 0,
|
||||
"what": "register pins + asm statements excluding GTE ops: the classes the phase drives to 0"
|
||||
},
|
||||
@@ -412,7 +412,7 @@
|
||||
"$29": 13,
|
||||
"$3": 698,
|
||||
"$4": 1045,
|
||||
"$5": 969,
|
||||
"$5": 959,
|
||||
"$6": 212,
|
||||
"$7": 175,
|
||||
"$8": 170,
|
||||
@@ -423,30 +423,30 @@
|
||||
"v0": 2,
|
||||
"v1": 3
|
||||
},
|
||||
"sites": 6910,
|
||||
"sites": 6900,
|
||||
"sp": 13,
|
||||
"spelling": {
|
||||
"__asm__": 6853,
|
||||
"__asm__": 6843,
|
||||
"asm": 57
|
||||
},
|
||||
"volatile_qualified": 3,
|
||||
"zero": 106
|
||||
},
|
||||
"src_stamp": "7552158a131a0fab",
|
||||
"src_stamp": "43d7810b6d23cc55",
|
||||
"tus": 4121,
|
||||
"unclassified": 0,
|
||||
"union_AD": {
|
||||
"bodies": 6586,
|
||||
"bodies": 6576,
|
||||
"by_kind": {
|
||||
"main": 165,
|
||||
"md": 133,
|
||||
"ov": 6097,
|
||||
"ov": 6087,
|
||||
"resident": 10,
|
||||
"shared": 181
|
||||
},
|
||||
"copies_in_multi": 5351,
|
||||
"distinct_bodies": 1450,
|
||||
"multi_copy_classes": 215
|
||||
"copies_in_multi": 5341,
|
||||
"distinct_bodies": 1448,
|
||||
"multi_copy_classes": 213
|
||||
},
|
||||
"verbatim_excluded": {
|
||||
"functions": 13,
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
lever_census: 218 binaries · 4,121 TUs + 3,181 headers · coverage OK · unclassified 0 · verbatim excluded 13 fn / 14 sites (manifest 13)
|
||||
coverage asm raw 29528 = live 22548 + macro-block 194 + comment/dead 6786
|
||||
coverage register raw 15543 = live 6960 + macro-block 18 + comment/dead 8565
|
||||
coverage asm raw 29513 = live 22533 + macro-block 194 + comment/dead 6786
|
||||
coverage register raw 15533 = live 6950 + macro-block 18 + comment/dead 8565
|
||||
coverage volatile raw 4448 = live 1890 + macro-block 82 + comment/dead 2476
|
||||
coverage builtin raw 599 = live 445 + macro-block 0 + comment/dead 154
|
||||
coverage attribute raw 76 = live 76 + macro-block 0 + comment/dead 0
|
||||
class sites in-bodies file-scope bodies distinct TUs marked unmarked kinds
|
||||
A pins 6910 6910 0 2334 869 1416 6910 0 {'pin': 6910}
|
||||
B asm 14636 14623 13 5024 857 1599 5359 9277 {'launder': 1801, 'barrier': 1936, 'keepalive': 645, 'gte': 6858, 'gte-lever': 462, 'instruction': 236, 'asm-body': 13, 'gte-unsigned': 3, 'verbatim-body': 2682}
|
||||
C volatile 1590 1438 152 496 95 610 14 1576 {'decl-body': 58, 'cast': 1378, 'decl-file': 152, 'param': 2}
|
||||
A pins 6900 6900 0 2329 868 1416 6900 0 {'pin': 6900}
|
||||
B asm 14631 14618 13 5019 856 1596 5354 9277 {'barrier': 1931, 'launder': 1801, 'keepalive': 645, 'gte': 6858, 'gte-lever': 462, 'gte-unsigned': 3, 'instruction': 236, 'asm-body': 13, 'verbatim-body': 2682}
|
||||
C volatile 1590 1438 152 496 95 610 14 1576 {'decl-body': 58, 'decl-file': 152, 'cast': 1378, 'param': 2}
|
||||
D register 50 50 0 47 47 6 0 50 {'register': 50}
|
||||
E asm-label 7688 1265 6423 997 120 2084 0 7688 {'asm-label': 7688}
|
||||
F builtin 445 445 0 428 28 302 0 445 {'builtin': 445}
|
||||
G attribute 76 1 75 1 1 40 0 76 {'attribute': 76}
|
||||
UNION A–D: 6,586 bodies · 1,450 distinct (addresses normalized) · 215 multi-copy classes holding 5,351 bodies · by kind {'ov': 6097, 'md': 133, 'shared': 181, 'main': 165, 'resident': 10}
|
||||
THE PHASE'S NUMBER (pins + asm statements, GTE excluded): 12,003 sites in 3,060 bodies (1,160 distinct) · marked !FAKE 12,003 · UNMARKED 0
|
||||
UNION A–D: 6,576 bodies · 1,448 distinct (addresses normalized) · 213 multi-copy classes holding 5,341 bodies · by kind {'main': 165, 'ov': 6087, 'resident': 10, 'shared': 181, 'md': 133}
|
||||
THE PHASE'S NUMBER (pins + asm statements, GTE excluded): 11,988 sites in 3,050 bodies (1,158 distinct) · marked !FAKE 11,988 · UNMARKED 0
|
||||
orphan !FAKE markers (no pin/asm site on the line nor below): 0
|
||||
GTE levers (clobbers beyond the canonical macro's): 462 sites (100 via a variant macro, 362 direct) · marked 462 · UNMARKED 0 · unsigned GTE statements 3
|
||||
per-TU asm macro definitions outside the GTE header: 314 {'gte': 150, 'instruction': 9, 'launder': 154, 'barrier': 1} (GTE variants 64)
|
||||
pins: 6,910 · $0 106 · $sp 13 · with initializer 538 · volatile-qualified 3 · bare-name 15 · spellings {'__asm__': 6853, 'asm': 57}
|
||||
per-TU asm macro definitions outside the GTE header: 314 {'gte': 150, 'launder': 154, 'instruction': 9, 'barrier': 1} (GTE variants 64)
|
||||
pins: 6,900 · $0 106 · $sp 13 · with initializer 538 · volatile-qualified 3 · bare-name 15 · spellings {'__asm__': 6843, 'asm': 57}
|
||||
whole-body asm routines in C shells, manifest PERMANENT (hand asm, NOT levers): 22 routines · 2,682 sites (2,660 private copies + 22 shared headers); asm-bodies NOT permanent (levers): 13 site(s) ['func_8001E378:DECOMPILE-NOW', 'func_80020F34:DECOMPILE-NOW', 'func_800249F0:DECOMPILE-NOW', 'func_80025CBC:DECOMPILE-NOW', 'func_80026514:UNCERTAIN', 'func_800268D0:UNCERTAIN', 'func_80027058:DECOMPILE-NOW', 'func_80027200:DECOMPILE-NOW', 'func_800CBA44:DECOMPILE-NOW', 'func_8017D810:DECOMPILE-NOW', 'func_8017E26C:UNCERTAIN', 'func_80184440:DECOMPILE-NOW', 'func_801A3BCC:DECOMPILE-NOW']
|
||||
asm kinds: {'asm-body/direct': 13, 'barrier/direct': 1934, 'barrier/via-macro': 2, 'gte/direct': 200, 'gte/via-macro': 6658, 'gte-lever/direct': 362, 'gte-lever/via-macro': 100, 'gte-unsigned/direct': 3, 'instruction/direct': 214, 'instruction/via-macro': 22, 'keepalive/direct': 645, 'launder/direct': 1735, 'launder/via-macro': 66, 'verbatim-body/direct': 2682}
|
||||
instruction mnemonics: {'la': 142, 'addu': 23, 'RTP_SND': 22, 'addiu': 22, '.section': 7, 'lui': 4, 'move': 4, 'lh': 3, 'and': 2, 'mult': 1, 'mfhi': 1, 'sll': 1, 'li': 1, 'lw': 1, 'nop': 1, 'srl': 1}
|
||||
gte mnemonics: {'gte_ldv0': 757, 'gte_stlvnl': 593, 'gte_stsxy': 447, 'gte_rtps': 437, 'gte_stflg': 415, 'gte_rtpt': 352, 'gte_SetRotMatrix': 246, 'gte_stsxy3': 236, 'gte_rtv0tr': 228, 'gte_SetTransMatrix': 226, 'gte_ldv3c': 184, 'gte_ldv3': 177, 'gte_ldrgb': 164, 'gte_stsv': 161, 'lwc2': 159, 'gte_stsz4': 149, 'gte_stsz3': 147, 'gte_stszotz': 134, 'gte_ldIR0z': 134, 'gte_ldIRGB': 134, 'gte_dpcl': 134, 'gte_stORGB': 134, 'gte_stsxy3_f3': 111, 'gte_stclmv': 108, 'gte_nclip': 108, 'gte_stopz': 108, 'gte_stsxy3c': 108, 'gte_stsxy3_ft3': 79, 'gte_rtir': 75, 'gte_ldclmv': 72}
|
||||
asm-bearing macro definitions: 314 (20 names, 3 with >1 text) kinds {'gte': 150, 'instruction': 9, 'launder': 154, 'barrier': 1}
|
||||
asm kinds: {'asm-body/direct': 13, 'barrier/direct': 1929, 'barrier/via-macro': 2, 'gte/direct': 200, 'gte/via-macro': 6658, 'gte-lever/direct': 362, 'gte-lever/via-macro': 100, 'gte-unsigned/direct': 3, 'instruction/direct': 214, 'instruction/via-macro': 22, 'keepalive/direct': 645, 'launder/direct': 1735, 'launder/via-macro': 66, 'verbatim-body/direct': 2682}
|
||||
instruction mnemonics: {'la': 142, 'addu': 23, 'addiu': 22, 'RTP_SND': 22, '.section': 7, 'lui': 4, 'move': 4, 'lh': 3, 'and': 2, 'mult': 1, 'mfhi': 1, 'sll': 1, 'li': 1, 'lw': 1, 'nop': 1, 'srl': 1}
|
||||
gte mnemonics: {'gte_ldv0': 757, 'gte_stlvnl': 593, 'gte_stsxy': 447, 'gte_rtps': 437, 'gte_stflg': 415, 'gte_rtpt': 352, 'gte_SetRotMatrix': 246, 'gte_stsxy3': 236, 'gte_rtv0tr': 228, 'gte_SetTransMatrix': 226, 'gte_ldv3c': 184, 'gte_ldv3': 177, 'gte_ldrgb': 164, 'gte_stsv': 161, 'lwc2': 159, 'gte_stsz4': 149, 'gte_stsz3': 147, 'gte_stszotz': 134, 'gte_ldIR0z': 134, 'gte_ldIRGB': 134, 'gte_dpcl': 134, 'gte_stORGB': 134, 'gte_stsxy3_f3': 111, 'gte_nclip': 108, 'gte_stopz': 108, 'gte_stsxy3c': 108, 'gte_stclmv': 108, 'gte_stsxy3_ft3': 79, 'gte_rtir': 75, 'gte_ldclmv': 72}
|
||||
asm-bearing macro definitions: 314 (20 names, 3 with >1 text) kinds {'gte': 150, 'launder': 154, 'instruction': 9, 'barrier': 1}
|
||||
controls (R39):
|
||||
src/800.c func_800226C0 pins got 14 expected 45 N-A
|
||||
src/shared/ov/func_80178004.h pins got 8 expected 26 N-A
|
||||
ov_SC03_006 func_80184034 bare-name pins got 0 expected 3 N-A
|
||||
engine_prelude.h asm sites (a macro definition only) got 0 expected 0 OK
|
||||
elapsed 29.7 s
|
||||
elapsed 31.0 s
|
||||
|
||||
+177
-177
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"head": "321b540e7",
|
||||
"head": "2a4f28f83",
|
||||
"stamp": "15956e4a96c4",
|
||||
"generated": "2026-09-10 18:08",
|
||||
"generated": "2026-09-10 18:13",
|
||||
"aliases": [
|
||||
"main",
|
||||
"ov_SC03_014",
|
||||
@@ -21,206 +21,206 @@
|
||||
"main": {
|
||||
"objects": 85,
|
||||
"identical": 85,
|
||||
"seconds": 8.127000000000002,
|
||||
"mean_s": 0.096
|
||||
"seconds": 7.8809999999999985,
|
||||
"mean_s": 0.093
|
||||
},
|
||||
"ov_SC03_014": {
|
||||
"objects": 32,
|
||||
"identical": 32,
|
||||
"seconds": 5.461000000000001,
|
||||
"mean_s": 0.171
|
||||
"seconds": 5.423000000000001,
|
||||
"mean_s": 0.169
|
||||
},
|
||||
"ov_SC03_015": {
|
||||
"objects": 32,
|
||||
"identical": 32,
|
||||
"seconds": 5.338000000000001,
|
||||
"mean_s": 0.167
|
||||
"seconds": 5.321999999999999,
|
||||
"mean_s": 0.166
|
||||
},
|
||||
"ov_SC04_011": {
|
||||
"objects": 28,
|
||||
"identical": 28,
|
||||
"seconds": 4.664000000000001,
|
||||
"mean_s": 0.167
|
||||
"seconds": 4.66,
|
||||
"mean_s": 0.166
|
||||
}
|
||||
},
|
||||
"per_object_seconds": {
|
||||
"build/src/800.o": 0.863,
|
||||
"build/src/800_b.o": 0.119,
|
||||
"build/src/800_b_2.o": 0.357,
|
||||
"build/src/800_b_o0a.o": 0.083,
|
||||
"build/src/800_c.o": 0.227,
|
||||
"build/src/800b2.o": 0.085,
|
||||
"build/src/apicard1.o": 0.076,
|
||||
"build/src/apicard2.o": 0.082,
|
||||
"build/src/apicard3.o": 0.078,
|
||||
"build/src/apicard4.o": 0.079,
|
||||
"build/src/apicard5.o": 0.117,
|
||||
"build/src/apicard6.o": 0.094,
|
||||
"build/src/apicard7.o": 0.108,
|
||||
"build/src/boot.o": 0.115,
|
||||
"build/src/gap.o": 0.088,
|
||||
"build/src/800.o": 0.854,
|
||||
"build/src/800_b.o": 0.083,
|
||||
"build/src/800_b_2.o": 0.338,
|
||||
"build/src/800_b_o0a.o": 0.077,
|
||||
"build/src/800_c.o": 0.215,
|
||||
"build/src/800b2.o": 0.113,
|
||||
"build/src/apicard1.o": 0.077,
|
||||
"build/src/apicard2.o": 0.074,
|
||||
"build/src/apicard3.o": 0.081,
|
||||
"build/src/apicard4.o": 0.068,
|
||||
"build/src/apicard5.o": 0.104,
|
||||
"build/src/apicard6.o": 0.085,
|
||||
"build/src/apicard7.o": 0.082,
|
||||
"build/src/boot.o": 0.13,
|
||||
"build/src/gap.o": 0.067,
|
||||
"build/src/libapi1.o": 0.085,
|
||||
"build/src/libapi2.o": 0.069,
|
||||
"build/src/libc2_1.o": 0.079,
|
||||
"build/src/libc2_2.o": 0.074,
|
||||
"build/src/libcd1.o": 0.082,
|
||||
"build/src/libcd2.o": 0.069,
|
||||
"build/src/libetc.o": 0.071,
|
||||
"build/src/libgpu.o": 0.091,
|
||||
"build/src/libgpu2.o": 0.088,
|
||||
"build/src/libgs1.o": 0.078,
|
||||
"build/src/libgs2.o": 0.073,
|
||||
"build/src/libgs3.o": 0.069,
|
||||
"build/src/libgs4.o": 0.079,
|
||||
"build/src/libgs5.o": 0.079,
|
||||
"build/src/libgs6.o": 0.097,
|
||||
"build/src/libgs7.o": 0.074,
|
||||
"build/src/libgs8.o": 0.085,
|
||||
"build/src/libgte1.o": 0.079,
|
||||
"build/src/libgte10.o": 0.078,
|
||||
"build/src/libgte11.o": 0.078,
|
||||
"build/src/libgte12.o": 0.076,
|
||||
"build/src/libgte13.o": 0.078,
|
||||
"build/src/libgte14.o": 0.073,
|
||||
"build/src/libgte15.o": 0.076,
|
||||
"build/src/libgte16.o": 0.078,
|
||||
"build/src/libgte17.o": 0.079,
|
||||
"build/src/libgte18.o": 0.083,
|
||||
"build/src/libgte19.o": 0.078,
|
||||
"build/src/libgte2.o": 0.077,
|
||||
"build/src/libgte20.o": 0.075,
|
||||
"build/src/libgte21.o": 0.074,
|
||||
"build/src/libgte22.o": 0.076,
|
||||
"build/src/libgte23.o": 0.071,
|
||||
"build/src/libgte24.o": 0.081,
|
||||
"build/src/libgte25.o": 0.078,
|
||||
"build/src/libgte26.o": 0.083,
|
||||
"build/src/libgte27.o": 0.075,
|
||||
"build/src/libgte28.o": 0.079,
|
||||
"build/src/libgte29.o": 0.078,
|
||||
"build/src/libgte3.o": 0.077,
|
||||
"build/src/libgte30.o": 0.081,
|
||||
"build/src/libgte4.o": 0.078,
|
||||
"build/src/libgte5.o": 0.074,
|
||||
"build/src/libgte6.o": 0.089,
|
||||
"build/src/libgte7.o": 0.086,
|
||||
"build/src/libgte8.o": 0.079,
|
||||
"build/src/libgte9.o": 0.084,
|
||||
"build/src/libmcrd1.o": 0.091,
|
||||
"build/src/libmcrd2.o": 0.087,
|
||||
"build/src/libpad1.o": 0.078,
|
||||
"build/src/libpad2.o": 0.092,
|
||||
"build/src/sgap.o": 0.075,
|
||||
"build/src/sgap_2.o": 0.076,
|
||||
"build/src/sgap_3.o": 0.085,
|
||||
"build/src/sgap_4.o": 0.086,
|
||||
"build/src/sgap_5.o": 0.079,
|
||||
"build/src/sgap_6.o": 0.077,
|
||||
"build/src/sgap_8.o": 0.08,
|
||||
"build/src/snd1.o": 0.085,
|
||||
"build/src/libapi2.o": 0.074,
|
||||
"build/src/libc2_1.o": 0.074,
|
||||
"build/src/libc2_2.o": 0.07,
|
||||
"build/src/libcd1.o": 0.083,
|
||||
"build/src/libcd2.o": 0.074,
|
||||
"build/src/libetc.o": 0.082,
|
||||
"build/src/libgpu.o": 0.074,
|
||||
"build/src/libgpu2.o": 0.084,
|
||||
"build/src/libgs1.o": 0.073,
|
||||
"build/src/libgs2.o": 0.076,
|
||||
"build/src/libgs3.o": 0.064,
|
||||
"build/src/libgs4.o": 0.066,
|
||||
"build/src/libgs5.o": 0.073,
|
||||
"build/src/libgs6.o": 0.092,
|
||||
"build/src/libgs7.o": 0.078,
|
||||
"build/src/libgs8.o": 0.069,
|
||||
"build/src/libgte1.o": 0.08,
|
||||
"build/src/libgte10.o": 0.076,
|
||||
"build/src/libgte11.o": 0.081,
|
||||
"build/src/libgte12.o": 0.079,
|
||||
"build/src/libgte13.o": 0.079,
|
||||
"build/src/libgte14.o": 0.078,
|
||||
"build/src/libgte15.o": 0.074,
|
||||
"build/src/libgte16.o": 0.074,
|
||||
"build/src/libgte17.o": 0.082,
|
||||
"build/src/libgte18.o": 0.076,
|
||||
"build/src/libgte19.o": 0.07,
|
||||
"build/src/libgte2.o": 0.071,
|
||||
"build/src/libgte20.o": 0.077,
|
||||
"build/src/libgte21.o": 0.072,
|
||||
"build/src/libgte22.o": 0.075,
|
||||
"build/src/libgte23.o": 0.075,
|
||||
"build/src/libgte24.o": 0.077,
|
||||
"build/src/libgte25.o": 0.082,
|
||||
"build/src/libgte26.o": 0.073,
|
||||
"build/src/libgte27.o": 0.079,
|
||||
"build/src/libgte28.o": 0.077,
|
||||
"build/src/libgte29.o": 0.079,
|
||||
"build/src/libgte3.o": 0.084,
|
||||
"build/src/libgte30.o": 0.09,
|
||||
"build/src/libgte4.o": 0.073,
|
||||
"build/src/libgte5.o": 0.082,
|
||||
"build/src/libgte6.o": 0.073,
|
||||
"build/src/libgte7.o": 0.078,
|
||||
"build/src/libgte8.o": 0.073,
|
||||
"build/src/libgte9.o": 0.082,
|
||||
"build/src/libmcrd1.o": 0.089,
|
||||
"build/src/libmcrd2.o": 0.076,
|
||||
"build/src/libpad1.o": 0.084,
|
||||
"build/src/libpad2.o": 0.09,
|
||||
"build/src/sgap.o": 0.08,
|
||||
"build/src/sgap_2.o": 0.07,
|
||||
"build/src/sgap_3.o": 0.086,
|
||||
"build/src/sgap_4.o": 0.082,
|
||||
"build/src/sgap_5.o": 0.076,
|
||||
"build/src/sgap_6.o": 0.075,
|
||||
"build/src/sgap_8.o": 0.083,
|
||||
"build/src/snd1.o": 0.081,
|
||||
"build/src/snd10.o": 0.076,
|
||||
"build/src/snd11.o": 0.075,
|
||||
"build/src/snd12.o": 0.072,
|
||||
"build/src/snd2.o": 0.083,
|
||||
"build/src/snd3.o": 0.079,
|
||||
"build/src/snd11.o": 0.072,
|
||||
"build/src/snd12.o": 0.082,
|
||||
"build/src/snd2.o": 0.085,
|
||||
"build/src/snd3.o": 0.073,
|
||||
"build/src/snd4.o": 0.076,
|
||||
"build/src/snd5.o": 0.08,
|
||||
"build/src/snd6.o": 0.087,
|
||||
"build/src/snd7.o": 0.084,
|
||||
"build/src/snd8.o": 0.074,
|
||||
"build/src/snd9.o": 0.086,
|
||||
"build/src/snd5.o": 0.074,
|
||||
"build/src/snd6.o": 0.08,
|
||||
"build/src/snd7.o": 0.077,
|
||||
"build/src/snd8.o": 0.072,
|
||||
"build/src/snd9.o": 0.082,
|
||||
"build/src/ov_SC03_014/ov_SC03_014.o": 0.154,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.592,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8012ACE0.o": 0.454,
|
||||
"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.076,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.146,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.189,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.139,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.095,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_after.o": 0.594,
|
||||
"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.072,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135A4C.o": 0.073,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80135D20.o": 0.156,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801380E0.o": 0.175,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013C98C.o": 0.135,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013F350.o": 0.092,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8013FFD8.o": 0.086,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.225,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.091,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.203,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.114,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80140608.o": 0.207,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015444C.o": 0.088,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80154C24.o": 0.19,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801588CC.o": 0.123,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80159C84.o": 0.08,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.086,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.113,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.549,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.308,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.116,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.229,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801789AC.o": 0.07,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80178D40.o": 0.126,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.083,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.196,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.221,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.057,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.306,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.065,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.069,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.065,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.082,
|
||||
"build/src/ov_SC03_015/ov_SC03_015.o": 0.153,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.6,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.432,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015A3C8.o": 0.082,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015AE2C.o": 0.112,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8015C32C.o": 0.546,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8016AB6C.o": 0.293,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80171B4C.o": 0.12,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801734BC.o": 0.24,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801789AC.o": 0.072,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80178D40.o": 0.119,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017A4AC.o": 0.074,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.o": 0.193,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.o": 0.238,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_80184440.o": 0.061,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_jr_801848E4.o": 0.32,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0b.o": 0.072,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0c.o": 0.07,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0d.o": 0.066,
|
||||
"build/src/ov_SC03_014/ov_SC03_014_o0e.o": 0.072,
|
||||
"build/src/ov_SC03_015/ov_SC03_015.o": 0.134,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_after.o": 0.575,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8012ACE0.o": 0.441,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135888.o": 0.063,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.056,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.135,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.177,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.122,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.089,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.072,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80140608.o": 0.204,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015444C.o": 0.087,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135A4C.o": 0.061,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80135D20.o": 0.13,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801380E0.o": 0.182,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013C98C.o": 0.137,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013F350.o": 0.087,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8013FFD8.o": 0.087,
|
||||
"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.09,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80154C24.o": 0.193,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.102,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.076,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.077,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801588CC.o": 0.115,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80159C84.o": 0.082,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015A3C8.o": 0.087,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015AE2C.o": 0.109,
|
||||
"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.319,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80171B4C.o": 0.121,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.23,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.069,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.123,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.075,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.197,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.242,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80184440.o": 0.065,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801848E4.o": 0.322,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.078,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.067,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.068,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.087,
|
||||
"build/src/ov_SC04_011/ov_SC04_011.o": 0.144,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.487,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.396,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.065,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.064,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.132,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.173,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.127,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.086,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.082,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.21,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.088,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80154C24.o": 0.203,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801588CC.o": 0.111,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80159C84.o": 0.075,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015A3C8.o": 0.077,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.112,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.418,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.261,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.122,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8015C32C.o": 0.53,
|
||||
"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.117,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801734BC.o": 0.231,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_801789AC.o": 0.07,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_80178D40.o": 0.117,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017A4AC.o": 0.079,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.o": 0.193,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_jr_8017EB7C.o": 0.226,
|
||||
"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.32,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0b.o": 0.071,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0c.o": 0.068,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0d.o": 0.065,
|
||||
"build/src/ov_SC03_015/ov_SC03_015_o0e.o": 0.088,
|
||||
"build/src/ov_SC04_011/ov_SC04_011.o": 0.143,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_after.o": 0.488,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8012ACE0.o": 0.398,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135888.o": 0.064,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135A4C.o": 0.065,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80135D20.o": 0.135,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801380E0.o": 0.168,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013C98C.o": 0.129,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013F350.o": 0.092,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8013FFD8.o": 0.076,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80140608.o": 0.209,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015444C.o": 0.083,
|
||||
"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.104,
|
||||
"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.079,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015AE2C.o": 0.106,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8015C32C.o": 0.421,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8016AB6C.o": 0.255,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80171B4C.o": 0.109,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801734BC.o": 0.203,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.07,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.106,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.08,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.122,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.525,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.06,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.065
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_801789AC.o": 0.072,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_80178D40.o": 0.118,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017A4AC.o": 0.083,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017AE2C.o": 0.126,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o": 0.528,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0b.o": 0.067,
|
||||
"build/src/ov_SC04_011/ov_SC04_011_o0c.o": 0.07
|
||||
},
|
||||
"ok": true,
|
||||
"seconds": 2.7
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -100,12 +100,17 @@ def related_bodies(tu, fn, target_text, alias, top=6, max_lines=600):
|
||||
for r in recs:
|
||||
if r.get("form") == "def" and r.get("name") == fn:
|
||||
body = txt[ls[r["line"] - 1]:ls[r["end"]]] if r["end"] < len(ls) else txt[ls[r["line"] - 1]:]
|
||||
if "!FAKE" not in body and "__asm__ __volatile__" not in body:
|
||||
# SAME NAME IS NOT SAME FUNCTION: overlays reuse addresses (S103, agent c43 — the func_80185578 listed
|
||||
# here from ov_SC03_014 was a one-line different function). Evidence required: a shared callee/global
|
||||
# and a comparable size.
|
||||
n_t, n_b = target_text.count("\n") or 1, body.count("\n") or 1
|
||||
shares = (set(SYM.findall(body)) - {fn}) & want
|
||||
if "!FAKE" not in body and "__asm__ __volatile__" not in body and shares and 0.6 <= n_b / n_t <= 1.6:
|
||||
same.append((rel, r["line"], body))
|
||||
break
|
||||
head = []
|
||||
for rel, line, body in same:
|
||||
head += [f"=== {fn} ALREADY LEVER-FREE in {rel}:{line} — a variant of your function: port it (R71) ===", body.rstrip(), ""]
|
||||
head += [f"=== {fn} ALREADY LEVER-FREE in {rel}:{line} — same name, shares symbols and size: PROBABLY a variant; diff it before porting (R71) ===", body.rstrip(), ""]
|
||||
seen, out = set(), head + [f"=== lever-free bodies in {alias} sharing a callee or global with {fn} "
|
||||
f"({len(cands)} found; top {top} by shared symbols) — read them for the SHAPE ==="]
|
||||
for _, n, name, rel, line, shared, body in cands:
|
||||
|
||||
@@ -47,3 +47,4 @@ date milestone head sites_AB pins asm bodies_AB distinct_AB marked unmarked gte_
|
||||
2026-09-10 S103: c36 + c35 (four ov_SC07_006/ov_SC06_010 classes, 39 bodies); R19 reads cast arity dd5e44c24 12481 7186 5295 3260 1207 12481 0 462 314 1590 50 7680 445 76
|
||||
2026-09-10 S103: extern-variant re-propagation (97), R19 cast regen (8 classes), c39 + c41 + c34 + c32 closes 7d5964b27 12033 6926 5107 3090 1164 12033 0 462 314 1590 50 7688 445 76
|
||||
2026-09-10 S103: c38 + c40 (four tier classes, 30 bodies) 321b540e7 12003 6910 5093 3060 1160 12003 0 462 314 1590 50 7688 445 76
|
||||
2026-09-10 S103: c42 func_80186A8C + func_80182058 (10 bodies) 2a4f28f83 11988 6900 5088 3050 1158 11988 0 462 314 1590 50 7688 445 76
|
||||
|
||||
|
+4
-1
@@ -93,6 +93,7 @@ counted, not marked). E, F and G belong to the canonical type layer and are the
|
||||
| 2026-09-10 | S103: c36 + c35 (four ov_SC07_006/ov_SC06_010 classes, 39 bodies); R19 reads cast arity | 7186 | 5295 | **12481** | 3260 | 1207 | 462 | 314 | 1590 | 50 | 7680 | 445 | 76 | `dd5e44c24` |
|
||||
| 2026-09-10 | S103: extern-variant re-propagation (97), R19 cast regen (8 classes), c39 + c41 + c34 + c32 closes | 6926 | 5107 | **12033** | 3090 | 1164 | 462 | 314 | 1590 | 50 | 7688 | 445 | 76 | `7d5964b27` |
|
||||
| 2026-09-10 | S103: c38 + c40 (four tier classes, 30 bodies) | 6910 | 5093 | **12003** | 3060 | 1160 | 462 | 314 | 1590 | 50 | 7688 | 445 | 76 | `321b540e7` |
|
||||
| 2026-09-10 | S103: c42 func_80186A8C + func_80182058 (10 bodies) | 6900 | 5088 | **11988** | 3050 | 1158 | 462 | 314 | 1590 | 50 | 7688 | 445 | 76 | `2a4f28f83` |
|
||||
|
||||
### The campaign — every batch, from the ledger (derived on every render)
|
||||
|
||||
@@ -264,7 +265,9 @@ counted, not marked). E, F and G belong to the canonical type layer and are the
|
||||
| `c38p` | 2026-09-10 | E | 0 | 0 | 0 | 14 | 14 |
|
||||
| `c40` | 2026-09-10 | E | 0 | 0 | 0 | 2 | 2 |
|
||||
| `c40p` | 2026-09-10 | E | 0 | 0 | 0 | 12 | 12 |
|
||||
| **total** | | | **17,119** | **20,778** | **283** | **22,417** | **9,676** |
|
||||
| `c42` | 2026-09-10 | E | 0 | 0 | 0 | 3 | 2 |
|
||||
| `c42p` | 2026-09-10 | E | 0 | 0 | 0 | 12 | 8 |
|
||||
| **total** | | | **17,119** | **20,778** | **283** | **22,432** | **9,686** |
|
||||
|
||||
*Generated by `tools/lever_progress.py --render` from `.run/P36/census/lever_census.json` and `.run/P36/delever/ledger.jsonl`; the series lives in `docs/lever-progress.tsv` (R75: published numbers are generated, never typed).*
|
||||
|
||||
|
||||
@@ -1694,6 +1694,16 @@ accumulate here as the phase produces them.**
|
||||
merge; and a hand-rotated `if … do … while` written as a real `for` loop, whose `NOTE_INSN_LOOP_VTOP`
|
||||
(`jump.c:2306`) makes reorg's `mostly_true_jump` predict taken (`reorg.c:1364-1372`) and fill the slot from the target.
|
||||
Tools: `cc1_dumps_tu.sh` gains `-dd` (`.dbr`); METHOD notes `--keep`'s path is the LAST output line.
|
||||
- **S103 — c42: `func_80186A8C` (ov_SC03_091, 8 → 0; 4/4) and `func_80182058` (ov_SC03_001, 10 → 0; 4/4) CLOSED —
|
||||
both through jump2's cross-jump in ways METHOD did not yet list.** func_80186A8C: the `- 0x4000` folded into both arms
|
||||
of the sign pick and `t` passed bare — `t` set in two blocks takes `$5` by copy preference, and cross-jump merges the two
|
||||
identical arm tails into the target's single join instruction (argument registers load in order on MIPS,
|
||||
`calls.c:1860-1881`); func_80182058: the case failures sent to one labelled `return 0` — cross-jump lowers its match
|
||||
threshold for a block at a label (`jump.c:2406-2410`) or right after a conditional jump past it (`:2516-2519`), so which
|
||||
block SURVIVES the merge is decided by where the labels are; the tree's "load-bearing zero-byte cross-jump barrier"
|
||||
comment was refuted. METHOD note: for a cross-jump residual, find which label survives in `.jump2`, yours and the tree's.
|
||||
- **S103 — the first MINIMUM-LEVER draw: c46 on `func_80177B5C`** (c19's plain body at 2; goal: 0 with the fewest marked
|
||||
levers, ideally one, instead of 23 per copy × 132).
|
||||
- **S103 — WHERE THE RESIDUE IS (measured at 12,003 sites): ~70% of the remaining lever weight sits in 9 classes of
|
||||
≥100 copies, every one already read by an agent with a written reading** (approx. copies × sites/body:
|
||||
func_8013D9B0 125×34 — c17 15 plain, the GTE-macro question; func_80177B5C 132×23 — c19 2, one `or` late;
|
||||
|
||||
@@ -4283,15 +4283,11 @@ void func_8017F4DC(s32 a0) {
|
||||
s32 t;
|
||||
s32 r;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
r = ((s32 (*)(s32))func_8012CBA4)(a0);
|
||||
if (r & 0x8000) {
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
@@ -4328,15 +4324,11 @@ void func_8017F4DC(s32 a0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + d;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
if ((((s32 (*)(s32))func_8012CBA4)(a0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
|
||||
@@ -7329,11 +7329,6 @@ s32 func_80182058(void *a0)
|
||||
u16 st;
|
||||
|
||||
if (func_8012BD14(*(s32 *)((s32)a0 + 0x64)) > 0x4000) {
|
||||
/* LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a).
|
||||
* Without it gcc's find_cross_jump merges this `move v0,0; j epi`
|
||||
* tail with the identical case-2 failure tail -> 58 ins instead of
|
||||
* 60, and the case-2 `beq` then loses its delay-slot fill. */
|
||||
__asm__ __volatile__(""); // !FAKE: barrier — NEEDED DIFFERS (P36 rung B tus7)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7344,13 +7339,13 @@ s32 func_80182058(void *a0)
|
||||
*(s16 *)((s32)p + 0x2) = 8;
|
||||
break;
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) != 1) {
|
||||
return 0;
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto hit;
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
hit:
|
||||
D_801EEAF0 = st;
|
||||
@@ -7358,6 +7353,9 @@ s32 func_80182058(void *a0)
|
||||
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x2) = 10;
|
||||
break;
|
||||
default:
|
||||
fail: /* the case-2/case-4 failures share this one `return 0`: a return
|
||||
* falling out of a conditional (as the first one does) is what
|
||||
* jump2's cross-jump would merge the early return into */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8428,11 +8426,6 @@ s32 func_801834C0(void *a0)
|
||||
u16 st;
|
||||
|
||||
if (func_8012BD14(*(s32 *)((s32)a0 + 0x64)) > 0x4000) {
|
||||
/* LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a).
|
||||
* Without it gcc's find_cross_jump merges this `move v0,0; j epi`
|
||||
* tail with the identical case-2 failure tail -> 58 ins instead of
|
||||
* 60, and the case-2 `beq` then loses its delay-slot fill. */
|
||||
__asm__ __volatile__(""); // !FAKE: barrier — NEEDED DIFFERS (P36 rung B tus7)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8443,13 +8436,13 @@ s32 func_801834C0(void *a0)
|
||||
*(s16 *)((s32)p + 0x2) = 8;
|
||||
break;
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) != 1) {
|
||||
return 0;
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto hit;
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
hit:
|
||||
D_801EEB00 = st;
|
||||
@@ -8457,6 +8450,9 @@ s32 func_801834C0(void *a0)
|
||||
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x2) = 10;
|
||||
break;
|
||||
default:
|
||||
fail: /* the case-2/case-4 failures share this one `return 0`: a return
|
||||
* falling out of a conditional (as the first one does) is what
|
||||
* jump2's cross-jump would merge the early return into */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -6876,15 +6876,11 @@ void func_80185BE4(s32 a0) {
|
||||
s32 t;
|
||||
s32 r;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
r = ((s32 (*)(s32))func_8012CBA4)(a0);
|
||||
if (r & 0x8000) {
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
@@ -6921,15 +6917,11 @@ void func_80185BE4(s32 a0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + d;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
if ((((s32 (*)(s32))func_8012CBA4)(a0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
|
||||
@@ -5210,15 +5210,11 @@ void func_80186A8C(s32 a0) {
|
||||
s32 t;
|
||||
s32 r;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
r = ((s32 (*)(s32))func_8012CBA4)(a0);
|
||||
if (r & 0x8000) {
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
@@ -5255,15 +5251,11 @@ void func_80186A8C(s32 a0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + d;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
if ((((s32 (*)(s32))func_8012CBA4)(a0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
|
||||
@@ -5093,15 +5093,11 @@ void func_80180864(s32 a0) {
|
||||
s32 t;
|
||||
s32 r;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
r = ((s32 (*)(s32))func_8012CBA4)(a0);
|
||||
if (r & 0x8000) {
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
@@ -5138,15 +5134,11 @@ void func_80180864(s32 a0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + d;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
if ((((s32 (*)(s32))func_8012CBA4)(a0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
|
||||
@@ -4379,15 +4379,11 @@ void func_8018106C(s32 a0) {
|
||||
s32 t;
|
||||
s32 r;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
r = ((s32 (*)(s32))func_8012CBA4)(a0);
|
||||
if (r & 0x8000) {
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
@@ -4424,15 +4420,11 @@ void func_8018106C(s32 a0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + d;
|
||||
if (ang >= 0) {
|
||||
t = -(ang << 4);
|
||||
t = -(ang << 4) - 0x4000;
|
||||
} else {
|
||||
t = ang << 4;
|
||||
}
|
||||
{
|
||||
register s32 av __asm__("$5"); // !FAKE: pin $5 — NEEDED DIFFERS (P36 rung B tus9)
|
||||
av = t - 0x4000;
|
||||
func_8012B178(a0, av);
|
||||
t = (ang << 4) - 0x4000;
|
||||
}
|
||||
func_8012B178(a0, t);
|
||||
if ((((s32 (*)(s32))func_8012CBA4)(a0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
*(u16 *)(a0 + 0x34) = 2;
|
||||
|
||||
@@ -7371,11 +7371,6 @@ s32 func_801825BC(void *a0)
|
||||
u16 st;
|
||||
|
||||
if (func_8012BD14(*(s32 *)((s32)a0 + 0x64)) > 0x4000) {
|
||||
/* LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a).
|
||||
* Without it gcc's find_cross_jump merges this `move v0,0; j epi`
|
||||
* tail with the identical case-2 failure tail -> 58 ins instead of
|
||||
* 60, and the case-2 `beq` then loses its delay-slot fill. */
|
||||
__asm__ __volatile__(""); // !FAKE: barrier — NEEDED DIFFERS (P36 rung B tus7)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7386,13 +7381,13 @@ s32 func_801825BC(void *a0)
|
||||
*(s16 *)((s32)p + 0x2) = 8;
|
||||
break;
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) != 1) {
|
||||
return 0;
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto hit;
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
hit:
|
||||
D_801E7020 = st;
|
||||
@@ -7400,6 +7395,9 @@ s32 func_801825BC(void *a0)
|
||||
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x2) = 10;
|
||||
break;
|
||||
default:
|
||||
fail: /* the case-2/case-4 failures share this one `return 0`: a return
|
||||
* falling out of a conditional (as the first one does) is what
|
||||
* jump2's cross-jump would merge the early return into */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5411,11 +5411,6 @@ s32 func_8017FB10(void *a0)
|
||||
u16 st;
|
||||
|
||||
if (func_8012BD14(*(s32 *)((s32)a0 + 0x64)) > 0x4000) {
|
||||
/* LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a).
|
||||
* Without it gcc's find_cross_jump merges this `move v0,0; j epi`
|
||||
* tail with the identical case-2 failure tail -> 58 ins instead of
|
||||
* 60, and the case-2 `beq` then loses its delay-slot fill. */
|
||||
__asm__ __volatile__(""); // !FAKE: barrier — NEEDED DIFFERS (P36 rung B tus7)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5426,13 +5421,13 @@ s32 func_8017FB10(void *a0)
|
||||
*(s16 *)((s32)p + 0x2) = 8;
|
||||
break;
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) != 1) {
|
||||
return 0;
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto hit;
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
hit:
|
||||
D_801ECE68 = st;
|
||||
@@ -5440,6 +5435,9 @@ s32 func_8017FB10(void *a0)
|
||||
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x2) = 10;
|
||||
break;
|
||||
default:
|
||||
fail: /* the case-2/case-4 failures share this one `return 0`: a return
|
||||
* falling out of a conditional (as the first one does) is what
|
||||
* jump2's cross-jump would merge the early return into */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3289,11 +3289,6 @@ s32 func_80180FB4(void *a0)
|
||||
u16 st;
|
||||
|
||||
if (func_8012BD14(*(s32 *)((s32)a0 + 0x64)) > 0x4000) {
|
||||
/* LOAD-BEARING zero-byte cross-jump barrier (cookbook §5a).
|
||||
* Without it gcc's find_cross_jump merges this `move v0,0; j epi`
|
||||
* tail with the identical case-2 failure tail -> 58 ins instead of
|
||||
* 60, and the case-2 `beq` then loses its delay-slot fill. */
|
||||
__asm__ __volatile__(""); // !FAKE: barrier — NEEDED DIFFERS (P36 rung B tus9)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3304,13 +3299,13 @@ s32 func_80180FB4(void *a0)
|
||||
*(s16 *)((s32)p + 0x2) = 8;
|
||||
break;
|
||||
case 2:
|
||||
if (*(u16 *)((s32)p + 0x34) != 1) {
|
||||
return 0;
|
||||
if (*(u16 *)((s32)p + 0x34) == 1) {
|
||||
goto hit;
|
||||
}
|
||||
goto hit;
|
||||
goto fail;
|
||||
case 4:
|
||||
if (*(u16 *)((s32)p + 0x34) != 0) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
hit:
|
||||
D_801ECE78 = st;
|
||||
@@ -3318,6 +3313,9 @@ s32 func_80180FB4(void *a0)
|
||||
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x2) = 10;
|
||||
break;
|
||||
default:
|
||||
fail: /* the case-2/case-4 failures share this one `return 0`: a return
|
||||
* falling out of a conditional (as the first one does) is what
|
||||
* jump2's cross-jump would merge the early return into */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,12 +100,17 @@ def related_bodies(tu, fn, target_text, alias, top=6, max_lines=600):
|
||||
for r in recs:
|
||||
if r.get("form") == "def" and r.get("name") == fn:
|
||||
body = txt[ls[r["line"] - 1]:ls[r["end"]]] if r["end"] < len(ls) else txt[ls[r["line"] - 1]:]
|
||||
if "!FAKE" not in body and "__asm__ __volatile__" not in body:
|
||||
# SAME NAME IS NOT SAME FUNCTION: overlays reuse addresses (S103, agent c43 — the func_80185578 listed
|
||||
# here from ov_SC03_014 was a one-line different function). Evidence required: a shared callee/global
|
||||
# and a comparable size.
|
||||
n_t, n_b = target_text.count("\n") or 1, body.count("\n") or 1
|
||||
shares = (set(SYM.findall(body)) - {fn}) & want
|
||||
if "!FAKE" not in body and "__asm__ __volatile__" not in body and shares and 0.6 <= n_b / n_t <= 1.6:
|
||||
same.append((rel, r["line"], body))
|
||||
break
|
||||
head = []
|
||||
for rel, line, body in same:
|
||||
head += [f"=== {fn} ALREADY LEVER-FREE in {rel}:{line} — a variant of your function: port it (R71) ===", body.rstrip(), ""]
|
||||
head += [f"=== {fn} ALREADY LEVER-FREE in {rel}:{line} — same name, shares symbols and size: PROBABLY a variant; diff it before porting (R71) ===", body.rstrip(), ""]
|
||||
seen, out = set(), head + [f"=== lever-free bodies in {alias} sharing a callee or global with {fn} "
|
||||
f"({len(cands)} found; top {top} by shared symbols) — read them for the SHAPE ==="]
|
||||
for _, n, name, rel, line, shared, body in cands:
|
||||
|
||||
Reference in New Issue
Block a user