#![cfg_attr(not(test), no_std)]
mod decode;
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,
zifencei_extension::ZifenceiOpcode, InstFormat, Instruction, OpcodeKind,
};
#[derive(Copy, Clone)]
pub enum Isa {
Rv32,
Rv64,
}
#[derive(Debug)]
enum Extensions {
BaseI,
M,
A,
C,
Zifencei,
Zicboz,
Zicsr,
Zicfiss,
Zicntr,
Priv,
}
impl TryFrom<usize> for Instruction {
type Error = DecodingError;
fn try_from(inst: usize) -> Result<Self, Self::Error> {
if inst & 0b11 == 0b11 {
u32::try_from(inst)
.expect("Truncation of usize to u32 failed.")
.decode(Isa::Rv64)
} else {
u16::try_from(inst)
.expect("Truncation of usize to u16 failed.")
.decode(Isa::Rv64)
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn usize_try_from_test() {
use crate::instruction::{
base_i::BaseIOpcode, c_extension::COpcode, InstFormat, Instruction, OpcodeKind,
};
assert_eq!(
Instruction::try_from(0b1111_1111_1001_1111_1111_0000_0110_1111_usize),
Ok(Instruction {
opc: OpcodeKind::BaseI(BaseIOpcode::JAL),
rd: Some(0),
rs1: None,
rs2: None,
imm: Some(-8),
inst_format: InstFormat::JFormat,
is_compressed: false,
})
);
assert_eq!(
Instruction::try_from(0x880ausize),
Ok(Instruction {
opc: OpcodeKind::C(COpcode::MV),
rd: Some(16),
rs1: None,
rs2: Some(2),
imm: None,
inst_format: InstFormat::CrFormat,
is_compressed: true,
})
);
assert_ne!(
Instruction::try_from(0x880busize),
Ok(Instruction {
opc: OpcodeKind::C(COpcode::MV),
rd: Some(16),
rs1: None,
rs2: Some(2),
imm: None,
inst_format: InstFormat::CrFormat,
is_compressed: true,
})
);
assert_eq!(
Instruction::try_from(0b1111_1111_1001_1111_1111_0000_0110_1111_usize)
.unwrap()
.opc,
OpcodeKind::BaseI(BaseIOpcode::JAL),
);
}
#[test]
fn inst_eq_test() {
use crate::decode::Decode;
use crate::instruction::{base_i::BaseIOpcode, InstFormat, Instruction, OpcodeKind};
use crate::Isa;
assert_eq!(
0b1111_1111_1001_1111_1111_0000_0110_1111_u32.decode(Isa::Rv64),
Ok(Instruction {
opc: OpcodeKind::BaseI(BaseIOpcode::JAL),
rd: Some(0),
rs1: None,
rs2: None,
imm: Some(-8),
inst_format: InstFormat::JFormat,
is_compressed: false,
})
);
assert_eq!(
0b1111_1111_1001_1111_1111_0000_0110_1111_u32
.decode(Isa::Rv64)
.unwrap()
.opc,
OpcodeKind::BaseI(BaseIOpcode::JAL),
);
}
}