mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
recLQC2/recSQC2 still paid iFlushCall(FLUSH_CONSTANT_REGS) on the fastmem path — the legacy q0-detach shape — which frees every caller-saved GPR/NEON allocator entry mid-block. UYA's hottest COP2 staging block (0x3F7690) pays it four times in a row. Rework both to the GE-14 recLQ/recSQ shape: address before the const flush (keeps the const-Rs fold), _flushConstRegs(true) only, and the quad staged through RQSCRATCH (q30, never allocator-tracked) so no q0 detach is needed. The softmem/faulting-PC fallback keeps the legacy full-flush + q0 shape. VF memory is current at both sites without any flush: LQC2/SQC2 are VF-cache-classifier-false, so recompileNextInstruction flushed the COP2 VF compile cache before the emitter runs, and VF regs are never EE-allocator-tracked. The fault path is the proven GE-07 live-mask thunk (handles non-q0 data registers, saves live allocator entries). Measured (M2 census, UYA 6000f, vs the S4-2 capture): static EE bytes -0.16%, 146 blocks shrink / zero grow, EE_003F7690 -104B; exec-weighted ldr_gpr_unpinned 5.04% -> 4.13% (the reload churn the seam caused downstream), neon q ld/st -0.3pt combined, cop2_vf flat by design. A compile-time VF-cache event trace + policy resimulation sized the ledger's original "VF residency across macro chains" idea at ~0.07% of cycles ceiling (flagship block: zero) — the seam, not the residency policy, was the prize. Tests: three new LQC2/SQC2 residency contracts (dirty caller-saved scalars + const-folded base, macro-result-then-SQC2 ordering, dirty resident MMI quad across an LQC2/SQC2 pair). Gates: 1390 tests, 8k fuzz seeds, vucorpus bins catalog-exact, UYA stepdiff signature identical, SotC stepdiff baseline-identical (its .01 signature drifted since the S4-2 session but pre/post agree byte-for-byte at block 0x006f7168 — pre-existing class, still uncharacterized). Co-Authored-By: Claude <noreply@anthropic.com>