mod inst_16;
mod inst_32;
mod a_extension;
mod base_i;
mod c_extension;
mod m_extension;
mod priv_extension;
mod zicboz_extension;
mod zicfiss_extension;
mod zicntr_extension;
mod zicsr_extension;
mod zifencei_extension;
use crate::instruction::{Instruction, Opcode, OpcodeKind};
use crate::{Extensions, Isa};
fn only_rv64<T: Opcode>(opcode: T, isa: Isa) -> Result<T, DecodingError> {
match isa {
Isa::Rv32 => Err(DecodingError::OnlyRv64Inst),
Isa::Rv64 => Ok(opcode),
}
}
#[derive(Debug, PartialEq)]
pub enum DecodingError {
Not16BitInst,
Not32BitInst,
InvalidFunct3,
InvalidFunct5,
InvalidFunct6,
InvalidFunct7,
InvalidOpcode,
UnknownExtension,
IllegalInstruction,
OnlyRv64Inst,
}
pub trait Decode {
fn decode(&self, isa: Isa) -> Result<Instruction, DecodingError>;
fn parse_opcode(self, isa: Isa) -> Result<OpcodeKind, DecodingError>;
fn parse_rd(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError>;
fn parse_rs1(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError>;
fn parse_rs2(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError>;
fn parse_imm(self, opkind: &OpcodeKind, isa: Isa) -> Result<Option<i32>, DecodingError>;
}
trait DecodeUtil {
fn slice(self, end: u32, start: u32) -> Self;
fn set(self, mask: &[u32]) -> u32;
fn parse_extension(self) -> Result<Extensions, DecodingError>;
fn to_signed_nbit(&self, imm32: i32, bit_size: u32) -> i32 {
let imm32 = imm32 & (2_i32.pow(bit_size) - 1);
if imm32 >> (bit_size - 1) & 0x1 == 1 {
imm32 - 2_i32.pow(bit_size)
} else {
imm32
}
}
}