refactor(cpu): vrfin uses stdlib f32::round_ties_even() per reviewer nit

P5 review feedback (non-blocking): replace the inline round-to-even
implementation with the stable stdlib intrinsic (Rust 1.77+).
Functionally equivalent; cleaner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-05-02 12:37:54 +02:00
parent 6fe2cbf251
commit 05f2f72c71

View File

@@ -2429,25 +2429,13 @@ fn execute(ctx: &mut PpcContext, mem: &dyn MemoryAccess, instr: &DecodedInstr) -
ctx.pc += 4; ctx.pc += 4;
} }
PpcOpcode::vrfin | PpcOpcode::vrfin128 => { PpcOpcode::vrfin | PpcOpcode::vrfin128 => {
// PPCBUG-432: ISA round-to-nearest-even, NOT Rust's round-half-away-from-zero. // PPCBUG-432: ISA round-to-nearest-even, NOT Rust's `round()`
// (which is round-half-away-from-zero).
let vb = if matches!(instr.opcode, PpcOpcode::vrfin128) { instr.vb128() } else { instr.rb() }; let vb = if matches!(instr.opcode, PpcOpcode::vrfin128) { instr.vb128() } else { instr.rb() };
let vd = if matches!(instr.opcode, PpcOpcode::vrfin128) { instr.vd128() } else { instr.rd() }; let vd = if matches!(instr.opcode, PpcOpcode::vrfin128) { instr.vd128() } else { instr.rd() };
let b = ctx.vr[vb].as_f32x4(); let b = ctx.vr[vb].as_f32x4();
let mut r = [0f32; 4]; let mut r = [0f32; 4];
for i in 0..4 { for i in 0..4 { r[i] = b[i].round_ties_even(); }
let x = b[i];
let t = x.trunc();
let frac = (x - t).abs();
r[i] = if frac > 0.5 {
t + if x >= 0.0 { 1.0 } else { -1.0 }
} else if frac < 0.5 {
t
} else {
// Tie — round to even.
let ti = t as i64;
if ti & 1 == 0 { t } else { t + if x >= 0.0 { 1.0 } else { -1.0 } }
};
}
ctx.vr[vd] = xenia_types::Vec128::from_f32x4_array(r); ctx.vr[vd] = xenia_types::Vec128::from_f32x4_array(r);
ctx.pc += 4; ctx.pc += 4;
} }