diff --git a/src/decode.rs b/src/decode.rs index 7c05a47..cca6d77 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -8,6 +8,7 @@ mod base_i; mod c_extension; mod m_extension; mod priv_extension; +mod zbb_extension; mod zicboz_extension; mod zicfiss_extension; mod zicntr_extension; diff --git a/src/decode/inst_32.rs b/src/decode/inst_32.rs index c176267..4d3ce4f 100644 --- a/src/decode/inst_32.rs +++ b/src/decode/inst_32.rs @@ -1,6 +1,6 @@ use super::{ - a_extension, base_i, m_extension, priv_extension, zicboz_extension, zicfiss_extension, - zicntr_extension, zicsr_extension, zifencei_extension, + a_extension, base_i, m_extension, priv_extension, zbb_extension, zicboz_extension, + zicfiss_extension, zicntr_extension, zicsr_extension, zifencei_extension, }; use super::{Decode, DecodeUtil, DecodingError}; use crate::instruction::{InstFormat, Instruction, OpcodeKind}; @@ -42,6 +42,7 @@ impl Decode for u32 { Ok(Extensions::Zicsr) => Ok(OpcodeKind::Zicsr(zicsr_extension::bit_32::parse_opcode( self, )?)), + Ok(Extensions::Zbb) => Ok(OpcodeKind::Zbb(zbb_extension::bit_32::parse_opcode(self)?)), Ok(Extensions::Zicfiss) => Ok(OpcodeKind::Zicfiss( zicfiss_extension::bit_32::parse_opcode(self)?, )), @@ -64,6 +65,7 @@ impl Decode for u32 { OpcodeKind::BaseI(opc) => Ok(base_i::bit_32::parse_rd(self, opc)), OpcodeKind::M(opc) => Ok(m_extension::bit_32::parse_rd(self, opc)), OpcodeKind::A(opc) => Ok(a_extension::bit_32::parse_rd(self, opc)), + OpcodeKind::Zbb(opc) => Ok(zbb_extension::bit_32::parse_rd(self, opc)), OpcodeKind::Zifencei(opc) => Ok(zifencei_extension::bit_32::parse_rd(self, opc)), OpcodeKind::Zicsr(opc) => Ok(zicsr_extension::bit_32::parse_rd(self, opc)), OpcodeKind::Zicfiss(opc) => Ok(zicfiss_extension::bit_32::parse_rd(self, opc)), @@ -79,6 +81,7 @@ impl Decode for u32 { OpcodeKind::BaseI(opc) => Ok(base_i::bit_32::parse_rs1(self, opc)), OpcodeKind::M(opc) => Ok(m_extension::bit_32::parse_rs1(self, opc)), OpcodeKind::A(opc) => Ok(a_extension::bit_32::parse_rs1(self, opc)), + OpcodeKind::Zbb(opc) => Ok(zbb_extension::bit_32::parse_rs1(self, opc)), OpcodeKind::Zifencei(opc) => Ok(zifencei_extension::bit_32::parse_rs1(self, opc)), OpcodeKind::Zicsr(opc) => Ok(zicsr_extension::bit_32::parse_rs1(self, opc)), OpcodeKind::Zicfiss(opc) => Ok(zicfiss_extension::bit_32::parse_rs1(self, opc)), @@ -94,6 +97,7 @@ impl Decode for u32 { OpcodeKind::BaseI(opc) => Ok(base_i::bit_32::parse_rs2(self, opc)), OpcodeKind::M(opc) => Ok(m_extension::bit_32::parse_rs2(self, opc)), OpcodeKind::A(opc) => Ok(a_extension::bit_32::parse_rs2(self, opc)), + OpcodeKind::Zbb(opc) => Ok(zbb_extension::bit_32::parse_rs2(self, opc)), OpcodeKind::Zifencei(opc) => Ok(zifencei_extension::bit_32::parse_rs2(self, opc)), OpcodeKind::Zicsr(opc) => Ok(zicsr_extension::bit_32::parse_rs2(self, opc)), OpcodeKind::Zicfiss(opc) => Ok(zicfiss_extension::bit_32::parse_rs2(self, opc)), @@ -109,6 +113,7 @@ impl Decode for u32 { OpcodeKind::BaseI(opc) => Ok(base_i::bit_32::parse_imm(self, opc, isa)), OpcodeKind::M(opc) => Ok(m_extension::bit_32::parse_imm(self, opc)), OpcodeKind::A(opc) => Ok(a_extension::bit_32::parse_imm(self, opc)), + OpcodeKind::Zbb(opc) => Ok(zbb_extension::bit_32::parse_imm(self, opc)), OpcodeKind::Zifencei(opc) => Ok(zifencei_extension::bit_32::parse_imm(self, opc)), OpcodeKind::Zicsr(opc) => Ok(zicsr_extension::bit_32::parse_imm(self, opc)), OpcodeKind::Zicfiss(opc) => Ok(zicfiss_extension::bit_32::parse_imm(self, opc)), @@ -139,6 +144,14 @@ impl DecodeUtil for u32 { 0b010 => Ok(Extensions::Zicboz), _ => Err(DecodingError::UnknownExtension), }, + 0b001_0011 => match funct3 { + 0b001 | 0b101 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, + 0b001_1011 => match funct3 { + 0b001 | 0b101 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, 0b010_1111 => match funct5 { 0b00000 | 0b00001 | 0b00010 | 0b00011 | 0b00100 | 0b01000 | 0b01100 | 0b10000 | 0b10100 | 0b11000 | 0b11100 => Ok(Extensions::A), @@ -147,11 +160,32 @@ impl DecodeUtil for u32 { }, 0b011_0011 => match funct7 { 0b000_0001 => Ok(Extensions::M), + 0b000_0100 => match funct3 { + 0b001 | 0b100 | 0b101 | 0b110 | 0b111 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, + 0b000_0101 => match funct3 { + 0b001..=0b111 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, + 0b001_0100 | 0b011_0100 => match funct3 { + 0b001 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, + 0b010_0000 => match funct3 { + 0b100 | 0b110 | 0b111 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, + 0b011_0000 => match funct3 { + 0b001 | 0b101 => Ok(Extensions::Zbb), + _ => Ok(Extensions::BaseI), + }, _ => Ok(Extensions::BaseI), }, 0b011_1011 => match funct7 { 0b000_0000 | 0b010_0000 => Ok(Extensions::BaseI), 0b000_0001 => Ok(Extensions::M), + 0b000_0100 | 0b011_0000 => Ok(Extensions::Zbb), _ => Err(DecodingError::UnknownExtension), }, 0b111_0011 => match funct3 { diff --git a/src/decode/zbb_extension.rs b/src/decode/zbb_extension.rs new file mode 100644 index 0000000..dff2e80 --- /dev/null +++ b/src/decode/zbb_extension.rs @@ -0,0 +1,407 @@ +//! Zbb extension decoder + +pub mod bit_32 { + use super::super::{DecodeUtil, DecodingError}; + use crate::instruction::zbb_extension::ZbbOpcode; + + pub fn parse_opcode(inst: u32) -> Result { + let op_6_0: u8 = u8::try_from(inst.slice(6, 0)).unwrap(); + let op_14_12: u8 = u8::try_from(inst.slice(14, 12)).unwrap(); + let op_31_20: u16 = u16::try_from(inst.slice(31, 20)).unwrap(); + let op_24_20: u8 = u8::try_from(inst.slice(24, 20)).unwrap(); + let op_31_25: u8 = u8::try_from(inst.slice(31, 25)).unwrap(); + match op_6_0 { + 0b11_1011 => match op_14_12 { + 0b1 => Ok(ZbbOpcode::ROLW), + 0b100 => Ok(ZbbOpcode::ZEXTH), + 0b101 => Ok(ZbbOpcode::RORW), + _ => Err(DecodingError::InvalidOpcode), + }, + 0b1_1011 => match op_14_12 { + 0b101 => Ok(ZbbOpcode::RORIW), + 0b1 => match op_31_20 { + 0b110_0000_0000 => Ok(ZbbOpcode::CLZW), + 0b110_0000_0001 => Ok(ZbbOpcode::CTZW), + 0b110_0000_0010 => Ok(ZbbOpcode::CPOPW), + _ => Err(DecodingError::InvalidOpcode), + }, + _ => Err(DecodingError::InvalidOpcode), + }, + 0b1_0011 => match op_14_12 { + 0b101 => match op_31_20 { + 0b10_1000_0111 => Ok(ZbbOpcode::ORCB), + 0b110_1011_1000 => Ok(ZbbOpcode::REV8), + _ => Ok(ZbbOpcode::RORI), + }, + 0b1 => match op_31_20 { + 0b110_0000_0000 => Ok(ZbbOpcode::CLZ), + 0b110_0000_0001 => Ok(ZbbOpcode::CTZ), + 0b110_0000_0010 => Ok(ZbbOpcode::CPOP), + _ => match op_24_20 { + 0b100 => Ok(ZbbOpcode::SEXTB), + 0b101 => Ok(ZbbOpcode::SEXTH), + _ => Err(DecodingError::InvalidOpcode), + }, + }, + _ => Err(DecodingError::InvalidOpcode), + }, + 0b11_0011 => match op_14_12 { + 0b1 => Ok(ZbbOpcode::ROL), + 0b100 => match op_31_25 { + 0b0_0101 => Ok(ZbbOpcode::MIN), + 0b10_0000 => Ok(ZbbOpcode::XNOR), + _ => Err(DecodingError::InvalidOpcode), + }, + 0b101 => match op_31_25 { + 0b0_0101 => Ok(ZbbOpcode::MINU), + 0b11_0000 => Ok(ZbbOpcode::ROR), + _ => Err(DecodingError::InvalidOpcode), + }, + 0b110 => match op_31_25 { + 0b0_0101 => Ok(ZbbOpcode::MAX), + 0b10_0000 => Ok(ZbbOpcode::ORN), + _ => Err(DecodingError::InvalidOpcode), + }, + 0b111 => match op_31_25 { + 0b0_0101 => Ok(ZbbOpcode::MAXU), + 0b10_0000 => Ok(ZbbOpcode::ANDN), + _ => Err(DecodingError::InvalidOpcode), + }, + _ => Err(DecodingError::InvalidOpcode), + }, + _ => Err(DecodingError::InvalidOpcode), + } + } + + /// Parsing Zbb instruction's rd + #[allow(clippy::unnecessary_wraps)] + pub fn parse_rd(inst: u32, opkind: &ZbbOpcode) -> Option { + let rd_11_7: usize = inst.slice(11, 7) as usize; + match opkind { + ZbbOpcode::RORIW + | ZbbOpcode::RORI + | ZbbOpcode::ROLW + | ZbbOpcode::RORW + | ZbbOpcode::ANDN + | ZbbOpcode::ORN + | ZbbOpcode::XNOR + | ZbbOpcode::MAX + | ZbbOpcode::MAXU + | ZbbOpcode::MIN + | ZbbOpcode::MINU + | ZbbOpcode::ROL + | ZbbOpcode::ROR + | ZbbOpcode::SEXTB + | ZbbOpcode::SEXTH + | ZbbOpcode::ZEXTH + | ZbbOpcode::REV8 + | ZbbOpcode::ORCB + | ZbbOpcode::CPOP + | ZbbOpcode::CPOPW + | ZbbOpcode::CLZ + | ZbbOpcode::CLZW + | ZbbOpcode::CTZ + | ZbbOpcode::CTZW => Some(rd_11_7), + } + } + + /// Parsing Zbb instruction's rs1 + #[allow(clippy::unnecessary_wraps)] + pub fn parse_rs1(inst: u32, opkind: &ZbbOpcode) -> Option { + let rs1_19_15: usize = inst.slice(19, 15) as usize; + match opkind { + ZbbOpcode::RORIW + | ZbbOpcode::RORI + | ZbbOpcode::ROLW + | ZbbOpcode::RORW + | ZbbOpcode::ANDN + | ZbbOpcode::ORN + | ZbbOpcode::XNOR + | ZbbOpcode::MAX + | ZbbOpcode::MAXU + | ZbbOpcode::MIN + | ZbbOpcode::MINU + | ZbbOpcode::ROL + | ZbbOpcode::ROR + | ZbbOpcode::SEXTB + | ZbbOpcode::SEXTH + | ZbbOpcode::ZEXTH + | ZbbOpcode::REV8 + | ZbbOpcode::ORCB + | ZbbOpcode::CPOP + | ZbbOpcode::CPOPW + | ZbbOpcode::CLZ + | ZbbOpcode::CLZW + | ZbbOpcode::CTZ + | ZbbOpcode::CTZW => Some(rs1_19_15), + } + } + + /// Parsing Zbb instruction's rs2 + pub fn parse_rs2(inst: u32, opkind: &ZbbOpcode) -> Option { + let rs2_24_20: usize = inst.slice(24, 20) as usize; + match opkind { + ZbbOpcode::ROLW + | ZbbOpcode::RORW + | ZbbOpcode::ANDN + | ZbbOpcode::ORN + | ZbbOpcode::XNOR + | ZbbOpcode::MAX + | ZbbOpcode::MAXU + | ZbbOpcode::MIN + | ZbbOpcode::MINU + | ZbbOpcode::ROL + | ZbbOpcode::ROR => Some(rs2_24_20), + ZbbOpcode::RORIW + | ZbbOpcode::RORI + | ZbbOpcode::SEXTB + | ZbbOpcode::SEXTH + | ZbbOpcode::ZEXTH + | ZbbOpcode::REV8 + | ZbbOpcode::ORCB + | ZbbOpcode::CPOP + | ZbbOpcode::CPOPW + | ZbbOpcode::CLZ + | ZbbOpcode::CLZW + | ZbbOpcode::CTZ + | ZbbOpcode::CTZW => None, + } + } + + /// Parsing Zbb instruction's imm + #[allow(clippy::cast_possible_wrap)] + pub fn parse_imm(inst: u32, opkind: &ZbbOpcode) -> Option { + let imm_24_20: i32 = inst.slice(24, 20) as i32; + let imm_25_20: i32 = inst.slice(25, 20) as i32; + match opkind { + ZbbOpcode::RORIW => Some(imm_24_20), + ZbbOpcode::RORI => Some(imm_25_20), + ZbbOpcode::ROLW + | ZbbOpcode::RORW + | ZbbOpcode::ANDN + | ZbbOpcode::ORN + | ZbbOpcode::XNOR + | ZbbOpcode::MAX + | ZbbOpcode::MAXU + | ZbbOpcode::MIN + | ZbbOpcode::MINU + | ZbbOpcode::ROL + | ZbbOpcode::ROR + | ZbbOpcode::SEXTB + | ZbbOpcode::SEXTH + | ZbbOpcode::ZEXTH + | ZbbOpcode::REV8 + | ZbbOpcode::ORCB + | ZbbOpcode::CPOP + | ZbbOpcode::CPOPW + | ZbbOpcode::CLZ + | ZbbOpcode::CLZW + | ZbbOpcode::CTZ + | ZbbOpcode::CTZW => None, + } + } +} +#[cfg(test)] +#[allow(unused_variables)] +mod test_zbb { + #[test] + #[allow(overflowing_literals)] + fn zbb_32bit_decode_test() { + use crate::decode::inst_32::test_32_in_rv64; + use crate::instruction::zbb_extension::ZbbOpcode; + use crate::OpcodeKind; + + test_32_in_rv64( + 0b110_0001_1011_0000_1101_1000_1001_1011, + OpcodeKind::Zbb(ZbbOpcode::RORIW), + Some(17), + Some(1), + None, + Some(27), + ); + test_32_in_rv64( + 0b110_0001_0000_1111_1101_1111_0001_0011, + OpcodeKind::Zbb(ZbbOpcode::RORI), + Some(30), + Some(31), + None, + Some(16), + ); + test_32_in_rv64( + 0b110_0000_0001_1000_0001_1101_0011_1011, + OpcodeKind::Zbb(ZbbOpcode::ROLW), + Some(26), + Some(16), + Some(1), + None, + ); + test_32_in_rv64( + 0b110_0001_0000_0001_1101_1010_1011_1011, + OpcodeKind::Zbb(ZbbOpcode::RORW), + Some(21), + Some(3), + Some(16), + None, + ); + test_32_in_rv64( + 0b100_0000_0101_0111_0111_0101_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::ANDN), + Some(10), + Some(14), + Some(5), + None, + ); + test_32_in_rv64( + 0b100_0000_0010_0110_0110_1111_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::ORN), + Some(30), + Some(12), + Some(2), + None, + ); + test_32_in_rv64( + 0b100_0001_0110_0111_1100_1111_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::XNOR), + Some(30), + Some(15), + Some(22), + None, + ); + test_32_in_rv64( + 0b00_1011_1110_1010_0110_1011_1011_0011, + OpcodeKind::Zbb(ZbbOpcode::MAX), + Some(23), + Some(20), + Some(30), + None, + ); + test_32_in_rv64( + 0b00_1010_0011_1111_1111_0010_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::MAXU), + Some(4), + Some(31), + Some(3), + None, + ); + test_32_in_rv64( + 0b00_1010_0111_1101_1100_0111_1011_0011, + OpcodeKind::Zbb(ZbbOpcode::MIN), + Some(15), + Some(27), + Some(7), + None, + ); + test_32_in_rv64( + 0b00_1011_1011_0110_0101_0101_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::MINU), + Some(10), + Some(12), + Some(27), + None, + ); + test_32_in_rv64( + 0b110_0000_0011_0001_0001_0111_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::ROL), + Some(14), + Some(2), + Some(3), + None, + ); + test_32_in_rv64( + 0b110_0001_1000_1110_0101_0100_0011_0011, + OpcodeKind::Zbb(ZbbOpcode::ROR), + Some(8), + Some(28), + Some(24), + None, + ); + test_32_in_rv64( + 0b110_0000_0100_0011_0001_0011_1001_0011, + OpcodeKind::Zbb(ZbbOpcode::SEXTB), + Some(7), + Some(6), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0101_0111_0001_0011_0001_0011, + OpcodeKind::Zbb(ZbbOpcode::SEXTH), + Some(6), + Some(14), + None, + None, + ); + test_32_in_rv64( + 0b00_1000_0000_1000_0100_0010_1011_1011, + OpcodeKind::Zbb(ZbbOpcode::ZEXTH), + Some(5), + Some(16), + None, + None, + ); + test_32_in_rv64( + 0b110_1011_1000_1101_0101_0100_1001_0011, + OpcodeKind::Zbb(ZbbOpcode::REV8), + Some(9), + Some(26), + None, + None, + ); + test_32_in_rv64( + 0b10_1000_0111_1111_1101_1100_1001_0011, + OpcodeKind::Zbb(ZbbOpcode::ORCB), + Some(25), + Some(31), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0010_1011_1001_0001_0001_0011, + OpcodeKind::Zbb(ZbbOpcode::CPOP), + Some(2), + Some(23), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0010_0000_0001_1100_0001_1011, + OpcodeKind::Zbb(ZbbOpcode::CPOPW), + Some(24), + Some(0), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0000_0110_1001_0110_1001_0011, + OpcodeKind::Zbb(ZbbOpcode::CLZ), + Some(13), + Some(13), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0000_0100_1001_0011_0001_1011, + OpcodeKind::Zbb(ZbbOpcode::CLZW), + Some(6), + Some(9), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0001_1110_1001_0011_1001_0011, + OpcodeKind::Zbb(ZbbOpcode::CTZ), + Some(7), + Some(29), + None, + None, + ); + test_32_in_rv64( + 0b110_0000_0001_1010_1001_0111_0001_1011, + OpcodeKind::Zbb(ZbbOpcode::CTZW), + Some(14), + Some(21), + None, + None, + ); + } +} diff --git a/src/instruction.rs b/src/instruction.rs index e96591b..b8a8dbf 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -5,6 +5,7 @@ pub mod base_i; pub mod c_extension; pub mod m_extension; pub mod priv_extension; +pub mod zbb_extension; pub mod zicboz_extension; pub mod zicfiss_extension; pub mod zicntr_extension; @@ -18,6 +19,7 @@ use base_i::BaseIOpcode; use c_extension::COpcode; use m_extension::MOpcode; use priv_extension::PrivOpcode; +use zbb_extension::ZbbOpcode; use zicboz_extension::ZicbozOpcode; use zicfiss_extension::ZicfissOpcode; use zicntr_extension::ZicntrOpcode; @@ -446,6 +448,8 @@ pub enum OpcodeKind { A(AOpcode), /// Compressed Instructions C(COpcode), + /// Basic bit manipulation + Zbb(ZbbOpcode), /// Instruction-Fetch Fence, Zifencei(ZifenceiOpcode), /// Cache-Block Zero Instructions @@ -467,6 +471,7 @@ impl Display for OpcodeKind { Self::M(opc) => write!(f, "{opc}"), Self::A(opc) => write!(f, "{opc}"), Self::C(opc) => write!(f, "{opc}"), + Self::Zbb(opc) => write!(f, "{opc}"), Self::Zifencei(opc) => write!(f, "{opc}"), Self::Zicboz(opc) => write!(f, "{opc}"), Self::Zicsr(opc) => write!(f, "{opc}"), @@ -485,6 +490,7 @@ impl OpcodeKind { Self::M(opc) => opc.get_format(), Self::A(opc) => opc.get_format(), Self::C(opc) => opc.get_format(), + Self::Zbb(opc) => opc.get_format(), Self::Zifencei(opc) => opc.get_format(), Self::Zicboz(opc) => opc.get_format(), Self::Zicsr(opc) => opc.get_format(), diff --git a/src/instruction/zbb_extension.rs b/src/instruction/zbb_extension.rs new file mode 100644 index 0000000..a89f262 --- /dev/null +++ b/src/instruction/zbb_extension.rs @@ -0,0 +1,143 @@ +//! Zbb extension Instruction + +use super::{InstFormat, Opcode}; +use core::fmt::{self, Display, Formatter}; + +/// Insturctions in Zbb Extension. +#[allow(non_camel_case_types, clippy::upper_case_acronyms)] +#[derive(Debug, PartialEq)] +pub enum ZbbOpcode { + /// Rotate Right Word by Immediate + RORIW, + + /// Rotate Right (Immediate) + RORI, + + /// Rotate Left Word (Register) + ROLW, + + /// Rotate Right Word (Register) + RORW, + + /// AND with inverted operand + ANDN, + + /// OR with inverted operand + ORN, + + /// Exclusive NOR + XNOR, + + /// Maximum + MAX, + + /// Unsigned maximum + MAXU, + + /// Minimum + MIN, + + /// Unsigned minimum + MINU, + + /// Rotate Left (Register) + ROL, + + /// Rotate Right + ROR, + + /// Sign-extend byte + SEXTB, + + /// Sign-extend halfword + SEXTH, + + /// Zero-extend halfword + ZEXTH, + + /// Byte-reverse register + REV8, + + /// Bitwise OR-Combine, byte granule + ORCB, + + /// Count set bits + CPOP, + + /// Count set bits in word + CPOPW, + + /// Count leading zero bits + CLZ, + + /// Count leading zero bits in word + CLZW, + + /// Count leading zero bits + CTZ, + + /// Count leading zero bits in word + CTZW, +} + +impl Display for ZbbOpcode { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + ZbbOpcode::RORIW => write!(f, "roriw"), + ZbbOpcode::RORI => write!(f, "rori"), + ZbbOpcode::ROLW => write!(f, "rolw"), + ZbbOpcode::RORW => write!(f, "rorw"), + ZbbOpcode::ANDN => write!(f, "andn"), + ZbbOpcode::ORN => write!(f, "orn"), + ZbbOpcode::XNOR => write!(f, "xnor"), + ZbbOpcode::MAX => write!(f, "max"), + ZbbOpcode::MAXU => write!(f, "maxu"), + ZbbOpcode::MIN => write!(f, "min"), + ZbbOpcode::MINU => write!(f, "minu"), + ZbbOpcode::ROL => write!(f, "rol"), + ZbbOpcode::ROR => write!(f, "ror"), + ZbbOpcode::SEXTB => write!(f, "sextb"), + ZbbOpcode::SEXTH => write!(f, "sexth"), + ZbbOpcode::ZEXTH => write!(f, "zexth"), + ZbbOpcode::REV8 => write!(f, "rev8"), + ZbbOpcode::ORCB => write!(f, "orcb"), + ZbbOpcode::CPOP => write!(f, "cpop"), + ZbbOpcode::CPOPW => write!(f, "cpopw"), + ZbbOpcode::CLZ => write!(f, "clz"), + ZbbOpcode::CLZW => write!(f, "clzw"), + ZbbOpcode::CTZ => write!(f, "ctz"), + ZbbOpcode::CTZW => write!(f, "ctzw"), + } + } +} + +impl Opcode for ZbbOpcode { + fn get_format(&self) -> InstFormat { + match self { + ZbbOpcode::RORIW + | ZbbOpcode::RORI + | ZbbOpcode::ROLW + | ZbbOpcode::RORW + | ZbbOpcode::ANDN + | ZbbOpcode::ORN + | ZbbOpcode::XNOR + | ZbbOpcode::MAX + | ZbbOpcode::MAXU + | ZbbOpcode::MIN + | ZbbOpcode::MINU + | ZbbOpcode::ROL + | ZbbOpcode::ROR => InstFormat::RFormat, + ZbbOpcode::SEXTB + | ZbbOpcode::SEXTH + | ZbbOpcode::ZEXTH + | ZbbOpcode::REV8 + | ZbbOpcode::ORCB + | ZbbOpcode::CPOP + | ZbbOpcode::CPOPW + | ZbbOpcode::CLZ + | ZbbOpcode::CLZW + | ZbbOpcode::CTZ + | ZbbOpcode::CTZW => InstFormat::RShamtFormat, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 931c6c4..ba23697 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,8 +33,8 @@ mod instruction; pub use crate::decode::{Decode, DecodingError}; pub use crate::instruction::{ a_extension::AOpcode, base_i::BaseIOpcode, c_extension::COpcode, m_extension::MOpcode, - priv_extension::PrivOpcode, zicboz_extension::ZicbozOpcode, zicfiss_extension::ZicfissOpcode, - zicntr_extension::ZicntrOpcode, zicsr_extension::ZicsrOpcode, + priv_extension::PrivOpcode, zbb_extension::ZbbOpcode, zicboz_extension::ZicbozOpcode, + zicfiss_extension::ZicfissOpcode, zicntr_extension::ZicntrOpcode, zicsr_extension::ZicsrOpcode, zifencei_extension::ZifenceiOpcode, InstFormat, Instruction, OpcodeKind, }; @@ -58,6 +58,8 @@ enum Extensions { A, /// Compressed Instructions C, + /// Basic bit manipulation + Zbb, /// Instruction-Fetch Fence Zifencei, /// Cache-Block Zero Instructions