2.2 KiB
§210 — THE SINGLE-BIT MASK IN A BOOLEAN TAIL: andi K ; sltu $zero,v vs srl n ; andi 1 is a STATEMENT-SHAPE dial, not an operator choice (P31 S58)
THE TARGET SHAPE — byte-identical tails, two different overlays, found independently by two different drafting agents:
jal func_80133784
sh $v0, 0x1A($sp)
andi $v0, $v0, 0x2000
lw $ra, 0x20($sp)
sltu $v0, $zero, $v0 <- the generic normalisation
jr $ra
(✔ byte-checked: asm/ov_SC03_029/.../func_8018723C.s and
asm/ov_SC03_006/.../func_80188C18.s — the two tails are word-for-word identical.)
THE TRAP. In a straight-line value tail with no join and no branches, the fused expression
return (func_80133784(1, pa, pb) & 0x2000) != 0; /* WRONG BYTES */
lets gcc see the single-bit mask inside the comparison and emit the bit-extract form
srl $v0,$v0,13 ; andi $v0,$v0,1. Refuted on the same card: the ternary ? 1 : 0 and the u32-cast
spelling do not fix it.
TWO FIXES, BOTH BYTE-PROVEN, ON THE SAME SHAPE:
| card | fix | result |
|---|---|---|
func_8018723C (ov_SC03_029, wave ag) |
name the masked value: r = call() & 0x2000; return r != 0; — the statement boundary hides the mask from the != 0 expander |
MATCH 30/30 |
func_80188C18 (ov_SC03_006, wave ae) |
spell the test as CONTROL FLOW: if (x & 0x2000) return 1; return 0; |
MATCH |
Same predicate, three statement shapes, two different final instruction sequences.
THE LAW. Mask visibility to the truth-expression expander is controlled by statement
boundaries alone, with no control flow required. When the target shows andi K ; sltu $zero,v and
your draft shows srl n ; andi 1, split the mask out of the comparison — either into a named local
or into an if.
BOUNDARY. This is a SINGLE-BIT-mask law. A multi-bit mask has no bit to extract and already
normalises to andi+sltu from the fused spelling, so the split is inert there. It is also distinct
from §164-56/§165-22 (fold_truthop paths over two comparisons) and from §19x/§167-09 (a 0/1
materialised at a JOIN label, which is about naming a condition, not a mask) — those cannot fire
on one mask of one call result. §195-E's value-vs-no-value axis gains this as a third dial.