1.6 KiB
§240 — A + K + B: WRITE THE CONSTANT BETWEEN THE TWO RUNTIME TERMS (P31 S58b)
§164-16 says parentheses and operand order are inert for +/-. That is true of where the
constant ends up; it is NOT true of which runtime term the addiu attaches to.
func_8018364C (ov_SC03_105, 17 oracle calls): the target emits addiu $a1,$a1,0x3000 before
addu $a1,$a0,$a1. Every left-to-right spelling of i*0x200 + r%1024 + 0x3000 emitted addu then
addiu. Measured:
| source | emission |
|---|---|
A + B + K |
addu first, then addiu — wrong |
A + K + B |
addiu on B, then addu with A — target |
| explicit temp statement | correct order, but register-allocation drift ($a0/$a1 swap) |
| inline call in the final expression | extra move |
split_tree's rebuild attaches the constant to the term it was written next to.
THE COMPOUND-ASSIGNMENT COROLLARY. func_801824FC (ov_SC01_080, 14 oracle calls): in
mem = mem - 0x20 + D*40 + (rand()&0x3F), every explicit-statement spelling — parenthesised, term-
reordered, u32-barriered, temp-hoisted — canonicalised to mem + (D40 + rnd − 32). Only the
compound mem -= 0x20; mem += … form put -0x20 on the memory operand as lw $a0 ; addiu $a0,-0x20 ahead of the D-term chain. (Cf. §219: += is not merely a style of RMW, it is an
association dial.)
RELATED: ASSOCIATION CONTROL BY STATEMENT. func_80185EAC (ov_SC06_032): w = r + 0x200; as its
own statement makes gcc reuse $s0 incrementally (addiu $s0,$s0,0x200 riding a jal rand delay
slot); written inline it reassociated into an extra addiu $v0 and length-drifted.