Phase 4 batch 5: 5 PPCBUGs in the load family. lha/lhax/lhau/lhaux
sign-extended halfword results to u64 (active poisoning for negative
halfwords); lwa/lwax/lwaux sign-extended u32 results.
- PPCBUG-095/096/097/098 lha[ux]: `as i16 as i64 as u64` →
`as i16 as i32 as u32 as u64`. Sign-extend to i32 then zero-extend.
Common trigger: int16_t struct fields, PCM samples, packed vertex
deltas. Memory 0x8000 was producing 0xFFFFFFFF_FFFF8000.
- PPCBUG-105 lwa/lwax/lwaux: `as i32 as i64 as u64` → `as u64`.
Per-canary the 64-bit-mode form sign-extends, but in 32-bit ABI we
must zero-extend (canary's behavior is rescued by x86 register
zeroing in JIT; pure interpreter has no escape). Memory 0x80000000
was producing 0xFFFFFFFF_80000000.
Tests:
- lha_negative_halfword_zero_extends_upper (PPCBUG-095).
- lhaux_negative_halfword_clean_writeback (PPCBUG-098 + EA update).
- lwa_high_bit_set_zero_extends_upper (PPCBUG-105).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>