extern crate alloc;
use crate::instructions::Instruction;
use crate::instructions::test_utils::{make_i_type, make_r_type};
use crate::instructions::v::zve64x::config::Zve64xConfigInstruction;
use crate::registers::general_purpose::Reg;
use alloc::format;
#[test]
fn test_vsetvli_basic() {
let inst = make_i_type(0b1010111, 1, 0b111, 2, 0x0b);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::Ra,
rs1: Reg::Sp,
vtypei: 0x0b,
})
);
}
#[test]
fn test_vsetvli_e8_m1() {
let inst = make_i_type(0b1010111, 10, 0b111, 11, 0x000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::A0,
rs1: Reg::A1,
vtypei: 0x000,
})
);
}
#[test]
fn test_vsetvli_e64_mf8_ta_ma() {
let vtypei = 0xdd;
let inst = make_i_type(0b1010111, 5, 0b111, 6, vtypei);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::T0,
rs1: Reg::T1,
vtypei: 0xdd,
})
);
}
#[test]
fn test_vsetvli_max_vtypei() {
let inst = make_i_type(0b1010111, 1, 0b111, 2, 0x7ff);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::Ra,
rs1: Reg::Sp,
vtypei: 0x7ff,
})
);
}
#[test]
fn test_vsetvli_rd_zero() {
let inst = make_i_type(0b1010111, 0, 0b111, 5, 0x03);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::Zero,
rs1: Reg::T0,
vtypei: 0x03,
})
);
}
#[test]
fn test_vsetvli_rs1_zero_rd_nonzero() {
let inst = make_i_type(0b1010111, 1, 0b111, 0, 0x03);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::Ra,
rs1: Reg::Zero,
vtypei: 0x03,
})
);
}
#[test]
fn test_vsetvli_rs1_zero_rd_zero() {
let inst = make_i_type(0b1010111, 0, 0b111, 0, 0x03);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli {
rd: Reg::Zero,
rs1: Reg::Zero,
vtypei: 0x03,
})
);
}
#[test]
fn test_vsetivli_basic() {
let inst = make_i_type(0b1010111, 1, 0b111, 4, 0xc0b);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetivli {
rd: Reg::Ra,
uimm: 4,
vtypei: 0x0b,
})
);
}
#[test]
fn test_vsetivli_uimm_zero() {
let inst = make_i_type(0b1010111, 10, 0b111, 0, 0xc00);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetivli {
rd: Reg::A0,
uimm: 0,
vtypei: 0x000,
})
);
}
#[test]
fn test_vsetivli_uimm_max() {
let inst = make_i_type(0b1010111, 1, 0b111, 31, 0xfff);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetivli {
rd: Reg::Ra,
uimm: 31,
vtypei: 0x3ff,
})
);
}
#[test]
fn test_vsetivli_e64_m1_ta_ma() {
let inst = make_i_type(0b1010111, 5, 0b111, 16, 0xcd8);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetivli {
rd: Reg::T0,
uimm: 16,
vtypei: 0x0d8,
})
);
}
#[test]
fn test_vsetvl_basic() {
let inst = make_r_type(0b1010111, 1, 0b111, 2, 3, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvl {
rd: Reg::Ra,
rs1: Reg::Sp,
rs2: Reg::Gp
})
);
}
#[test]
fn test_vsetvl_all_arg_regs() {
let inst = make_r_type(0b1010111, 10, 0b111, 11, 12, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvl {
rd: Reg::A0,
rs1: Reg::A1,
rs2: Reg::A2
})
);
}
#[test]
fn test_vsetvl_rd_zero() {
let inst = make_r_type(0b1010111, 0, 0b111, 5, 6, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvl {
rd: Reg::Zero,
rs1: Reg::T0,
rs2: Reg::T1
})
);
}
#[test]
fn test_vsetvl_rs1_zero_rd_nonzero() {
let inst = make_r_type(0b1010111, 1, 0b111, 0, 7, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(
decoded,
Some(Zve64xConfigInstruction::Vsetvl {
rd: Reg::Ra,
rs1: Reg::Zero,
rs2: Reg::T2
})
);
}
#[test]
fn test_wrong_opcode() {
let inst = make_r_type(0b0110011, 1, 0b111, 2, 3, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(decoded, None);
}
#[test]
fn test_wrong_funct3() {
let inst = make_r_type(0b1010111, 1, 0b000, 2, 3, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(decoded, None);
}
#[test]
fn test_vsetvl_wrong_funct7() {
let inst = make_r_type(0b1010111, 1, 0b111, 2, 3, 0b1000001);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(decoded, None);
}
#[test]
fn test_vsetvl_nonzero_bits_29_25() {
let inst = make_r_type(0b1010111, 1, 0b111, 2, 3, 0b1000010);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert_eq!(decoded, None);
}
#[test]
fn test_vsetvli_bit31_clear() {
let inst = make_i_type(0b1010111, 1, 0b111, 2, 0x7ff);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert!(matches!(
decoded,
Some(Zve64xConfigInstruction::Vsetvli { .. })
));
}
#[test]
fn test_vsetivli_bits_31_30_set() {
let inst = make_i_type(0b1010111, 1, 0b111, 2, 0xc00);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst);
assert!(matches!(
decoded,
Some(Zve64xConfigInstruction::Vsetivli { .. })
));
}
#[test]
fn test_display_vsetvli() {
let inst = make_i_type(0b1010111, 1, 0b111, 2, 0x0b);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst).unwrap();
assert_eq!(format!("{}", decoded), "vsetvli ra, sp, 11");
}
#[test]
fn test_display_vsetivli() {
let inst = make_i_type(0b1010111, 1, 0b111, 4, 0xc0b);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst).unwrap();
assert_eq!(format!("{}", decoded), "vsetivli ra, 4, 11");
}
#[test]
fn test_display_vsetvl() {
let inst = make_r_type(0b1010111, 1, 0b111, 2, 3, 0b1000000);
let decoded = Zve64xConfigInstruction::<Reg<u64>>::try_decode(inst).unwrap();
assert_eq!(format!("{}", decoded), "vsetvl ra, sp, gp");
}