#[inline(always)]
pub const fn vm(inst: u32) -> bool {
(inst >> 25) & 1 != 0
}
#[inline(always)]
pub const fn nf(inst: u32) -> u8 {
((inst >> 29) & 0x7) as u8
}
#[inline(always)]
pub const fn mop(inst: u32) -> u8 {
((inst >> 26) & 0x3) as u8
}
#[inline(always)]
pub const fn mew(inst: u32) -> bool {
(inst >> 28) & 1 != 0
}
#[inline(always)]
pub const fn lumop(inst: u32) -> u8 {
((inst >> 20) & 0x1F) as u8
}
#[inline(always)]
pub const fn sumop(inst: u32) -> u8 {
((inst >> 20) & 0x1F) as u8
}
#[inline(always)]
pub const fn funct6(inst: u32) -> u32 {
(inst >> 26) & 0x3F
}
#[inline(always)]
pub const fn vs1(inst: u32) -> u8 {
((inst >> 15) & 0x1F) as u8
}
#[inline(always)]
pub const fn vs2(inst: u32) -> u8 {
((inst >> 20) & 0x1F) as u8
}
#[inline(always)]
pub const fn vd(inst: u32) -> u8 {
((inst >> 7) & 0x1F) as u8
}
#[inline(always)]
pub const fn simm5(inst: u32) -> i64 {
let raw = ((inst >> 15) & 0x1F) as i32;
((raw << 27) >> 27) as i64
}
#[inline(always)]
pub const fn uimm5(inst: u32) -> u64 {
((inst >> 15) & 0x1F) as u64
}
#[inline(always)]
pub const fn zimm_vsetvli(inst: u32) -> u64 {
((inst >> 20) & 0x7FF) as u64
}
#[inline(always)]
pub const fn zimm_vsetivli(inst: u32) -> u64 {
((inst >> 20) & 0x3FF) as u64
}
#[inline(always)]
pub const fn uimm_vsetivli(inst: u32) -> u64 {
((inst >> 15) & 0x1F) as u64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vm_bit() {
assert!(vm(1 << 25));
assert!(!vm(0));
}
#[test]
fn test_nf() {
let inst = 0b0110_0000_0000_0000_0000_0000_0000_0000_u32;
assert_eq!(nf(inst), 3);
}
#[test]
fn test_funct6() {
let inst = 0b1010_1000_0000_0000_0000_0000_0000_0000_u32;
assert_eq!(funct6(inst), 0b101010);
}
#[test]
fn test_simm5_positive() {
let inst = 0b0000_0000_0000_0011_1000_0000_0000_0000_u32;
assert_eq!(simm5(inst), 7);
}
#[test]
fn test_simm5_negative() {
let inst = 0b0000_0000_0000_1111_1000_0000_0000_0000_u32;
assert_eq!(simm5(inst), -1);
}
#[test]
fn test_simm5_min() {
let inst = 0b0000_0000_0000_1000_0000_0000_0000_0000_u32;
assert_eq!(simm5(inst), -16);
}
#[test]
fn test_vd_vs1_vs2() {
let inst = (15u32 << 20) | (10u32 << 15) | (5u32 << 7);
assert_eq!(vd(inst), 5);
assert_eq!(vs1(inst), 10);
assert_eq!(vs2(inst), 15);
}
#[test]
fn test_zimm_vsetvli() {
let inst = 0x7FF << 20;
assert_eq!(zimm_vsetvli(inst), 0x7FF);
}
#[test]
fn test_zimm_vsetivli() {
let inst = 0x3FF << 20;
assert_eq!(zimm_vsetivli(inst), 0x3FF);
}
#[test]
fn test_uimm_vsetivli() {
let inst = 0x1F << 15;
assert_eq!(uimm_vsetivli(inst), 31);
}
}