diff --git a/config/dedup.us.yaml b/config/dedup.us.yaml index 7704f3e57..2b8f4b7fd 100644 --- a/config/dedup.us.yaml +++ b/config/dedup.us.yaml @@ -13067,3 +13067,10 @@ groups: func: DEFINE_func_80167714 vram: 0x80167714 binaries: [ov_SC01_077, ov_SC01_005, ov_SC01_006, ov_SC03_001, ov_SC01_000, ov_SC01_001, ov_SC02_000, ov_SC02_003, ov_SC03_002, ov_SC03_006, ov_SC04_000, ov_SC04_018, ov_SC04_019, ov_SC05_000, ov_SC06_000, ov_SC07_000, ov_SC01_004, ov_SC01_008, ov_SC01_009, ov_SC01_074, ov_SC01_080, ov_SC01_084, ov_SC02_004, ov_SC02_005, ov_SC02_011, ov_SC02_015, ov_SC02_016, ov_SC02_017, ov_SC02_021, ov_SC02_026, ov_SC02_027, ov_SC02_028, ov_SC02_031, ov_SC02_035, ov_SC02_039, ov_SC02_041, ov_SC03_003, ov_SC03_007, ov_SC03_010, ov_SC03_011, ov_SC03_012, ov_SC03_013, ov_SC03_014, ov_SC03_015, ov_SC03_023, ov_SC03_024, ov_SC03_028, ov_SC03_029, ov_SC03_030, ov_SC03_031, ov_SC03_089, ov_SC03_090, ov_SC03_091, ov_SC03_092, ov_SC03_093, ov_SC03_094, ov_SC03_095, ov_SC03_096, ov_SC03_097, ov_SC03_098, ov_SC03_099, ov_SC03_100, ov_SC03_101, ov_SC03_102, ov_SC03_103, ov_SC03_104, ov_SC03_105, ov_SC03_108, ov_SC03_109, ov_SC03_110, ov_SC03_111, ov_SC03_112, ov_SC03_113, ov_SC03_114, ov_SC03_115, ov_SC03_116, ov_SC03_117, ov_SC03_118, ov_SC03_119, ov_SC03_121, ov_SC03_124, ov_SC03_125, ov_SC03_126, ov_SC04_002, ov_SC04_003, ov_SC04_004, ov_SC04_005, ov_SC04_006, ov_SC04_007, ov_SC04_008, ov_SC04_009, ov_SC04_010, ov_SC04_011, ov_SC04_012, ov_SC04_015, ov_SC04_016, ov_SC04_020, ov_SC04_021, ov_SC05_001, ov_SC05_002, ov_SC05_003, ov_SC05_004, ov_SC05_005, ov_SC05_006, ov_SC05_007, ov_SC05_008, ov_SC05_009, ov_SC05_010, ov_SC05_011, ov_SC05_017, ov_SC05_018, ov_SC05_019, ov_SC06_006, ov_SC06_008, ov_SC06_010, ov_SC06_011, ov_SC06_013, ov_SC06_014, ov_SC06_015, ov_SC06_016, ov_SC06_018, ov_SC06_020, ov_SC06_022, ov_SC06_024, ov_SC06_025, ov_SC06_027, ov_SC06_029, ov_SC06_030, ov_SC06_032, ov_SC06_033, ov_SC07_001, ov_SC07_002, ov_SC07_008, ov_SC07_009] + - id: E_func_80165CA0 + tier: h_exact + hash: 0b19faae66ff52a25ca2b58be1ada578a8dd6b8e + source: src/shared/engine_core.h + func: DEFINE_func_80165CA0 + vram: 0x80165CA0 + binaries: [ov_SC01_077, ov_SC01_000, ov_SC07_006] diff --git a/docs/decision-log.md b/docs/decision-log.md index 07dde4219..ecf519964 100644 --- a/docs/decision-log.md +++ b/docs/decision-log.md @@ -1620,3 +1620,50 @@ loose-typed code in the engine). The cheaper yield is the ~83 non-jtbl targets ( isolate-FAIL corrupts the whole batch, `final SHA None`); and `fix_arity` on a fn in engine_core.h edits fleet-shared state — a `git checkout src//` restore misses `src/shared/`, and the per-overlay build stays byte-identical so nothing flags the leak (caught here by a full `git status` + R22 clean-fleet). + +## 2026-07-23 (Phase 29, SESSION-13) — the reach-138 wave on a P27-onboarded overlay is LOW-ROI; the true lever is LIVE-siblings, and the fresh families are per-member walls / def-side plumbing (R14/R35) + +**Context + belief.** The SESSION-12 checkpoint's option (b): a fresh-exemplar crack-wave on a *higher-reach* +overlay (Task-5 greedy cover, ov_SC03_015/ov_SC07_006 "each ~+0.3–0.6pp of FRESH families"), billed as a +cleaner path than the drained ov_SC06_018 non-jtbl tail. Belief: ov_SC07_006's **122 draft-now reach-138 WAVE +families** (all cached, zero prefetch) are untouched fresh fuel — one crack + sweep banks ×138 (the SESSION-11 +`func_801365B8 ×138` precedent). + +**What happened.** `tools/build_wave_args.py` (new) emitted the top-24 reach-138 families **ranked by the fuel +manifest's `nins*reach` leverage**. Wave (`wave_binary.js`, 24 xHigh): 16 self-assessed MATCH, 8 killed by the +Anthropic session usage limit. Byte-gate: **2 via plain harvest_verify + 4 via `gate_stage` reconcile = 6 ×1 +banked**; 17 failed as PLUMBING (`conflicting types for func_XXXX/D_XXXX`), 2 CC1-FAIL, 2 DIFF. Propagation: +`dedup_propagate --addr` banked **func_801325B8 → +3 onboarded-tail siblings**; func_8014A048/func_801678F0 +**byte-diverge** in the SC07 cluster (kept ×1); func_8014FE60/func_80167540 **local-type-blocked** (§20 cap); +**func_80165CA0 consolidated its h_exact subgroup (+0 new)** and then **swept 0/135** via `family_sweep --hseq` +— a per-member wall like func_80133AB0 (0/136). **Net batch-1 yield ≈ 9 newly-matched functions**; ov_SC07_006 +84.6% → 84.8%; fleet +0.1pp instr, ~0 distinct. R22 clean-fleet 140/140 twice (the engine_core.h arity edit +was fleet-safe); tools-health green. + +**The finding (R14/R35 — verify the leverage assumption against the bytes BEFORE scaling).** The fuel +manifest's `nins*reach` leverage **badly over-counts**: a reach-138 family already matched in ~135 overlays +yields **+(live siblings)** on a fresh crack, not +138. Re-scoping the 122-fn pool by **actual live-sibling +count** (grep INCLUDE_ASM): **76 "fresh" (≥100 live) vs 44 onboarded-tail (<5 live)**. And the two classes have +OPPOSITE difficulty: the **onboarded-tail** families bank *easily* (they have a matched sibling in ~135 +overlays to port verbatim — 5 of the 6 banks) but yield only +few; the **genuine fresh** families are the HARD +tail — batch-1's fresh-138 attempts FAILED as **def-side plumbing** (`conflicting types for func_XXXX`, needs +§54 `--fix-def-sig`, which `gate_stage`'s caller-arity pre-pass does NOT clear), **genuine DIFF** (permuter +fuel), or **per-member walls** (func_80165CA0). A fresh crack does **not** reliably unlock its family. + +**Why this is a good outcome, not a wasted batch.** (1) The corrected lever is durable: `build_wave_args.py` +now ranks by `--rank live` and reports the fresh/tail split, so future scoping targets the true fuel and never +again mistakes an onboarded-tail family's inflated `nins*reach` for leverage. (2) It confirms — from a fresh +overlay ov077/ov_SC06_018 never sourced from — that the reach-138 *family well is largely SPENT via wave+gate* +(the Phase-26 "h_seq templatable-families thesis is byte-proven SPENT" finding, now re-confirmed on the SC07 +cluster). The remaining reach-138 residual is per-function (permuter + §54), not breadth. + +**Hindsight better-path.** (a) Rank by live-count AND *require a matched-sibling-to-adapt* — that combination +is what banks (the tail wins had siblings; the sibling-less fresh families didn't). (b) The onboarded SC07 +overlays (006/007/010/011) are a **distinct less-shared ~84% cluster** (1549 vs 1702 distinct-code base), not +merely un-integrated — so a "sweep every matched family into them" pass will hit the same per-member +divergence batch-1 saw (func_8014A048/func_801678F0 diverge; two more local-type-blocked). (c) The genuinely +higher-ROI next move is NOT more ov_SC07_006 wave batches — it is either the per-function grind (permuter on +the DIFFs, §54 `--fix-def-sig` on the def-side-plumbing failures) or a different lever entirely (Task 7's +ROI-gated close arithmetic now has a third low-yield data point: ov_SC06_018 non-jtbl tail ≈0.1pp, this ≈9 +functions). **Do NOT close P29 on ROI — the burn-down floor is still undetermined (needs 3 session-close +deltas).** diff --git a/docs/family-hseq.md b/docs/family-hseq.md index df0f3fc70..135432468 100644 --- a/docs/family-hseq.md +++ b/docs/family-hseq.md @@ -2,11 +2,11 @@ > Generated by `tools/family_hseq.py` from the 134 overlay sigs + per-overlay src stubs. Ranked by TEMPLATABLE byte-weight (PURE+IMM members × nins × 4). The byte-gate is the arbiter. -**Fleet (overlays):** 88.4% fn / 79.0% instr / 68.4% distinct-code matched. Unmatched: 40,629 instances / 2,744,690 ins (22,621 distinct classes). +**Fleet (overlays):** 88.5% fn / 79.0% instr / 68.4% distinct-code matched. Unmatched: 40,620 instances / 2,743,730 ins (22,621 distinct classes). **Tail cross-check (Phase-25 close):** 27,520 tail fns / 1,103,065 ins → 574 h_seq families ≥2, **158 substantial (nins≥80) / 616,402 ins**. -**Full frontier (all unmatched by h_seq):** 2722 target families (≥2 members or a matched sibling) + 3780 singletons (Step-D residue). Substantial: **559 families / 1,450,299 templatable ins**, 75 with a matched sibling (zero-crack). Substantial member classes: 9,119 PURE · 40 IMM · 6 STRUCT-excluded. +**Full frontier (all unmatched by h_seq):** 2721 target families (≥2 members or a matched sibling) + 3780 singletons (Step-D residue). Substantial: **558 families / 1,449,339 templatable ins**, 74 with a matched sibling (zero-crack). Substantial member classes: 9,110 PURE · 40 IMM · 6 STRUCT-excluded. ## Top substantial families (by templatable byte-weight) @@ -45,8 +45,8 @@ | 30 | 105 | 135 (135/0/0) | 1/135 | per-location | PURE | 3 | · | 0x801749c8 matched-ov077 | 14,175 | | 31 | 101 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x801463a0 draft-ov077 | 13,938 | | 32 | 101 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x80177940 draft-ov077 | 13,938 | -| 33 | 99 | 136 (136/0/0) | 1/136 | per-location | PURE | 2 | · | 0x80165ca0 matched-ov077 | 13,464 | -| 34 | 97 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x8014cd80 draft-ov077 | 13,386 | +| 33 | 97 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x8014cd80 draft-ov077 | 13,386 | +| 34 | 99 | 135 (135/0/0) | 1/135 | per-location | PURE | 3 | · | 0x80165ca0 matched-ov077 | 13,365 | | 35 | 94 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x8016b6bc draft-ov077 | 12,972 | | 36 | 97 | 133 (133/0/0) | 1/133 | per-location | PURE | 5 | · | 0x8017b490 matched-ov077 | 12,901 | | 37 | 93 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x8014d12c draft-ov077 | 12,834 | diff --git a/docs/progress.fleet.md b/docs/progress.fleet.md index cc949ad81..aab045f69 100644 --- a/docs/progress.fleet.md +++ b/docs/progress.fleet.md @@ -4,23 +4,23 @@ # cross-binary collapsible-byte leverage: docs/duplicates.cross.md. # THREE progress metrics (all matter — see the labels): -FLEET fn-count byte-ident: 312044 / 353722 = 88.22% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) -FLEET instr-weighted : 10336291 / 13141652 = 78.7% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number) +FLEET fn-count byte-ident: 312042 / 353717 = 88.22% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) +FLEET instr-weighted : 10336630 / 13141652 = 78.7% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number) FLEET distinct-code(uniq): 3810787 / 5634875 = 67.6% (64824/87459 unique fns; the DISTINCT-RE number) MAIN game-code weighted : 436 / 60201 = 0.7% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-06-14; caveat is R34: no independent second oracle for a PS-X EXE, NOT drift) - (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 10335855 / 13081451 = 79.0%) + (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 10336194 / 13081451 = 79.0%) -FLEET REAL substantive : 310189 (of which dedup-shared 234571 via 1849 groups / 234615 instances) +FLEET REAL substantive : 310187 (of which dedup-shared 234574 via 1850 groups / 234618 instances) FLEET LINKED PsyQ objs : 959 FLEET NON_MATCHING : 7 (0 in any default build — G4) -FLEET INCLUDE_ASM stubs : 41671 -FLEET matchable : 353722 +FLEET INCLUDE_ASM stubs : 41668 +FLEET matchable : 353717 | binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % | |---|---:|---:|---:|---:|---:|---:| | main | 54 | 2 | 959 | 1055 | 2096 | 50.3% | | resident | 129 | 0 | 0 | 131 | 145 | 90.3% | -| ov_SC01_000 | 2227 | 1707 | 0 | 2227 | 2403 | 92.7% | +| ov_SC01_000 | 2227 | 1708 | 0 | 2227 | 2403 | 92.7% | | ov_SC01_001 | 2227 | 1707 | 0 | 2229 | 2466 | 90.4% | | ov_SC01_004 | 2218 | 1698 | 0 | 2219 | 2414 | 91.9% | | ov_SC01_005 | 2247 | 1720 | 0 | 2247 | 2503 | 89.8% | @@ -28,7 +28,7 @@ FLEET matchable : 353722 | ov_SC01_008 | 2218 | 1698 | 0 | 2220 | 2426 | 91.5% | | ov_SC01_009 | 2243 | 1699 | 0 | 2244 | 2507 | 89.5% | | ov_SC01_074 | 2222 | 1699 | 0 | 2224 | 2425 | 91.7% | -| ov_SC01_077 | 2411 | 1667 | 0 | 2413 | 2585 | 93.3% | +| ov_SC01_077 | 2411 | 1668 | 0 | 2413 | 2585 | 93.3% | | ov_SC01_080 | 2260 | 1702 | 0 | 2260 | 2512 | 90.0% | | ov_SC01_084 | 2267 | 1702 | 0 | 2272 | 2579 | 88.1% | | ov_SC02_000 | 2320 | 1737 | 0 | 2320 | 2683 | 86.5% | @@ -152,9 +152,9 @@ FLEET matchable : 353722 | ov_SC07_000 | 2246 | 1706 | 0 | 2248 | 2521 | 89.2% | | ov_SC07_001 | 2230 | 1702 | 0 | 2232 | 2454 | 91.0% | | ov_SC07_002 | 2257 | 1702 | 0 | 2261 | 2579 | 87.7% | -| ov_SC07_006 | 2003 | 1549 | 0 | 2083 | 2456 | 84.8% | -| ov_SC07_007 | 2014 | 1550 | 0 | 2098 | 2614 | 80.3% | +| ov_SC07_006 | 2002 | 1550 | 0 | 2082 | 2455 | 84.8% | +| ov_SC07_007 | 2014 | 1550 | 0 | 2098 | 2613 | 80.3% | | ov_SC07_008 | 2215 | 1702 | 0 | 2215 | 2386 | 92.8% | | ov_SC07_009 | 2224 | 1702 | 0 | 2226 | 2430 | 91.6% | -| ov_SC07_010 | 2026 | 1550 | 0 | 2109 | 2526 | 83.5% | -| ov_SC07_011 | 2013 | 1549 | 0 | 2093 | 2450 | 85.4% | +| ov_SC07_010 | 2025 | 1550 | 0 | 2108 | 2524 | 83.5% | +| ov_SC07_011 | 2013 | 1549 | 0 | 2093 | 2449 | 85.5% | diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 9b46a3072..02ff0679c 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -1475,3 +1475,56 @@ conditional) · main-EXE/B9 + GLM/B6 + resident's 14 walls (P30) · behemoths B7 > - **DO NOT close P29 on ROI** (burn-down floor still undetermined). **CARRIED:** the 5 batch-1 deferred matches > (missing-sym/§58/deeper) + the jtbl residuals (func_80135260 %hi-share = permuter seed). `wave_binary.js` is > the reusable binary-aware wave; scope `.run/wave_sc06018_nonjtbl.json`. + +- **✅ 2026-07-23 (SESSION-13, ultracode) — took option (b): ov_SC07_006 reach-138 fresh-exemplar crack-wave + batch-1. Fleet 78.6→78.7% instr · 67.6 distinct (flat) · 88.22 fn-count (flat); ov_SC07_006 84.6→84.8%.** + New `tools/build_wave_args.py` emits `wave_binary.js` args from a fuel manifest (asm/ghidra_c path resolve + + jtbl detect). Scoped ov_SC07_006 = **122 draft-now reach-138 WAVE families** (all cached → zero prefetch; + ov_SC03_015 had 100 but 227 uncached). Ran batch-1 = **top-24 by nins*reach leverage** (`wave_binary.js`, 24 + xHigh). **Wave: 16 self-assessed MATCH, 8 killed by the Anthropic session usage limit** (resets ~1:40am + Denver — no more agent waves possible this session). + **Byte-gate ladder (all inline, no agent tokens): 6 ×1 banked** — plain harvest_verify 2 (func_801325B8, + func_80165CA0) + `gate_stage` reconcile 4 (func_8014FE60, func_8014A048, func_801678F0, func_80167540). 17 + PLUMBING-fail / 2 CC1-FAIL / 2 DIFF. **Propagation (§55b: banks committed FIRST, then targeted):** + `dedup_propagate --addr` → **func_801325B8 +3 onboarded-tail siblings**; func_8014A048/func_801678F0 + byte-DIVERGE in the SC07 cluster (×1); func_8014FE60/func_80167540 local-type-blocked §20 (×1); + **func_80165CA0 consolidated its h_exact subgroup (+0) then `family_sweep --hseq` 0/135 — a PER-MEMBER WALL** + (like func_80133AB0 0/136). **Net ≈ 9 newly-matched functions.** R22 clean-fleet 140/140 ×2 (engine_core.h + arity edit fleet-safe); tools-health green (dedup 1850/0). + **THE FINDING (R14/R35 → decision-log 2026-07-23):** the fuel manifest's `nins*reach` leverage OVER-COUNTS — + a reach-138 family matched in ~135 overlays yields +(live), not +138. Corrected metric = **live-siblings**: + the 122-pool splits **76 fresh (≥100 live) / 44 onboarded-tail (<5 live)**, and they have OPPOSITE difficulty + — the tail banks easily (has a sibling to port; 5 of 6 banks) but +few; the fresh families are the HARD tail + (def-side plumbing `conflicting types for func_XXXX` → §54 `--fix-def-sig`; DIFF → permuter; per-member + walls). A fresh crack does NOT reliably unlock its family. `build_wave_args.py --rank live` now ranks by the + true lever + reports the fresh/tail split. Commits: `commit:0848` (6 banks) + the propagation/tooling commit. + +> **🛑 SESSION-13 CHECKPOINT (2026-07-23, ultracode) — supersedes SESSION-12; safe to open a FRESH session here.** +> Tree clean after commit (only R23 `db.*.gbf` churn). **R22 clean-fleet 140/140 byte-identical** ×2; +> tools-health OK (dedup 1850/0, 0 NON_MATCHING G4). **Drew pushes** (R6/R20). Commits: `commit:0848` + the +> propagation/tooling/checkpoint commit. +> **Fleet: 78.7% instr · 67.6% distinct · 88.22% fn-count** (SESSION-12 opened 78.6/67.6/88.22 → **+0.1 instr, +> flat distinct/fn** — a SMALL, honest delta; the reach-138 wave path is LOW-ROI, 3rd such data point). +> +> **WHAT LANDED (all byte-gated, committed):** +> 1. **ov_SC07_006 reach-138 batch-1: 6 ×1 banks + 3 propagated = ~9 functions** (84.6→84.8%). Wave killed +> early by the usage limit (8/24 drafters). +> 2. **The corrected-metric finding** (R14/R35): rank by LIVE-siblings, not `nins*reach`. `build_wave_args.py +> --rank live` shipped. The reach-138 family well is largely SPENT via wave+gate (re-confirms Phase-26). +> 3. func_80165CA0 = a per-member wall (0/135 sweep) — the fresh-exemplar bet is family-specific, and this one +> lost. +> +> **▶ NEXT — the batch-1 evidence says DON'T run more ov_SC07_006 wave batches (low-ROI). Options, ranked:** +> - **(a) RE-SCOPE FIRST (cheap, token-free):** `build_wave_args.py --rank live --min-live 100 --binary ov_SC07_006` +> emits the 76 genuine-fresh pool; then decide if ANY are worth a permuter/§54 attack. Most fresh-138 are +> walls/def-side-plumbing (batch-1 proof), so expect a thin real yield. +> - **(b) TOKEN-FREE per-function grind (I am out of agent-wave budget):** permuter/grinder on batch-1's 2 DIFFs +> (func_80177940, func_80169228 — incomplete session-limit drafts) + the 7 gate-near reconcile-fails; and +> `family_sweep --fix-def-sig` (§54) on the def-side-plumbing fails (func_8014D12C/func_80168070/func_8014CD80 +> — "conflicting types for func_XXXX"). Drafts staged in `.run/drafts-sc07006-b1/`, pool +> `.run/wave_sc07006_nonjtbl_pool.json`. +> - **(c) A DIFFERENT lever entirely** — the reach-138 family campaign's easy wins are banked; Task 7's +> ROI-gated close now has 3 low-yield data points (ov_SC06_018 non-jtbl ≈0.1pp; ov_SC07_006 reach-138 ≈9 fns). +> - **DO NOT close P29 on ROI** — burn-down floor still undetermined (needs 3 session-close deltas; this is one). +> **CARRIED:** the 8 session-limit-unfinished drafts (redraft when the limit resets); `func_80165CA0`/the +> diverging tail families are documented walls — do NOT re-sweep. diff --git a/src/ov_SC01_000/ov_SC01_000_jr_8015C32C.c b/src/ov_SC01_000/ov_SC01_000_jr_8015C32C.c index 451dea61e..995feb24e 100644 --- a/src/ov_SC01_000/ov_SC01_000_jr_8015C32C.c +++ b/src/ov_SC01_000/ov_SC01_000_jr_8015C32C.c @@ -4520,41 +4520,7 @@ extern s32 D_8011D030; extern s32 D_80126728; #define SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x)) -void func_80165CA0(void) { - register s32 i __asm__("$17"); - s32 off; - u16 *q; - s32 a1, base; - short *p; - register short v __asm__("$2"); - register short w __asm__("$3"); - i = 0; q = &D_8011D030; - do { - if (*q != 0) (*(void (**)(u16 *))((u32)*q * 4 + D_80126728))(q); - i = i + 1; q = q + 0x2c; - } while (i < 0x1e); - i = 0; off = 0; - do { - base = (s32)&D_8011D030; SHB(base); - a1 = off + base; - p = *(short **)(a1 + 0x20); - if (p != 0) { - s32 q2; - if ((u16)*p == 1) { - v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(p + 0x24) = v; - v = *(short *)(a1 + 0xa); p[5] = v; SHB(v); *(int *)(p + 0x26) = v; - w = *(short *)(a1 + 0xe); p[6] = w; v = p[0x16] | 1; SHB(w); p[0x16] = v; *(int *)(p + 0x28) = w; - } else if ((q2 = *(int *)(p + 0x1a)) != 0) { - v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(q2 + 0x14) = v; - v = *(short *)(a1 + 0xa); p[5] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x18) = v; - v = *(short *)(a1 + 0xe); p[6] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x1c) = v; - } else { - p[4] = *(short *)(a1 + 6); p[5] = *(short *)(a1 + 0xa); p[6] = *(short *)(a1 + 0xe); - } - } - i = i + 1; off = off + 0x58; - } while (i < 0x1e); -} +DEFINE_func_80165CA0() /* dedup: shared engine-core @0x80165CA0 (src/shared) */ extern M2C_UNK D_801A3E64; diff --git a/src/ov_SC01_077/ov_SC01_077_jr_8015C32C.c b/src/ov_SC01_077/ov_SC01_077_jr_8015C32C.c index a918870df..46772e279 100644 --- a/src/ov_SC01_077/ov_SC01_077_jr_8015C32C.c +++ b/src/ov_SC01_077/ov_SC01_077_jr_8015C32C.c @@ -4649,44 +4649,7 @@ DEFINE_func_80165C78() /* dedup: shared engine-core @0x80165C78 (src/shared) */ extern s32 D_8011D030; extern s32 D_80126728; #define SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x)) -void func_80165CA0(void) { - extern s32 D_8011D030; - extern s32 D_80126728; - - register s32 i __asm__("$17"); - s32 off; - u16 *q; - s32 a1, base; - short *p; - register short v __asm__("$2"); - register short w __asm__("$3"); - i = 0; q = &D_8011D030; - do { - if (*q != 0) (*(void (**)(u16 *))((u32)*q * 4 + D_80126728))(q); - i = i + 1; q = q + 0x2c; - } while (i < 0x1e); - i = 0; off = 0; - do { - base = (s32)&D_8011D030; SHB(base); - a1 = off + base; - p = *(short **)(a1 + 0x20); - if (p != 0) { - s32 q2; - if ((u16)*p == 1) { - v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(p + 0x24) = v; - v = *(short *)(a1 + 0xa); p[5] = v; SHB(v); *(int *)(p + 0x26) = v; - w = *(short *)(a1 + 0xe); p[6] = w; v = p[0x16] | 1; SHB(w); p[0x16] = v; *(int *)(p + 0x28) = w; - } else if ((q2 = *(int *)(p + 0x1a)) != 0) { - v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(q2 + 0x14) = v; - v = *(short *)(a1 + 0xa); p[5] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x18) = v; - v = *(short *)(a1 + 0xe); p[6] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x1c) = v; - } else { - p[4] = *(short *)(a1 + 6); p[5] = *(short *)(a1 + 0xa); p[6] = *(short *)(a1 + 0xe); - } - } - i = i + 1; off = off + 0x58; - } while (i < 0x1e); -} +DEFINE_func_80165CA0() /* dedup: shared engine-core @0x80165CA0 (src/shared) */ M2C_UNK func_8001534C(M2C_UNK, M2C_UNK *, M2C_UNK, M2C_UNK, s32, s32); /* extern */ M2C_UNK func_800153CC(M2C_UNK, u16, M2C_UNK, M2C_UNK, s32, s32); /* extern */ diff --git a/src/ov_SC07_006/ov_SC07_006_jr_80131340.c b/src/ov_SC07_006/ov_SC07_006_jr_80131340.c index a3aa7aeea..d71c9e450 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_80131340.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_80131340.c @@ -1084,64 +1084,7 @@ DEFINE_func_8013240C() /* dedup: shared engine-core @0x8013240c (src/shared) */ // @class: plumbing // @stuck: none — MATCH (reuse of proven DEFINE_func_801325B8 body, engine_core.h h_exact) -extern void memcpy(); -extern void gteMIMefunc(); -void func_801325B8(int dst, int src, int m0, int mm, int arg5) -{ - register int p __asm__("$4"); - register int m __asm__("$16"); - register int n __asm__("$17"); - register int dv __asm__("$18"); - int sv; - int ofs; - int c; - m = m0; - p = src; - if (*(int *)(p + 4) == 1) { - sv = *(int *)(p + 0xC); - } else { - ofs = (int)((*(unsigned int *)(p + 0xC) >> 2) << 2) + 0xC; - sv = p + ofs; - } - p = dst; - sv += *(int *)(m + 8) * 8; - if (*(int *)(p + 4) == 1) { - dv = *(int *)(p + 0xC); - } else { - ofs = (int)((*(unsigned int *)(p + 0xC) >> 2) << 2) + 0xC; - dv = p + ofs; - } - c = *(int *)(m + 8); - dv += c * 8; - n = *(int *)(m + 0xC); - m += 0x10; - memcpy(dv, sv, n * 8); - gteMIMefunc(dv, m, n, arg5); - if (mm != 0) { - m = mm; - p = src; - if (*(int *)(p + 4) == 1) { - sv = *(int *)(p + 0x14); - } else { - ofs = (int)((*(unsigned int *)(p + 0x14) >> 2) << 2) + 0xC; - sv = p + ofs; - } - p = dst; - sv += *(int *)(m + 8) * 8; - if (*(int *)(p + 4) == 1) { - dv = *(int *)(p + 0x14); - } else { - ofs = (int)((*(unsigned int *)(p + 0x14) >> 2) << 2) + 0xC; - dv = p + ofs; - } - c = *(int *)(m + 8); - dv += c * 8; - n = *(int *)(m + 0xC); - m += 0x10; - memcpy(dv, sv, n * 8); - gteMIMefunc(dv, m, n, arg5); - } -} +DEFINE_func_801325B8() /* dedup: shared engine-core @0x801325B8 (src/shared) */ void func_8013277C(void) { diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c index f81ac8014..5cc8cba8b 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c @@ -5243,41 +5243,7 @@ extern s32 D_8011D030; extern s32 D_80126728; #define SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x)) -void func_80165CA0(void) { - register s32 i __asm__("$17"); - s32 off; - u16 *q; - s32 a1, base; - short *p; - register short v __asm__("$2"); - register short w __asm__("$3"); - i = 0; q = &D_8011D030; - do { - if (*q != 0) (*(void (**)(u16 *))((u32)*q * 4 + D_80126728))(q); - i = i + 1; q = q + 0x2c; - } while (i < 0x1e); - i = 0; off = 0; - do { - base = (s32)&D_8011D030; SHB(base); - a1 = off + base; - p = *(short **)(a1 + 0x20); - if (p != 0) { - s32 q2; - if ((u16)*p == 1) { - v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(p + 0x24) = v; - v = *(short *)(a1 + 0xa); p[5] = v; SHB(v); *(int *)(p + 0x26) = v; - w = *(short *)(a1 + 0xe); p[6] = w; v = p[0x16] | 1; SHB(w); p[0x16] = v; *(int *)(p + 0x28) = w; - } else if ((q2 = *(int *)(p + 0x1a)) != 0) { - v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(q2 + 0x14) = v; - v = *(short *)(a1 + 0xa); p[5] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x18) = v; - v = *(short *)(a1 + 0xe); p[6] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x1c) = v; - } else { - p[4] = *(short *)(a1 + 6); p[5] = *(short *)(a1 + 0xa); p[6] = *(short *)(a1 + 0xe); - } - } - i = i + 1; off = off + 0x58; - } while (i < 0x1e); -} +DEFINE_func_80165CA0() /* dedup: shared engine-core @0x80165CA0 (src/shared) */ diff --git a/src/ov_SC07_007/ov_SC07_007_jr_80131340.c b/src/ov_SC07_007/ov_SC07_007_jr_80131340.c index 5e5c4c522..7961c97d3 100644 --- a/src/ov_SC07_007/ov_SC07_007_jr_80131340.c +++ b/src/ov_SC07_007/ov_SC07_007_jr_80131340.c @@ -1082,7 +1082,7 @@ DEFINE_func_80132288() /* dedup: shared engine-core @0x80132288 (src/shared) */ DEFINE_func_8013240C() /* dedup: shared engine-core @0x8013240c (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_007/nonmatchings/ov_SC07_007_jr_80131340", func_801325B8); +DEFINE_func_801325B8() /* dedup: shared engine-core @0x801325B8 (src/shared) */ void func_8013277C(void) { } diff --git a/src/ov_SC07_010/ov_SC07_010_jr_80131340.c b/src/ov_SC07_010/ov_SC07_010_jr_80131340.c index ab58c1c2a..426847294 100644 --- a/src/ov_SC07_010/ov_SC07_010_jr_80131340.c +++ b/src/ov_SC07_010/ov_SC07_010_jr_80131340.c @@ -1087,7 +1087,7 @@ DEFINE_func_80132288() /* dedup: shared engine-core @0x80132288 (src/shared) */ DEFINE_func_8013240C() /* dedup: shared engine-core @0x8013240c (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_010/nonmatchings/ov_SC07_010_jr_80131340", func_801325B8); +DEFINE_func_801325B8() /* dedup: shared engine-core @0x801325B8 (src/shared) */ void func_8013277C(void) { } diff --git a/src/ov_SC07_010/ov_SC07_010_jr_80140608.c b/src/ov_SC07_010/ov_SC07_010_jr_80140608.c index 2e3b7457a..869b07aa7 100644 --- a/src/ov_SC07_010/ov_SC07_010_jr_80140608.c +++ b/src/ov_SC07_010/ov_SC07_010_jr_80140608.c @@ -2586,60 +2586,7 @@ s32 func_80149FB0(s32 a0) { } -extern u8 func_8014BEF8(void); -extern void func_8012F14C(s32); -extern s32 func_80135260(s32, s32, s32, s32); -extern void func_8014A1B0(s32 a0, s32 a1); -s32 func_8014A048(s32 param_1) { - - extern u8 D_801202A0[]; - Loc L; - s32 s0; - s32 s2; - u32 s3; - if ((*(u32 *)(param_1 + 0x44) & 0x400) != 0) { - return 0; - } - if ((*(u16 *)(param_1 + 0xAC) & 0x80) == 0) { - if ((*(u16 *)(param_1 + 0xAC) & 0x10) == 0) { - return 0; - } - if (((s32 (*)(s32))func_8014BEF8)(param_1) == 0) { - goto ret0; - } - } - L.a30 = *(s16 *)(param_1 + 6); - L.a2e = *(s16 *)(param_1 + 0xA); - L.a2c = *(s16 *)(param_1 + 0xE); - L.a1e = -0x10; - L.a20 = 0; - L.a1c = -0x20; - ((void (*)(s32, s32, s32))func_8012F14C)(*(s32 *)(param_1 + 0x20) + 0x34, (s32)&L.a20, (s32)L.buf); - s3 = 0; - s2 = 0; - while (1) { - s0 = (s32)D_801202A0 + s2; - __asm__ __volatile__("" : "=r"(s0) : "0"(s0)); - if ((*(u16 *)s0 != 0) && - (*(s32 *)(s0 + 0x58) != 0) && - (*(s16 *)(s0 + 0xAA) == 0) && - (*(s32 *)(param_1 + 0x184) != s0) && - ((*(u16 *)(s0 + 0x5C) & 0x200) != 0) && - (((s32 (*)(s32, s32, s32, s32))func_80135260)(*(s32 *)(s0 + 0x20), *(s32 *)(s0 + 0x58), (s32)&L.a30, (s32)L.buf) != 0)) { - break; - } - s3++; - s2 += 0x10C; - if (s3 >= 0x60) { - return 0; - } - } - *(s32 *)(param_1 + 0x178) = s0; - func_8014A1B0(param_1, s0); - return 1; -ret0: - return 0; -} +DEFINE_func_8014A048() /* dedup: shared engine-core @0x8014A048 (src/shared) */ DEFINE_func_8014A1B0() /* dedup: shared engine-core @0x8014a1b0 (src/shared) */ diff --git a/src/ov_SC07_011/ov_SC07_011_jr_80131340.c b/src/ov_SC07_011/ov_SC07_011_jr_80131340.c index beda70aff..0e099b775 100644 --- a/src/ov_SC07_011/ov_SC07_011_jr_80131340.c +++ b/src/ov_SC07_011/ov_SC07_011_jr_80131340.c @@ -1082,7 +1082,7 @@ DEFINE_func_80132288() /* dedup: shared engine-core @0x80132288 (src/shared) */ DEFINE_func_8013240C() /* dedup: shared engine-core @0x8013240c (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_011/nonmatchings/ov_SC07_011_jr_80131340", func_801325B8); +DEFINE_func_801325B8() /* dedup: shared engine-core @0x801325B8 (src/shared) */ void func_8013277C(void) { } diff --git a/src/shared/engine_core.h b/src/shared/engine_core.h index 13b9e88a5..f6d0da68d 100644 --- a/src/shared/engine_core.h +++ b/src/shared/engine_core.h @@ -28043,4 +28043,43 @@ ((void (*)(s32))func_80146C3C)(param_1); \ } +#define DEFINE_func_80165CA0() \ + void func_80165CA0(void) { \ + extern s32 D_8011D030; \ + extern s32 D_80126728; \ + register s32 i __asm__("$17"); \ + s32 off; \ + u16 *q; \ + s32 a1, base; \ + short *p; \ + register short v __asm__("$2"); \ + register short w __asm__("$3"); \ + i = 0; q = &D_8011D030; \ + do { \ + if (*q != 0) (*(void (**)(u16 *))((u32)*q * 4 + D_80126728))(q); \ + i = i + 1; q = q + 0x2c; \ + } while (i < 0x1e); \ + i = 0; off = 0; \ + do { \ + base = (s32)&D_8011D030; SHB(base); \ + a1 = off + base; \ + p = *(short **)(a1 + 0x20); \ + if (p != 0) { \ + s32 q2; \ + if ((u16)*p == 1) { \ + v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(p + 0x24) = v; \ + v = *(short *)(a1 + 0xa); p[5] = v; SHB(v); *(int *)(p + 0x26) = v; \ + w = *(short *)(a1 + 0xe); p[6] = w; v = p[0x16] | 1; SHB(w); p[0x16] = v; *(int *)(p + 0x28) = w; \ + } else if ((q2 = *(int *)(p + 0x1a)) != 0) { \ + v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(q2 + 0x14) = v; \ + v = *(short *)(a1 + 0xa); p[5] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x18) = v; \ + v = *(short *)(a1 + 0xe); p[6] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x1c) = v; \ + } else { \ + p[4] = *(short *)(a1 + 6); p[5] = *(short *)(a1 + 0xa); p[6] = *(short *)(a1 + 0xe); \ + } \ + } \ + i = i + 1; off = off + 0x58; \ + } while (i < 0x1e); \ + } + #endif diff --git a/tools/build_wave_args.py b/tools/build_wave_args.py index c7b778d7f..40dc6d88a 100644 --- a/tools/build_wave_args.py +++ b/tools/build_wave_args.py @@ -13,10 +13,21 @@ Usage: build_wave_args.py --fuel .run/fuel_ov_SC07_006.json --binary ov_SC07_006 \ --batch 24 --out-prefix .run/wave_sc07006 --draft-dir .run/drafts-sc07006-b1 """ -import argparse, glob, json, os, re, sys +import argparse, glob, json, os, re, subprocess, sys JR = re.compile(r"\bjr\s+\$(\w+)") + +def live_count(fn): + """Number of overlays that still hold `fn` as an INCLUDE_ASM stub (the TRUE lever). + + R14/R35 (Phase-29 batch-1): the fuel manifest's nins*reach `leverage` over-counts — + a reach-138 family already matched in ~135 overlays yields only +(live) on a fresh + crack, not +138. Rank by LIVE siblings, not family span.""" + r = subprocess.run(["grep", "-rl", rf"INCLUDE_ASM.*\b{fn}\b", "src/"], + capture_output=True, text=True) + return len([l for l in r.stdout.splitlines() if l.strip()]) + def has_own_jtbl(asm_path): try: with open(asm_path) as f: @@ -46,13 +57,18 @@ def main(): ap.add_argument("--draft-dir", required=True) ap.add_argument("--klass", default="WAVE") ap.add_argument("--max-nins", type=int, default=150, help="skip GIANT-sized bodies") + ap.add_argument("--rank", choices=["live", "leverage"], default="live", + help="live = rank by live-sibling count (the TRUE lever, R14/R35); " + "leverage = legacy nins*reach (over-counts onboarded-tail families)") + ap.add_argument("--min-live", type=int, default=0, + help="drop families with fewer than this many live siblings " + "(e.g. 100 = genuine fresh families only, skipping the onboarded tail)") args = ap.parse_args() targets = json.load(open(args.fuel))["targets"] pool = [t for t in targets if t["class"] == args.klass and t["reach"] >= args.reach and t.get("cached") and t["nins"] <= args.max_nins] - pool.sort(key=lambda t: -t["leverage"]) recs_nonjtbl, recs_jtbl, missing = [], [], [] for t in pool: @@ -61,28 +77,40 @@ def main(): if asm is None: missing.append(name) continue + lc = live_count(name) + if lc < args.min_live: + continue rec = { "name": name, "addr": t["addr"], "nins": t["nins"], "reach": t["reach"], "asm": asm, "asm_subdir": subdir, "ghidra_c": f".run/ghidra_c/{name}.c", "own_jtbl": has_own_jtbl(asm), "o0": False, "sibling_ov077": None, - "leverage": t["leverage"], "region": t.get("region"), + "leverage": t["leverage"], "live": lc, "region": t.get("region"), } (recs_jtbl if rec["own_jtbl"] else recs_nonjtbl).append(rec) + key = (lambda r: -r["live"]) if args.rank == "live" else (lambda r: -r["leverage"]) + recs_nonjtbl.sort(key=key) + recs_jtbl.sort(key=key) + fresh = sum(1 for r in recs_nonjtbl if r["live"] >= 100) + tail = sum(1 for r in recs_nonjtbl if r["live"] < 5) + batch = recs_nonjtbl[:args.batch] b1 = {"binary": args.binary, "draftDir": args.draft_dir, "targets": batch} json.dump(b1, open(f"{args.out_prefix}_b1_args.json", "w"), indent=1) json.dump(recs_nonjtbl, open(f"{args.out_prefix}_nonjtbl_pool.json", "w"), indent=1) json.dump(recs_jtbl, open(f"{args.out_prefix}_jtbl_pool.json", "w"), indent=1) - print(f"binary={args.binary} reach>={args.reach} class={args.klass} cached-pool={len(pool)}") + print(f"binary={args.binary} reach>={args.reach} class={args.klass} " + f"cached-pool={len(pool)} rank={args.rank} min-live={args.min_live}") print(f" non-jtbl: {len(recs_nonjtbl)} jtbl: {len(recs_jtbl)} asm-missing: {len(missing)}") + print(f" FRESH (>=100 live): {fresh} onboarded-tail (<5 live): {tail} " + f"[fresh = the real fuel; tail = already matched in ~135, +few on a crack]") if missing: print(f" missing asm (skipped): {missing[:8]}{'...' if len(missing)>8 else ''}") - print(f" batch-1 = top {len(batch)} non-jtbl by leverage " - f"(sum leverage {sum(r['leverage'] for r in batch)}):") + print(f" batch = top {len(batch)} non-jtbl by {args.rank} " + f"(sum live {sum(r['live'] for r in batch)} / sum leverage {sum(r['leverage'] for r in batch)}):") for r in batch: - print(f" {r['name']} {r['addr']} nins={r['nins']} reach={r['reach']} lever={r['leverage']}") + print(f" {r['name']} {r['addr']} nins={r['nins']} LIVE={r['live']} lever={r['leverage']}") print(f" -> {args.out_prefix}_b1_args.json / _nonjtbl_pool.json / _jtbl_pool.json") if __name__ == "__main__":