Merge audit-2026-05-fix/swapbug-001-revert-addi-truncation: SWAPBUG-001 revert
This commit is contained in:
@@ -112,10 +112,8 @@ fn execute(ctx: &mut PpcContext, mem: &dyn MemoryAccess, instr: &DecodedInstr) -
|
||||
match instr.opcode {
|
||||
// ===== ALU: Immediate =====
|
||||
PpcOpcode::addi => {
|
||||
// PPCBUG-001: 32-bit ABI. `li rT, -1` (= addi rT, r0, -1) must produce
|
||||
// 0x00000000_FFFFFFFF, not 0xFFFFFFFF_FFFFFFFF (sign-extended simm16).
|
||||
let ra_val = if instr.ra() == 0 { 0 } else { ctx.gpr[instr.ra()] };
|
||||
ctx.gpr[instr.rd()] = ra_val.wrapping_add(instr.simm16() as i64 as u64) as u32 as u64;
|
||||
ctx.gpr[instr.rd()] = ra_val.wrapping_add(instr.simm16() as i64 as u64);
|
||||
ctx.pc += 4;
|
||||
}
|
||||
PpcOpcode::addis => {
|
||||
@@ -5570,9 +5568,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn addi_li_neg_one_zero_extends_upper() {
|
||||
// PPCBUG-001: `li r3, -1` (= addi r3, r0, -1) must produce
|
||||
// 0x00000000_FFFFFFFF, not 0xFFFFFFFF_FFFFFFFF.
|
||||
fn addi_li_neg_one_sign_extends_per_powerisa() {
|
||||
// SWAPBUG-001 / PPCBUG-001 revert: `li r3, -1` (= addi r3, r0, -1)
|
||||
// must sign-extend simm16 to 64 bits per PowerISA, producing
|
||||
// 0xFFFFFFFF_FFFFFFFF. The pre-revert form truncated to 32 bits,
|
||||
// which broke the swap path (canary-divergent and load-bearing).
|
||||
let mut ctx = PpcContext::new();
|
||||
let mut mem = TestMem::new();
|
||||
// addi r3, r0, -1: opcode 14, simm16 = 0xFFFF
|
||||
@@ -5580,7 +5580,7 @@ mod tests {
|
||||
write_instr(&mut mem, 0, raw);
|
||||
ctx.pc = 0;
|
||||
step(&mut ctx, &mut mem);
|
||||
assert_eq!(ctx.gpr[3], 0x0000_0000_FFFF_FFFFu64);
|
||||
assert_eq!(ctx.gpr[3], 0xFFFF_FFFF_FFFF_FFFFu64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user