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.