use crate::RegisterFile;
use crate::rv32::test_utils::{execute, initialize_state};
use ab_riscv_primitives::prelude::*;
#[test]
fn test_clmul_simple() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmul {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0b1010u32);
state.regs.write(Reg::A1, 0b1100u32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0b1111000u32);
}
#[test]
fn test_clmul_zero() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmul {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0xFFFF_FFFFu32);
state.regs.write(Reg::A1, 0u32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0);
}
#[test]
fn test_clmul_identity() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmul {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0x1234_5678u32);
state.regs.write(Reg::A1, 1u32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0x1234_5678u32);
}
#[test]
fn test_clmulh_zero() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmulh {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0xFFFF_FFFFu32);
state.regs.write(Reg::A1, 0u32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0);
}
#[test]
fn test_clmulh_all_ones() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmulh {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0xFFFF_FFFFu32);
state.regs.write(Reg::A1, 0xFFFF_FFFFu32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0x5555_5555u32);
}
#[test]
fn test_clmulr_simple() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmulr {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0b1010u32);
state.regs.write(Reg::A1, 0b1100u32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0);
}
#[test]
fn test_clmulr_with_high_bits() {
let mut state = initialize_state([Rv32ZbcInstruction::Clmulr {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
}]);
state.regs.write(Reg::A0, 0x8000_0000u32);
state.regs.write(Reg::A1, 0x8000_0000u32);
execute(&mut state).unwrap();
assert_eq!(state.regs.read(Reg::A2), 0x8000_0000u32);
}
#[test]
fn test_clmul_combination() {
let mut state = initialize_state([
Rv32ZbcInstruction::Clmul {
rd: Reg::A2,
rs1: Reg::A0,
rs2: Reg::A1,
},
Rv32ZbcInstruction::Clmulh {
rd: Reg::A3,
rs1: Reg::A0,
rs2: Reg::A1,
},
]);
state.regs.write(Reg::A0, 0x1234_5678u32);
state.regs.write(Reg::A1, 0xABCD_EF01u32);
execute(&mut state).unwrap();
let low = state.regs.read(Reg::A2);
let high = state.regs.read(Reg::A3);
assert!(low != 0 || high != 0);
}