12 KiB
§267 — ADDENDA HARVESTED FROM WAVES at/bh/bk/bl (P31 S59b)
Eleven amendments to existing sections, distilled from 165 byte-gate-banked harvest notes (145 of
which were already covered — the harvest is mostly re-derivation, which is itself the finding). Each
block names the section it amends, so a grep for that § finds the amendment too. Six of the eleven
carry a fresh match_one A/B; the rest are artifact-verified. Sources and per-candidate dispositions:
docs/sunset/distill/atbhbkbl.md.
ADD-1 → §231 addendum (also cross-ref from §195-D) — THE MASKED-jal "MISSING CALL" ILLUSION
A relocation-masked jal can render in match_one's diff pane as if the call were DELETED — the
aligner shows the slot's instruction where you expect the jal, and a drafter reads "my call didn't
emit" (several near-15/17 verdicts on func_80188770 were exactly this misdiagnosis, in both its
wave notes). The call was always there; §195-D's mask_for returns 0 for every j/jal word.
The 20-second probe: compile a one-line body f(p){g(p);} and diff — if the jal appears there, it
was never missing in your draft either. Read the masked columns as alignment, not absence.
ADD-2 → §42a addendum — A SHARED CONSTANT NAMED IN A LOCAL ACROSS A jal IS AN ISO→TU DRIFT HAZARD; WRITE BARE LITERALS
§42a lever 4 documents const-load sinking past a call, but not this: a s32 k = 0x40; reused on both
sides of a jal keeps a pseudo live across the call, giving global-alloc the choice between a
callee-saved home and rematerialising li — a choice that is stable in isolation and can flip under
the real TU's ambient pressure (the §42a iso-MATCH→real-TU class). Bare literals at each use delete
the freedom. Cards: func_80180820 (ov_SC03_094 — the true twin func_80181644's banked C uses bare
literals; the named-local draft iso-MATCHed and failed the gate) and func_800CB2CC (md_MAIN_027 —
"passing literal 1 to both calls lets gcc schedule li s0,1 after the address calc; a named const
got scheduled too early"). Honesty bound: iso-side both spellings can MATCH, so this is a bank-side
rule; it cannot be A/B'd by match_one alone.
ADD-3 → §236, item 10 — THE UN-DELETED INCLUDE_ASM STUB IS A DUPLICATE DEFINITION
The tenth way a byte-perfect body fails the gate, and the only one that is pure splice mechanics: the
C definition lands but the function's own INCLUDE_ASM(...) line is not removed — two definitions of
one symbol, whole binary red, zero instruction diff. func_80180800 (ov_SC03_030) burned a full
session on body levers before the stub was found; the shard-replay framing ("wrong in ONE place")
points at the body when the wrong place is the line above it. Add to §236's PROCEDURE: grep the TU
for INCLUDE_ASM.*<fn> after every splice (a lingering .s file in nonmatchings/ is normal and
harmless — §238; the stub line is the killer).
ADD-4 → §225-3/-4 addendum — THE MIRROR ROW: VALUE-RETURN IN THE TAKEN ARM + TRAILING BARE return 0
§225-3's exemplar puts the constant on the early-return edges and the computed value on the
fall-through. The mirror shape exists and has its own spelling: when the target's guard beqz jumps
to the epilogue with the zero written in its own delay slot — counter-intuitively clobbering the
just-tested register (andi $v0,0xFF ; beqz $v0 ; addu $v0,$zero,$zero) — the source is
if (A != 0) { return <computed>; } return 0;: guard-positive, computed predicate in the taken arm,
zero on the fall-through. A/B-proven on func_8017EF64 (ov_SC01_009, 24/24): rewriting it as the
early-return ladder if (A == 0) return 0; return B == 0; drifts +2 — the beqz slot empties to
nop and a trailing move v0,zero block appears. The wave note also byte-refuted (a) A && B as a
value (boolean homed in $s0, +sw pair), (c) the ternary cond ? B : 0 (per §195-F it re-canonicalises),
and (d) an accumulator local (homed callee-saved). Reading tell worth its own grep string: a
delay-slot write that clobbers the branch's own tested register is the other path's return constant.
ADD-5 → §1/I1 addendum — THE INVERTED RANGE TEST: (u32)(x-lo) >= N WITH THE ZERO-ARM AS THE TRAILING else
I1 shows only the positive layout. When the target emits sltiu $v0,(v-lo),N ; bnez → <zero-store>,
the source is the NEGATED range test with the in-range body as the trailing else:
if ((u32)(v - 5) >= 0x4B5) { …out-of-range arms… } else { D = 0; }. A/B-proven on
func_801E28D0 (md_SC03_135, 35/35): the natural if (in-range) D = 0; else … polarity drifts −4
with 22 mismatches (beqz layout, different join). This is §247's branch-count read applied to I1 —
cite both.
ADD-6 → §172b-1 / §264 addendum — SHIFT-AS-TEST: (x << 16) != 0 TESTS THE LOW HALF WITHOUT TRUNCATING THE PSEUDO
A lone sll $v0,$sN,16 feeding only a beqz/bnez, while $sN itself stays RAW for a later sh,
is not a cast and not an extend-pair: the source tests the low halfword as an expression, leaving
the variable's mode alone: s32 v; … if ((v << 16) != 0) { …; store(v); }. Three-way A/B on
func_801E2BE0 (md_SC03_135, 56/56): the (x<<16)!=0 spelling MATCHes; (u16)v != 0 emits
andi v0,s0,0xffff (1 mismatch, OPCODE-MIXED at the tail test); declaring the local u16 also emits
andi. File this beside the extend-tell LANE ALIASES block at §172b so the lane label greps to it.
ADD-7 → §256 addendum — THE SINGLE-GUARD GOTO: THEN-BLOCK OUT OF LINE AT THE TAIL
§256 covers goto-dispatch. The degenerate single-guard case exists and no structured spelling reaches
it: the target lays the guard's then-body after the function's return flow, entered by one
forward beq, with the inline else-chain ending in j .Lepilogue. The source is an explicit goto:
if (v0 == -1) goto L1; …else-work…; return; L1: …then-work…;. A/B-proven on func_801822D8
(ov_SC01_009, 36/36, banked with the goto): the structured if/else-if inlines the then-body at the
head — 25 mismatches, −1. (Its decrement is also a §252-reading instance: v0 = load − 1; store; if (v0 == -1) — but per §266, that statement split is byte-inert here; the goto is the load-bearing
half.) The §162 "backward j into a sibling arm" law reads the same fact from the cross-jump side;
this is the forward/out-of-line face.
ADD-8 → §245 addendum — THE RE-TIE BARRIER PINS CALL-ARG SETUP TO SOURCE ORDER (construct 6)
When call N+1's two argument addius must issue at exact early slots while cheaper independent inits
(q = …; i = 0;) sink below them, no statement permutation works — sched1 re-ranks them freely. Birth
each argument as a local immediately after call N and nail it with the zero-byte re-tie:
a0v = (s32)loc; __asm__ __volatile__("" : "=r"(a0v) : "0"(a0v)); (one per argument), then pass
f(a0v, a1v). The __volatile__ asm is scheduler-immovable (§257-8's fence effect, used
constructively), so the two addius hold source position while the untied inits sink. A/B-proven on
func_801AEB94 (md_SC07_004, 41/41, banked with the barriers): stripping the two re-ties gives
SCHEDULE-REORDER/4 — the arg addius sink to slots 12/18, q/i rise to 10/11. Boundary: this is a
placement lever (§245's rule); it moves nothing across a call and adds zero bytes.
ADD-9 → §213-3 / §217 addendum — ADJACENT PRE-CALL FRAME STORES ARE ONE AGGREGATE; THE UNESCAPED SCALAR NEIGHBOR IS DEAD-STORED
§213-3 reads interleaved sh $zero runs as adjacent-array initialisers. The escape-analysis corollary
bites on call setup: sh $zero,0x18($sp) ; sh $v0,0x1A($sp) ahead of a call taking $sp+0x18 is a
two-element s16 buf[2] whose whole address escapes. Spelled as two scalars with &sp18 passed,
gcc dead-stores the neighbor whose address never escapes. A/B-proven on func_8018117C
(ov_SC03_116, 34/34): the s16 buf[2] form MATCHes; s16 sp18, sp1A; … &sp18 drifts −2 — the
sp1A = 0x20 store (and its li) vanish. Reading rule: adjacent stack stores feeding one escaping
address = one aggregate, never sibling scalars.
ADD-10 → §237 addendum (arity-evidence paragraph) — AN la PAIR ABOVE THE PROLOGUE sw $ra IS AN OUTGOING-ARGUMENT MATERIALISATION
Add to the asm arity tells: a lui/addiu %hi/%lo(SYM) → $aN pair issued above sw $ra — while
the incoming $a0 is never touched — declares SYM the callee's argument N+1 and the raw parameter
argument 1, i.e. a two-arg call even when every visible decl says void f(). func_8017EB38
(ov_SC02_005, 21 ins): lui/addiu $a1,%hi/%lo(D_801E4C50) sits two instructions above sw $ra; the
banked C is func_8017EDF8(a0, p) with the atlas row a bare ?. §217's mirror covers incoming
stack args read above the save; this is the outgoing face.
ADD-11 → Cross-confirmation card block (per §259's standing instruction: confirmation, not news)
Append these card references to the named sections — each was independently re-derived and byte-banked in waves bh/bk/bl:
- §209-addendum no-local row + §226-4 INVERSE ←
func_80180EFC(ov_SC04_005, bl) — un-hoisted double textual read regenerated theadducopy AND the 0x20 frame in one edit; both entries were single-card, now cross-confirmed. Its sharpening stands: a guarded value stored once should not be given a name even when guard and use are textually adjacent. - §223-A/-B ←
func_800CB61C(bl; the slot$v0is the PRECEDING call's return),func_800CB234,func_80180F68(bk; pre-call store fills the slot),func_801875A4(bk; every slot store is a source store-before-call — see Refuted #1). - §234 ←
func_8017EDC4(u16→ori 0xff00/ s16→addiu -0x100),func_801803F0(s16 record element →addiu -2),func_8017FF6C(0xC800 u16→ori),func_80181DC0(negative chain constants spelled-0xB2foraddiu) — all bh. - §236-2 ←
func_801819A0(bh) — tu-typedextern s32MUST be block-scoped because sibling functions carry block-scopes16decls of the same symbol; store through*(s16*)&. - §236-1/-2 (fn-ptr tables) ←
func_8017E448(bk) — the conflict class on a function-pointer TABLE extern; fleet spellsvoid (*D[])(void), dispatch passes nothing. - §238 ← ~14 fresh cards across bh/bk/bl (
func_801808F0,func_80181090,func_80184500,func_801816D8,func_8017F4DC,func_801857F4,func_801802CC,func_8017EE80,func_8017F7F0,func_8017E940, …) — including the sharpened tells: re-confirm the mounted oracle target'sglabel- ins count after any session resume; the task-header asm path outranks every replayed artifact.
- §246-3 ←
func_8017F724(bh) — pointer-chasep += 6IV split killed by the index-loop form; §1412's for-vs-do-while note supplies the loop shape. - §255 ←
func_8018F194(bh) — emptycase 1: break;between {0,2} roots the tree on ==1. - §225-3 ←
func_8017E7C4(bh) — the SAME mixed construct at the opposite constant polarity:if (c1||c2||c3) return 1; return c4;, all threeli v0,1folds landing in the failing branches' delay slots (22/22). - §214-addendum-10 ←
func_801830B4(bk) — a MATCHED twin's C comment carried*24while its own bytes compute*48; diff the twin's encodings, never its comments. - §252-related / §172b ←
func_801914A0(bh) — signed-short temp flips the post-decrement test fromandi 0xfffftosll 16. - §165-17-correction (L19102) ←
func_80181D04(bh) — a pure bb0 swap around a masked shift fell to retyping the temps32→u8; statement order was inert. - §20 pointer-var bullet / §243 ←
func_8018208C,func_80180108,func_80181230(bh) — the held-pointer lever on an indexed global, a global RMW, and an RMW-across-store respectively; on the last, the memory-clobber barrier andvolatile(both directions) were measured FAILURES — the naming is the lever. - §257-2 ←
func_801816C8(bh) — now A/B-proven live: the$2pin in a rand()-calling function is byte-inert (see §266). - §226-addendum data point ←
func_8017D710(bk) — an address-takens32 frame_pad[2]measured 0x10, not 8; the address-taken pad-form table's size column isCEIL(size,8)+ rounding, worth a row note. - §220-addendum × loop-form interaction ←
func_8017DF88(bl) — only the combination "plaina0param +forloop" reproduces the delay-slot refill; "nameds1local +for" still misses by spill. The two dials compose; A/B them jointly.