2.7 KiB
§296 — THE FRAME CHECK OUTRANKS THE ATLAS LEVER: READ PROLOGUE/EPILOGUE BEFORE DRAFTING ANY C — A REAL TELL CAN LIVE INSIDE AN UNREACHABLE FRAGMENT (P31 S61; wave m0a, 16 cards byte-proven; extends §179-C)
SIXTEEN m0a cards carried a genuine atlas lever — mostly extend-tell, and the sll/sra pairs ARE
in the targets — on symbols that are splitter FRAGMENTS: no prologue, no epilogue, exits by bare
j <sibling> with live-out $t registers, or entry state arriving in registers no C calling
convention expresses. Every C draft gains the phantom teardown (§179-C: no sibcall pass;
expand_function_end always appends), so the drafts plateau at +2..+7 instructions REGARDLESS of how
well the lever is played — the lever is real and unreachable at once.
The routing law: before spending one compile on any card's lever, read the target's FRAME.
Greppable in seconds: no trailing jr $ra; an exit j <named sibling>; endlabel abutting the next
glabel; a frame adjust riding a delay slot; a *_OBJ_NN-suffixed symbol. Any of these ⇒ the
§179-C/§265 file-scope blob lane, and the lever's knowledge banks as a COMMENT in the blob, not as C.
Fragment chains bank in link order so shared-tail fallthroughs resolve
(func_8005AC24 → SYS_OBJ_1A30 → SYS_OBJ_1A70; RotMatrixYXZ → FGO_02_OBJ_68 → _CC → _160). The
banked comment src/800b_5.c:44-46 states the class exactly: "FGO_01_OBJ_64 ... is NOT a callable
function: it is the second code FRAGMENT of one larger routine (func_8004978C -> FGO_01_OBJ_64 ->
FGO_01_OBJ_CC -> FGO_01_OBJ_160)."
The liveness-proof pattern (before believing a computation trio is dead and letting DCE eat it):
read the SIBLING fragment's opening instructions — FGO_02_OBJ_CC opens multu $t4,$t0 and stores
$t6, values only the upstream arms wrote; liveness crosses two fragment boundaries
(RotMatrixYXZ card).
THE BOUNDARY, byte-proven the same night: a fragment that legitimately returns via jr $ra is NOT
in this class. SYS_OBJ_1AF0 banked as PLAIN C with register pins (src/800c.c:1873):
s32 SYS_OBJ_1AF0(void) {
register s32 r_v0 __asm__("v0");
register s32 r_v1 __asm__("v1");
r_v0 |= 0xE5000000;
return r_v1 | r_v0;
}
— the constant-OR kept as its own statement (fusing it lets gcc commute the pair), the tail spelled
r_v1 | r_v0 for operand order. The frame check, not the fragment-looking label, decides the lane.
Cards: RotMatrixYXZ/RotMatrixY/RotMatrixX · func_8004978C · func_80049CAC · FGO_01_OBJ_64 · FGO_02_OBJ_68/_CC · FGO_03_OBJ_64 · SetDrawEnv · SYS_OBJ_1A30/1C28/2F7C · func_8005AC24 · VM_NO1_OBJ_31C (all banked as §179-C/§265 blobs) + SYS_OBJ_1AF0 (the C-side boundary).