Files
BFM-decomp/.run/giants/s19_side.py
T
Drew T 3ffff74f5b feat(phase-29): BEHEMOTH #3 func_8017F510 CRACKED — 97 -> MATCH (1,511 ins), pin-free
- BANKED into ov_SC03_006 through the whole-binary byte-gate (G3/P9); R22 clean-fleet
  140 passed, 0 failed of 140. Verified independently before believing the agent's report
  (R14): match_one -> MATCH (1511 ins), then harvest_verify -> BYTE-IDENTICAL.
- DISTINCT-CODE 3,813,512 -> 3,815,023 = +1,511, EXACTLY the function's instruction count and
  the ONLY distinct-code movement of the entire session. Reach is ×1 by sig, no propagation --
  which is precisely why it moves the metric propagation cannot touch. instr 80.3%, fn 89.18%.
- EFFORT EXPERIMENT (Drew): behemoths #1-#3 were worked at High; this is the first at xHigh
  (Opus 5 agent). It closed a residual the lower tier had fully localized but could not move,
  and that 3,663 permuter candidates at base 97 had failed to improve by even 1.
- MECHANISM -> cookbook §76: the allocno CLASS (local vs global) is the dominant regalloc lever
  and C reaches it ONLY through declaration scope and variable reuse -- unreachable by statement
  order, expression shape, pins, or random search, which is exactly why the permuter was spent.
  (1) `otp` per emit ARM: 4 deaths -> four 1-death local pseudos (local-alloc.c:472); its
  second-order effect via global.c:668-671 (local placements re-marked as HARD regs for
  global-alloc) had made the target's otp=$a0 STRUCTURALLY IMPOSSIBLE, visible as hard-reg 4 in
  the `;; N conflicts:` tail of the .greg dump. (2) `cb` reused as the unlit rgbc temp: refs
  27->39 lifts its global.c:594 allocno_compare priority past `tp`, flipping the 3-colouring ->
  97 -> 10. (3) one shared `rgbw` temp -> 10 -> 2. (4) mny-before-my + one zero-byte __asm__ at
  the head of the tri cull block -> MATCH.
- THREE CORRECTIONS TO MY OWN BRIEF, all byte-evidenced: residual B was never a scheduling
  residual (it fell out free with lever 2 -- a register grant seen as a schedule diff); residual
  A is RTL EXPANSION order, proven with -fno-schedule-insns AND -fno-schedule-insns2 (source
  order survives both -- that attribution primitive is the reusable bit); residual C had no
  single c3 seed (c3 has no lever of its own, it moves only when cb out-ranks tp).
- FIXED a latent SHARED-HEADER defect, pre-existing and unrelated to the draft:
  src/shared/engine_types.h closed its include guard at line 1174 of 1259, leaving 11 typedefs /
  85 lines OUTSIDE the guard since the crack-wave lift. A TU including it twice re-declares them
  and gcc-2.7.2 rejects a repeated typedef even when identical -> `conflicting types for
  Blk16_956C`. Guard moved to EOF; byte-neutral.
- ARTIFACTS TRACKED (R20): .run/giants/s19_func_8017F510_b4.c (130-line dossier) +
  s19_f510_report.md, whose ~50-row do-not-re-buy table is arguably worth more than the match,
  + the s19_* analysis tooling.
- STRETCH, MEASURED: func_8017F5B4 (1,511 ins, ov_SC02_031) has a DIFFERENT h_exact -- not a
  dedup sibling, a family_remap TEMPLATE candidate off the b4 source.
2026-07-25 14:41:08 -06:00

34 lines
1.5 KiB
Python

#!/usr/bin/env python3
"""Side-by-side index-wise listing of a compiled object vs target .s over a range.
usage: side.py <obj.o> <lo> <hi> [fn]"""
import sys, os, re, subprocess, shutil
sys.path.insert(0, '/home/musashi/bfm-decomp/tools')
import masked_diff
OBJ = sys.argv[1]; LO = int(sys.argv[2]); HI = int(sys.argv[3])
FN = sys.argv[4] if len(sys.argv) > 4 else 'func_8017F510'
TGT = '/home/musashi/bfm-decomp/asm/ov_SC03_006/nonmatchings/ov_SC03_006_jr_8017AE2C/%s.s' % FN
OD = [c for c in ["mips-linux-gnu-objdump", "mipsel-linux-gnu-objdump"] if shutil.which(c)][0]
out = subprocess.run([OD, "-drz", OBJ], capture_output=True, text=True).stdout
# collect mnemonic text for the function only
mt = []
inside = False
for line in out.splitlines():
if re.match(r'^[0-9a-f]+ <%s>:' % FN, line): inside = True; continue
if inside:
if re.match(r'^[0-9a-f]+ <', line): break
m = re.match(r'\s*[0-9a-f]+:\s+[0-9a-f]{8}\s+(.*)', line)
if m: mt.append(re.sub(r'\s+', ' ', m.group(1).strip()))
tt = []
for line in open(TGT):
m = re.match(r'\s*/\* \w+ [0-9A-F]{8} [0-9A-F]{8} \*/\s+(.*)', line)
if m: tt.append(re.sub(r'\s+', ' ', m.group(1).strip().rstrip()))
mine = masked_diff.insns_from_object(OBJ, FN)
tgt = masked_diff.insns_from_s(TGT)
diffs = {i for i, a, b in masked_diff.structured_diff(mine, tgt)}
for k in range(LO, min(HI, max(len(mt), len(tt)))):
flag = '*' if k in diffs else ' '
print('%s %4d | %-38s | %s' % (flag, k, mt[k] if k < len(mt) else '', tt[k] if k < len(tt) else ''))