diff --git a/config/wave_exclude.txt b/config/wave_exclude.txt index 9084a06cec..07a084bffb 100644 --- a/config/wave_exclude.txt +++ b/config/wave_exclude.txt @@ -1,8 +1,7 @@ # regenerated by tools/exclude_audit.py from config/wave_exclude.txt -# 8 still-valid of 8; 0 dropped as stale (banked / linked / blocker-since-fixed). +# 7 still-valid of 8; 1 dropped as stale (banked / linked / blocker-since-fixed). # An exclude list records what the TOOLING could not do — regenerate it as # part of every tool fix, or it becomes a list of work you decided not to do. -md_MAIN_034:func_800CB00C # WALL: compiler wall (merged from S68_walls_332.txt) ov_SC03_105:func_801834A4 # WALL: loop.c movable ordering, closeness 6 (S71) ov_SC06_022:func_8017DF28 # WALL: expand_block_move copy_addr_to_reg pseudo cse-reused for both later &mtx args (cse_expr.md [A23-2]/§H) — the addiu $s2,sp,0x10 sits in the jal's delay slot vs the target's bnez slot; closeness 2 on five RTL-verified attempts (S71/S79); permuter_ils 8x150s (S80) reported 1 but its waypoint REPLACED the addiu with `sw zero,48(sp)` — a divergent rewrite, not a closer body: closeness stays 2 main:func_80032A74 # WALL: candidate: 422/422, frame/offsets/27 symbols exact, sole residual idx 244 `lh` vs `lhu` — extendhisi2 is a force_not_mem EXPAND (an orphan frame slot is minted only at an lh), the target's 8 extra frame bytes are §172 producer 3 (caller-save area, reload1.c:1445); ~200 byte-probes incl. a 100-variant retyping sweep (S79 Opus) + permuter_ils 8x150s null (S80); closeness 1 diff --git a/docs/backlog.md b/docs/backlog.md index be5bb766a6..1460448df3 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -2,7 +2,7 @@ > Generated by `tools/backlog.py render` from `.run/backlog.jsonl`. These are functions the Phase-21 automation got **close** on but did NOT byte-match. The whole-binary byte-gate is the sole arbiter (G3/P9): **byte-matches bank and are NOT listed here** — only genuine near-misses/blockers are. Ranked by hand-session priority: **reach** (×N propagation leverage) → **closeness** (match_one mismatch count, lower = closer) → **size**. Each row's `best_draft` is the closest C the machine reached — resume from there. -**Open near-misses:** 18 · by status {'near': 16, 'failed': 2} · by class {None: 18} +**Open near-misses:** 17 · by status {'near': 15, 'failed': 2} · by class {None: 17} | # | addr | reach | class | nins | status | closeness | where it stuck | best draft | |--:|------|------:|-------|-----:|--------|----------:|----------------|------------| @@ -21,6 +21,5 @@ | 13 | func_80015B6C | None | | None | near | 44 | 120/120; prologue + most of block1 exact. Residual = two documented walls (6 prior attempts): a 6-ins v0/v1 swap in the D_800B9A02*20 index calc (pinning the load to $2 inert) + sched1 hoisting the xa=x corner copy one slot across the block1/block2 boundary (memory clobber does not stop a pure-register move). Per-block pins (m24=$5, mFF=$7, one=$8, tag/tag2/tag3) + opaque-copy barriers on xa/ya: 8 | `.run/S79w/sonnet/func_80015B6C.c` | | 14 | func_800CF3E8 | None | | None | near | 54 | Recovered the S74 vW body (closeness 256) and drove it to 54 at the exact length 469/469, with all four block sizes exact (19/113/114/223), segment 0 byte-perfect, and all 20 symbols plus their relocation counts identical to the target; rtu_match in the real TU reproduces 54 with no declaration conflict, so this is a real-TU-clean NEAR, not a standalone artefact. The decisive new lever is that zer | `/home/musashi/bfm-decomp/.run/S79w/opus/func_800CF3E8.c` | | 15 | func_8017DC80 | None | | None | near | 84 | The splat "Handwritten function" tag is wrong — this is ordinary gcc-2.7.2 -O2 C, and the TU's "~20 drafts plateaued at LENGTH-DRIFT/-33" wall was simply the GTE macros being undefined and compiling to implicit `jal`s (the card's prior body has that exact defect). Draft is now 346/346 instructions with the exact 0x70 frame, exact stack offsets, and the 9 callee-saved allocations (r=$s4 c=$s2 va=$s | `/home/musashi/bfm-decomp/.run/S79w/opus/func_8017DC80.c` | -| 16 | func_800CB00C | None | | 123 | near | 168 | resolver DIFF (real-TU rtu_match, 20260826-053145): mine=174 target=123 | `.run/wave_g0c/shard30/func_800CB00C.c` | -| 17 | func_800D06E8 | None | | None | failed | | resolver CC1 (real-TU rtu_match, 20260825-233820): .run/resolver/work/resident__func_800D06E8/c0/rtu/func_800D06E8/t.c:1770: conflicting types for `Struct80078E78' | `.run/wave_ch/shard62/func_800D06E8.c` | -| 18 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | +| 16 | func_800D06E8 | None | | None | failed | | resolver CC1 (real-TU rtu_match, 20260825-233820): .run/resolver/work/resident__func_800D06E8/c0/rtu/func_800D06E8/t.c:1770: conflicting types for `Struct80078E78' | `.run/wave_ch/shard62/func_800D06E8.c` | +| 17 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | diff --git a/src/md_MAIN_034/md_MAIN_034.c b/src/md_MAIN_034/md_MAIN_034.c index c664a2145d..9f0ca7df38 100644 --- a/src/md_MAIN_034/md_MAIN_034.c +++ b/src/md_MAIN_034/md_MAIN_034.c @@ -84,7 +84,95 @@ void func_800CAE88(s32 *arg0, s32 p1, s32 p2) { INCLUDE_RODATA("asm/md_MAIN_034/nonmatchings/md_MAIN_034", D_800CAE08); -INCLUDE_ASM("asm/md_MAIN_034/nonmatchings/md_MAIN_034", func_800CB00C); +#include "common.h" + +typedef void (*Fn7_800CB00C)(void *, void *, void *, void *, s32, s32, s32); + +void func_800CB00C(s32 arg0, s32 arg1, s32 arg2) +{ + /* §203/§20 callee-decl recovery, draft-text tier: these seven callees are + * DEFINED later in this same TU with pointer return types whose typedefs are + * also declared later, so a file-scope `extern` here is a hard + * `conflicting types` error and the canonical prototypes cannot be spelled + * before their typedefs exist. gcc-2.7.2 demotes the same clash to a + * warning when the forward declaration sits at BLOCK scope, and every call + * is cast to the byte-target's own signature, so codegen is unchanged. */ + extern void func_800CB1F8(); + extern void func_800CB3C0(); + extern void func_800CBA18(); + extern void func_800CB5D0(); + extern void func_800CB7BC(); + extern void func_800CBC2C(); + extern void func_800CBE28(); + + s32 v0; + s32 a3; + s32 s3; + s32 s2; + s32 s1; + u32 s6; + u32 code; + s32 s0; + + v0 = *(s32 *)(arg0 + 8); + a3 = *(s32 *)(arg0 + 0xC); + s3 = *(s32 *)v0; + s2 = *(s32 *)(v0 + 8); + s1 = *(s32 *)(v0 + 0x10); + + do { + s6 = *(u32 *)a3; + s0 = *(s32 *)(a3 + 4); + a3 += 8; + code = s6 >> 24; + switch ((code & 0xFC) - 0x20) { + case 0: + ((Fn7_800CB00C)func_800CB1F8)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += s0 << 4; + break; + case 8: + ((Fn7_800CB00C)func_800CB3C0)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += (s0 * 5) << 2; + break; + case 12: + ((Fn7_800CB00C)func_800CBA18)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += s0 << 5; + break; + case 16: + ((Fn7_800CB00C)func_800CB5D0)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += (s0 * 5) << 2; + break; + case 24: + ((Fn7_800CB00C)func_800CB7BC)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += (s0 * 3) << 3; + break; + case 20: + ((Fn7_800CB00C)func_800CBC2C)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += (s0 * 7) << 2; + break; + case 28: + ((Fn7_800CB00C)func_800CBE28)((void *)s1, (void *)s3, (void *)s2, + (void *)a3, s0, arg2, + *(s32 *)(arg1 + 4)); + s1 += (s0 * 9) << 2; + break; + } + a3 = (s6 & 0xFFFFFF) | (s32)0x80000000; + } while ((s6 & 0xFFFFFF) != 0); +} + #include "common.h"