mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-04 08:21:50 -04:00
1.7 KiB
1.7 KiB
§241 — THE FOLDED SIGN-EXTEND-AND-SCALE: sll 16 ; sra (16 − log2 scale) (P31 S58b)
A sll $x,16 followed by sra $x,N with N < 16 is not a division and not a plain
extension: it is a sign-extension of a halfword fused with a left shift of 16 − N.
| pair | meaning | scale |
|---|---|---|
sll 16 ; sra 16 |
plain (s16)x |
×1 |
sll 16 ; sra 14 |
((s16)x) * 4 |
×4 — indexes a 4-byte table |
sll 17 ; sra 14 |
(s16)(x*2) * 4 |
doubled index, 8-byte elements |
sll 16 ; sra 17 |
((s16)x) >> 1 |
signed halve (N > 16) |
BYTE-VERIFIED. asm/ov_SC07_007/.../func_80180EC8.s lines 11–16: sll $v0,$v0,16 ; sra $v0,$v0,14 feeding an lw off a %lo base — i.e. a 4-byte-element table indexed by a
sign-extended halfword. The first draft used explicit *4 scaling and produced sra 12.
THE C SPELLINGS.
- ×4 fold: write the index unscaled and sign-extended —
((v << 16) >> 16)— and let gcc fold the scale into thesraamount (func_80180EC8). - doubled index into 8-byte rows:
(s16)(m * 2)used as the subscript givessll 17 ; sra 14exactly, with the second element asbase+4off the sharedlui/addiu(func_801AE734, md_SC07_004). - signed halve:
((s16)u16_global) >> 1giveslhu ; sll 16 ; sra 17(func_8017F30C, ov_SC06_022;func_801800D0, ov_SC03_029;func_801AC3C8's accumulator, where the temp must bes16nots32or you get a baresra 17with no leadingsll).
THE DISCRIMINATOR vs §167-03's HImode-division reading: ask what consumes the result. If it feeds
an lw/lhu address, it is a scaled index (this section). If it feeds an addu/subu sum or a
compare, it is a divide (§167-03/§167-25).