raki 1.3.2

RISC-V instruction decoder written in Rust.
Documentation
pub mod bit_32 {
    use super::super::{DecodeUtil, DecodingError};
    use crate::instruction::zicntr_extension::ZicntrOpcode;

    pub fn parse_opcode(inst: u32) -> Result<ZicntrOpcode, DecodingError> {
        let opmap: u8 = u8::try_from(inst.slice(6, 0)).unwrap();
        let funct3: u8 = u8::try_from(inst.slice(14, 12)).unwrap();
        let csr_num: u16 = u16::try_from(inst.slice(31, 20)).unwrap();

        match opmap {
            0b111_0011 => match funct3 {
                0b010 => match csr_num {
                    0xc00 => Ok(ZicntrOpcode::RDCYCLE),
                    0xc01 => Ok(ZicntrOpcode::RDTIME),
                    0xc02 => Ok(ZicntrOpcode::RDINSTRET),
                    0xc80 => Ok(ZicntrOpcode::RDCYCLE_H),
                    0xc81 => Ok(ZicntrOpcode::RDTIME_H),
                    0xc82 => Ok(ZicntrOpcode::RDINSTRET_H),
                    _ => Err(DecodingError::InvalidOpcode),
                },
                _ => Err(DecodingError::InvalidFunct3),
            },
            _ => Err(DecodingError::InvalidOpcode),
        }
    }

    #[allow(clippy::unnecessary_wraps)]
    pub fn parse_rd(inst: u32, opkind: &ZicntrOpcode) -> Option<usize> {
        let rd: usize = inst.slice(11, 7) as usize;
        match opkind {
            ZicntrOpcode::RDCYCLE
            | ZicntrOpcode::RDTIME
            | ZicntrOpcode::RDINSTRET
            | ZicntrOpcode::RDCYCLE_H
            | ZicntrOpcode::RDTIME_H
            | ZicntrOpcode::RDINSTRET_H => Some(rd),
        }
    }

    #[allow(clippy::unnecessary_wraps)]
    pub fn parse_rs1(_inst: u32, opkind: &ZicntrOpcode) -> Option<usize> {
        match opkind {
            ZicntrOpcode::RDCYCLE
            | ZicntrOpcode::RDTIME
            | ZicntrOpcode::RDINSTRET
            | ZicntrOpcode::RDCYCLE_H
            | ZicntrOpcode::RDTIME_H
            | ZicntrOpcode::RDINSTRET_H => None,
        }
    }

    #[allow(clippy::unnecessary_wraps)]
    pub fn parse_rs2(_inst: u32, opkind: &ZicntrOpcode) -> Option<usize> {
        match opkind {
            ZicntrOpcode::RDCYCLE
            | ZicntrOpcode::RDTIME
            | ZicntrOpcode::RDINSTRET
            | ZicntrOpcode::RDCYCLE_H
            | ZicntrOpcode::RDTIME_H
            | ZicntrOpcode::RDINSTRET_H => None,
        }
    }

    #[allow(clippy::cast_possible_wrap, clippy::unnecessary_wraps)]
    pub fn parse_imm(_inst: u32, opkind: &ZicntrOpcode) -> Option<i32> {
        match opkind {
            ZicntrOpcode::RDCYCLE
            | ZicntrOpcode::RDTIME
            | ZicntrOpcode::RDINSTRET
            | ZicntrOpcode::RDCYCLE_H
            | ZicntrOpcode::RDTIME_H
            | ZicntrOpcode::RDINSTRET_H => None,
        }
    }
}

#[cfg(test)]
#[allow(unused_variables)]
mod test_zicntr {
    #[test]
    #[allow(overflowing_literals)]
    fn zicntr_decode_test() {
        use crate::decode::inst_32::test_32_in_rv64;
        use crate::instruction::zicntr_extension::ZicntrOpcode;
        use crate::OpcodeKind;

        test_32_in_rv64(
            0b1100_0000_0001_0000_0010_0111_1111_0011,
            OpcodeKind::Zicntr(ZicntrOpcode::RDTIME),
            Some(15),
            None,
            None,
            None,
        );
    }
}