Assembling the pieces
Time to read a whole expression cold. When a multiply chain's input is itself a computed value, the decode has two layers: figure out what value the chain is feeding on, then run the margin math. Here's (p - q) * 10 + 3:
subu v0, a0, a1 # v0 = p - q — the value being multiplied
sll t6, v0, 2 # t6 = (p-q) * 4
addu t6, t6, v0 # t6 = (p-q) * 5 — note: adds v0, NOT a0!
sll t6, t6, 1 # t6 = (p-q) * 10
addiu v0, t6, 3 # v0 = (p-q)*10 + 3
jr ra
nop
The read that matters is on line three. In a bare × 5 the addu folds in the argument register; here it folds in v0, the subtraction's result — because the thing being quintupled is (p − q), not p. The chain's ±1 steps always reference the chain's own input, whatever register that lives in. Spot that register once, at the first sll, and carry it through.
So the general decode for compound arithmetic:
- Find the sub-expression: the instructions before the first
sll, and the register they leave their result in.
- Run margin math on the chain, reading "the input" as that register.
- Attach whatever trails the chain — here a constant, in the target below something else you've seen.
Your task
Write func_801b6710 to reproduce the target assembly.