1#![cfg_attr(not(test), no_std)]
28
29mod decode;
30mod instruction;
31
32pub use crate::decode::{Decode, DecodingError};
34pub use crate::instruction::{
35 a_extension::AOpcode, base_i::BaseIOpcode, c_extension::COpcode, m_extension::MOpcode,
36 priv_extension::PrivOpcode, zicboz_extension::ZicbozOpcode, zicfiss_extension::ZicfissOpcode,
37 zicntr_extension::ZicntrOpcode, zicsr_extension::ZicsrOpcode,
38 zifencei_extension::ZifenceiOpcode, InstFormat, Instruction, OpcodeKind,
39};
40
41#[derive(Copy, Clone)]
43pub enum Isa {
44 Rv32,
46 Rv64,
48}
49
50#[derive(Debug)]
52enum Extensions {
53 BaseI,
55 M,
57 A,
59 C,
61 Zifencei,
63 Zicboz,
65 Zicsr,
67 Zicfiss,
69 Zicntr,
71 Priv,
73}
74
75impl TryFrom<usize> for Instruction {
76 type Error = DecodingError;
77 fn try_from(inst: usize) -> Result<Self, Self::Error> {
78 if inst & 0b11 == 0b11 {
79 u32::try_from(inst)
80 .expect("Truncation of usize to u32 failed.")
81 .decode(Isa::Rv64)
82 } else {
83 u16::try_from(inst)
84 .expect("Truncation of usize to u16 failed.")
85 .decode(Isa::Rv64)
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 #[test]
93 fn usize_try_from_test() {
94 use crate::instruction::{
95 base_i::BaseIOpcode, c_extension::COpcode, InstFormat, Instruction, OpcodeKind,
96 };
97
98 assert_eq!(
99 Instruction::try_from(0b1111_1111_1001_1111_1111_0000_0110_1111_usize),
100 Ok(Instruction {
101 opc: OpcodeKind::BaseI(BaseIOpcode::JAL),
102 rd: Some(0),
103 rs1: None,
104 rs2: None,
105 imm: Some(-8),
106 inst_format: InstFormat::JFormat,
107 is_compressed: false,
108 })
109 );
110
111 assert_eq!(
112 Instruction::try_from(0x880ausize),
113 Ok(Instruction {
114 opc: OpcodeKind::C(COpcode::MV),
115 rd: Some(16),
116 rs1: None,
117 rs2: Some(2),
118 imm: None,
119 inst_format: InstFormat::CrFormat,
120 is_compressed: true,
121 })
122 );
123
124 assert_ne!(
125 Instruction::try_from(0x880busize),
126 Ok(Instruction {
127 opc: OpcodeKind::C(COpcode::MV),
128 rd: Some(16),
129 rs1: None,
130 rs2: Some(2),
131 imm: None,
132 inst_format: InstFormat::CrFormat,
133 is_compressed: true,
134 })
135 );
136
137 assert_eq!(
138 Instruction::try_from(0b1111_1111_1001_1111_1111_0000_0110_1111_usize)
139 .unwrap()
140 .opc,
141 OpcodeKind::BaseI(BaseIOpcode::JAL),
142 );
143 }
144
145 #[test]
146 fn inst_eq_test() {
147 use crate::decode::Decode;
148 use crate::instruction::{base_i::BaseIOpcode, InstFormat, Instruction, OpcodeKind};
149 use crate::Isa;
150
151 assert_eq!(
152 0b1111_1111_1001_1111_1111_0000_0110_1111_u32.decode(Isa::Rv64),
153 Ok(Instruction {
154 opc: OpcodeKind::BaseI(BaseIOpcode::JAL),
155 rd: Some(0),
156 rs1: None,
157 rs2: None,
158 imm: Some(-8),
159 inst_format: InstFormat::JFormat,
160 is_compressed: false,
161 })
162 );
163
164 assert_eq!(
165 0b1111_1111_1001_1111_1111_0000_0110_1111_u32
166 .decode(Isa::Rv64)
167 .unwrap()
168 .opc,
169 OpcodeKind::BaseI(BaseIOpcode::JAL),
170 );
171 }
172}