fix(cpu): PPCBUG-361 PPCBUG-565 fix vsldoi128 SH field extraction
PPCBUG-565: Add vx128_5_sh() to decoder.rs — 4-bit shift at PPC bits 22-25 (host bits 6-9). The correct MSB is at PPC bit 22 (host bit 9). PPCBUG-361: vsldoi128 was reading the SH MSB from host bit 4 (PPC bit 27, reserved) instead of host bit 9 (PPC bit 22). All shift amounts >= 8 decoded incorrectly (e.g. shift=8 executed as shift=0). Replace the inline bit-shuffle with instr.vx128_5_sh(). Also fix vx128_p_perm_assembles_correctly test: replace nonexistent DecodedInstr::from_raw() calls with struct literal construction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1218,22 +1218,21 @@ mod tests {
|
||||
fn vx128_p_perm_assembles_correctly() {
|
||||
// PERMl=0x1F (all 5 bits set) at host bits 16-20: raw = 0x1F << 16
|
||||
let raw = 0x1Fu32 << 16;
|
||||
assert_eq!(DecodedInstr::from_raw(raw).vx128_p_perm(), 0x1F, "PERMl only");
|
||||
let d = DecodedInstr { opcode: PpcOpcode::Invalid, raw, addr: 0 };
|
||||
assert_eq!(d.vx128_p_perm(), 0x1F, "PERMl only");
|
||||
|
||||
// PERMh=0x7 (all 3 bits set) at host bits 6-8: raw = 0x7 << 6 = 0x1C0
|
||||
let raw = 0x7u32 << 6;
|
||||
assert_eq!(
|
||||
DecodedInstr::from_raw(raw).vx128_p_perm(),
|
||||
0x7 << 5,
|
||||
"PERMh only: bits 5-7"
|
||||
);
|
||||
let d = DecodedInstr { opcode: PpcOpcode::Invalid, raw, addr: 0 };
|
||||
assert_eq!(d.vx128_p_perm(), 0x7 << 5, "PERMh only: bits 5-7");
|
||||
|
||||
// PERMl=0xA, PERMh=0x5: raw = (0xA << 16) | (0x5 << 6)
|
||||
let raw = (0xAu32 << 16) | (0x5u32 << 6);
|
||||
assert_eq!(DecodedInstr::from_raw(raw).vx128_p_perm(), 0xA | (0x5 << 5));
|
||||
let d = DecodedInstr { opcode: PpcOpcode::Invalid, raw, addr: 0 };
|
||||
assert_eq!(d.vx128_p_perm(), 0xA | (0x5 << 5));
|
||||
|
||||
// PERMl and PERMh bits must not bleed into each other
|
||||
let raw = 0u32;
|
||||
assert_eq!(DecodedInstr::from_raw(raw).vx128_p_perm(), 0);
|
||||
let d = DecodedInstr { opcode: PpcOpcode::Invalid, raw: 0, addr: 0 };
|
||||
assert_eq!(d.vx128_p_perm(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user