Files
BFM-decomp/cookbook/C0248.md
T

1.8 KiB

§227 — TYPE THE SOURCE BY THE LOAD WIDTH, NOT BY THE STORE WIDTH (P31 S58)

The access-width-by-store heuristic (§183 law 2, "type by access width") picks the wrong answer whenever a narrowing conversion sits between a wide load and a narrow store. Four cards.

card binary the target the trap
func_80184CA4 ov_SC02_005 lw from a table at +0x20, then sh into 0x6/0xA/0xE s16 = s32 narrowing emits lw + sh; s16 = u16 emits lhu + sh. Writing the source as an s16 lvalue read gave lhu and failed
func_8018A0E4 ov_SC02_005 three loads at +0x48/+0x4C/+0x50 must be s32 lw even though only 16 bits are stored — a u16 source type emits lhu
func_8018558C ov_SC03_028 lhu of D_80078E92 the atlas fleet row says s16, which would emit lh + sra and break the match. The TU had no declaration, so the access width wins — extern u16
func_80180908 ov_SC02_027 D_800AE620 struct-copied into D_801DA730 as 8 words the fleet s16 hint for a struct-copy DESTINATION must be reconciled against the .data dlabel size (32 B ⇒ a 32-byte record), not taken literally

THE LAW. Read the LOAD's opcode to type the source object and the STORE's opcode to type the destination lvalue; they are independent, and a card that gives you one type for a symbol is telling you about only one end. Mixed signedness within one statement is normal and must be spelled per-instruction — func_8018CCF8 (ov_SC02_005) has an lh/slti 0x380 guard on a field whose increment is lhu-load/s16-store; func_80180F8C (ov_SC02_017) has a counter that is lhu/sh while the guard test on it is lh; func_80188818 (ov_SC04_011) uses s16 guard compares and u16 store-backs on the same fields per §15764.