mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-09 01:59:26 -04:00
3ffff74f5b
- 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.
77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Compose variants of the b3 draft from named levers.
|
|
usage: mk.py <out.c> lever[,lever...]
|
|
levers:
|
|
otparm - declare `u32 *otp;` inside each of the 4 emit ARMS (drop fn-scope decl)
|
|
tpcase - declare `u32 *tp;` inside each of the 2 innermost-if blocks (per CASE)
|
|
tparm - declare `u32 *tp;` inside each of the 4 emit ARMS
|
|
cbmerge - reuse `cb` as the unlit rgbc temp
|
|
cbcase - declare `u32 cb;` inside each innermost-if block
|
|
uvwcase - declare `u32 uvw;` inside the quad innermost-if block
|
|
"""
|
|
import sys
|
|
|
|
BASE = '/home/musashi/bfm-decomp/.run/giants/s18_func_8017F510_b3.c'
|
|
IFANCH = 'if (my >= -0x6E && mny < 0x6F) {'
|
|
|
|
|
|
def arms(lines):
|
|
out = []
|
|
for i, l in enumerate(lines):
|
|
s = l.strip()
|
|
if s == 'if (f0) {':
|
|
out.append(i)
|
|
elif s == '} else {' and lines[i - 1].strip().startswith('pkt += 0x'):
|
|
out.append(i)
|
|
assert len(out) == 4, out
|
|
return sorted(out)
|
|
|
|
|
|
def cases(lines):
|
|
out = [i for i, l in enumerate(lines) if l.strip() == IFANCH]
|
|
assert len(out) == 2, out
|
|
return out
|
|
|
|
|
|
def insert_at(lines, idxs, decl):
|
|
for i in reversed(idxs):
|
|
ind = ' ' * (len(lines[i]) - len(lines[i].lstrip()) + 4)
|
|
lines.insert(i + 1, ind + decl)
|
|
|
|
|
|
def build(levers, base=BASE):
|
|
s = open(base).read()
|
|
if 'cbmerge' in levers:
|
|
for T in ('PolyFT3', 'PolyFT4'):
|
|
old = '((%s *)pkt)->rgbc = (tp[0] & 0xFF000000) | col;' % T
|
|
new = ('cb = (tp[0] & 0xFF000000) | col;\n'
|
|
+ ' ' * 0 + '@IND@((%s *)pkt)->rgbc = cb;' % T)
|
|
assert old in s, T
|
|
i = s.index(old)
|
|
ind = ' ' * (i - s.rindex('\n', 0, i) - 1)
|
|
s = s.replace(old, new.replace('@IND@', ind), 1)
|
|
lines = s.split('\n')
|
|
if 'otparm' in levers:
|
|
lines = [l for l in lines if l.strip() != 'u32 *otp;']
|
|
insert_at(lines, arms(lines), 'u32 *otp;')
|
|
if 'tparm' in levers:
|
|
lines = [l for l in lines if l.strip() != 'u32 *tp;']
|
|
insert_at(lines, arms(lines), 'u32 *tp;')
|
|
if 'tpcase' in levers:
|
|
lines = [l for l in lines if l.strip() != 'u32 *tp;']
|
|
insert_at(lines, cases(lines), 'u32 *tp;')
|
|
if 'cbcase' in levers:
|
|
lines = [l for l in lines if l.strip() != 'u32 cb;']
|
|
insert_at(lines, cases(lines), 'u32 cb;')
|
|
if 'uvwcase' in levers:
|
|
lines = [l for l in lines if l.strip() != 'u32 uvw;']
|
|
insert_at(lines, [cases(lines)[1]], 'u32 uvw;')
|
|
return '\n'.join(lines)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
out = sys.argv[1]
|
|
lv = [] if sys.argv[2] == 'none' else sys.argv[2].split(',')
|
|
open(out, 'w').write(build(lv))
|
|
print('wrote', out, lv)
|