use crate::exec::compute::fpu;
use crate::isa::op::AluOp;
fn execute(op: AluOp, a: u64, b: u64, c: u64, is32: bool) -> u64 {
fpu::execute_full(op, a, b, c, is32).0
}
#[test]
fn test_box_f32() {
let f: f32 = 1.234;
let boxed = box_f32(f);
assert_eq!(boxed >> 32, 0xFFFFFFFF, "Upper 32 bits must be all 1s");
assert_eq!(boxed as u32, f.to_bits(), "Lower 32 bits must match f32 representation");
}
#[test]
fn test_nan_boxing_unboxing() {
let f_val: f32 = 42.0;
let valid_boxed = box_f32(f_val);
let zero = box_f32(0.0);
let res = execute(AluOp::FAdd, valid_boxed, zero, 0, true);
assert_eq!(res >> 32, 0xFFFFFFFF);
assert_eq!(f32::from_bits(res as u32), 42.0);
let invalid_boxed = f_val.to_bits() as u64; let res_invalid = execute(AluOp::FAdd, invalid_boxed, zero, 0, true);
let canon_nan_32 = 0x7fc00000u32;
assert_eq!(
res_invalid,
box_f32(f32::from_bits(canon_nan_32)),
"Invalidly boxed input must result in canonical NaN"
);
}
#[test]
fn test_fmin_fmax_nan_handling() {
let f_val = box_f32(10.0);
let f_nan = box_f32(f32::NAN);
let res_min = execute(AluOp::FMin, f_val, f_nan, 0, true);
assert_eq!(res_min, f_val, "fmin(val, NaN) should be val");
let res_min2 = execute(AluOp::FMin, f_nan, f_val, 0, true);
assert_eq!(res_min2, f_val, "fmin(NaN, val) should be val");
let res_max = execute(AluOp::FMax, f_val, f_nan, 0, true);
assert_eq!(res_max, f_val, "fmax(val, NaN) should be val");
let res_max2 = execute(AluOp::FMax, f_nan, f_val, 0, true);
assert_eq!(res_max2, f_val, "fmax(NaN, val) should be val");
let res_both_nan = execute(AluOp::FMin, f_nan, f_nan, 0, true);
let canon_nan_32 = 0x7fc00000u32;
assert_eq!(res_both_nan, box_f32(f32::from_bits(canon_nan_32)));
}
#[test]
fn test_canonical_nan_propagation() {
let snan_bits = 0x7f800001u32;
let snan = box_f32(f32::from_bits(snan_bits));
let zero = box_f32(0.0);
let res = execute(AluOp::FAdd, snan, zero, 0, true);
let canon_nan_32 = 0x7fc00000u32;
assert_eq!(res, box_f32(f32::from_bits(canon_nan_32)), "sNaN must be quieted to canonical NaN");
}
#[test]
fn test_f64_nan_boxing_not_applicable() {
let d_val1 = f64::to_bits(1.0);
let d_val2 = f64::to_bits(2.0);
let res = execute(AluOp::FAdd, d_val1, d_val2, 0, false);
assert_eq!(f64::from_bits(res), 3.0);
}
use crate::exec::compute::fpu::nan_handling::*;
#[test]
fn test_unbox_f32_direct() {
let valid = box_f32(1.0);
assert_eq!(unbox_f32(valid).to_bits(), 1.0f32.to_bits());
let invalid = 1.0f32.to_bits() as u64; assert_eq!(unbox_f32(invalid).to_bits(), 0x7fc0_0000);
}
#[test]
fn test_fmin_fmax_f32_direct() {
let pos_zero = f32::from_bits(0x0000_0000);
let neg_zero = f32::from_bits(0x8000_0000);
assert_eq!(fmin_f32(neg_zero, pos_zero).to_bits(), neg_zero.to_bits());
assert_eq!(fmin_f32(pos_zero, neg_zero).to_bits(), neg_zero.to_bits());
assert_eq!(fmax_f32(neg_zero, pos_zero).to_bits(), pos_zero.to_bits());
assert_eq!(fmax_f32(pos_zero, neg_zero).to_bits(), pos_zero.to_bits());
let nan = f32::from_bits(0x7fc0_0000);
assert_eq!(fmin_f32(nan, nan).to_bits(), 0x7fc0_0000);
assert_eq!(fmax_f32(nan, nan).to_bits(), 0x7fc0_0000);
assert_eq!(fmin_f32(nan, 1.0).to_bits(), 1.0f32.to_bits());
assert_eq!(fmin_f32(1.0, nan).to_bits(), 1.0f32.to_bits());
assert_eq!(fmax_f32(nan, 1.0).to_bits(), 1.0f32.to_bits());
assert_eq!(fmax_f32(1.0, nan).to_bits(), 1.0f32.to_bits());
assert_eq!(fmin_f32(1.0, 2.0).to_bits(), 1.0f32.to_bits());
assert_eq!(fmax_f32(1.0, 2.0).to_bits(), 2.0f32.to_bits());
}
#[test]
fn test_fmin_fmax_f64_direct() {
let pos_zero = f64::from_bits(0x0000_0000_0000_0000);
let neg_zero = f64::from_bits(0x8000_0000_0000_0000);
assert_eq!(fmin_f64(neg_zero, pos_zero).to_bits(), neg_zero.to_bits());
assert_eq!(fmin_f64(pos_zero, neg_zero).to_bits(), neg_zero.to_bits());
assert_eq!(fmax_f64(neg_zero, pos_zero).to_bits(), pos_zero.to_bits());
assert_eq!(fmax_f64(pos_zero, neg_zero).to_bits(), pos_zero.to_bits());
let nan = f64::from_bits(0x7ff8_0000_0000_0000);
assert_eq!(fmin_f64(nan, nan).to_bits(), 0x7ff8_0000_0000_0000);
assert_eq!(fmax_f64(nan, nan).to_bits(), 0x7ff8_0000_0000_0000);
assert_eq!(fmin_f64(nan, 1.0).to_bits(), 1.0f64.to_bits());
assert_eq!(fmin_f64(1.0, nan).to_bits(), 1.0f64.to_bits());
assert_eq!(fmax_f64(nan, 1.0).to_bits(), 1.0f64.to_bits());
assert_eq!(fmax_f64(1.0, nan).to_bits(), 1.0f64.to_bits());
assert_eq!(fmin_f64(1.0, 2.0).to_bits(), 1.0f64.to_bits());
assert_eq!(fmax_f64(1.0, 2.0).to_bits(), 2.0f64.to_bits());
}