1#![no_std]
2
3mod compressed;
4mod instruction;
5pub mod types;
6
7use types::*;
8
9pub use instruction::Instruction;
10
11#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
12pub enum DecodingError {
13 Custom,
15 Reserved,
17 Unknown,
19 Truncated,
21 Unimplemented,
24}
25
26type DecodingResult = Result<Instruction, DecodingError>;
27
28pub fn instruction_length(i: u16) -> usize {
34 if i & 0b11 != 0b11 {
35 2
36 } else if i & 0b11100 != 0b11100 {
37 4
38 } else if i & 0b111111 == 0b011111 {
39 6
40 } else if i & 0b1111111 == 0b011111 {
41 8
42 } else {
43 10 + 2 * ((i >> 12) & 0b111) as usize
44 }
45}
46
47pub fn decode(i: u32) -> DecodingResult {
49 match i & 0b11 {
50 0b00 => compressed::decode_q00(i),
51 0b01 => compressed::decode_q01(i),
52 0b10 => compressed::decode_q10(i),
53 0b11 => match (i >> 2) & 0b11111 {
54 0b00000 => decode_load(i),
55 0b00001 => match (i >> 12) & 0b111 {
56 0b010 => Ok(Instruction::Flw(IType(i))),
57 _ => Err(DecodingError::Unknown),
58 },
59 0b00010 => Err(DecodingError::Custom),
60 0b00011 => decode_misc_mem(i),
61 0b00100 => decode_op_imm(i),
62 0b00101 => Ok(Instruction::Auipc(UType(i))),
63 0b00110 => decode_op_imm32(i),
64 0b00111 => Err(DecodingError::Reserved), 0b01000 => decode_store(i),
67 0b01001 => match (i >> 12) & 0b111 {
68 0b010 => Ok(Instruction::Fsw(SType(i))),
69 _ => Err(DecodingError::Unknown),
70 },
71 0b01010 => Err(DecodingError::Custom),
72 0b01011 => decode_amo(i),
73 0b01100 => decode_op(i),
74 0b01101 => Ok(Instruction::Lui(UType(i))),
75 0b01110 => decode_op32(i),
76 0b01111 => Err(DecodingError::Reserved), 0b10000 => match (i >> 25) & 0b11 {
79 0b00 => Ok(Instruction::Fmadds(R4Type(i))),
80 _ => Err(DecodingError::Unknown),
81 },
82 0b10001 => match (i >> 25) & 0b11 {
83 0b00 => Ok(Instruction::Fmsubs(R4Type(i))),
84 _ => Err(DecodingError::Unknown),
85 },
86 0b10010 => match (i >> 25) & 0b11 {
87 0b00 => Ok(Instruction::Fnmsubs(R4Type(i))),
88 _ => Err(DecodingError::Unknown),
89 },
90 0b10011 => match (i >> 25) & 0b11 {
91 0b00 => Ok(Instruction::Fnmadds(R4Type(i))),
92 _ => Err(DecodingError::Unknown),
93 },
94 0b10100 => decode_opfp(i), 0b10101 => Err(DecodingError::Reserved),
96 0b10110 => Err(DecodingError::Custom),
97 0b10111 => Err(DecodingError::Reserved), 0b11000 => decode_branch(i),
100 0b11001 => Ok(Instruction::Jalr(IType(i))),
101 0b11010 => Err(DecodingError::Reserved),
102 0b11011 => Ok(Instruction::Jal(JType(i))),
103 0b11100 => decode_system(i),
104 0b11101 => Err(DecodingError::Reserved),
105 0b11110 => Err(DecodingError::Custom),
106 0b11111 => Err(DecodingError::Reserved), _ => unreachable!(),
108 },
109 _ => unreachable!(),
110 }
111}
112
113fn decode_opfp(i: u32) -> Result<Instruction, DecodingError> {
114 match (i >> 25) & 0b1111111 {
115 0b0000000 => Ok(Instruction::Fadds(RType(i))),
116 0b0000100 => Ok(Instruction::Fsubs(RType(i))),
117 0b0001000 => Ok(Instruction::Fmuls(RType(i))),
118 0b0001100 => Ok(Instruction::Fdivs(RType(i))),
119 0b0101100 if i >> 20 & 0b11111 == 0 => Ok(Instruction::Fsqrts(RType(i))),
120 0b0010000 => match i >> 12 & 0b111 {
121 0b000 => Ok(Instruction::Fsgnjs(RType(i))),
122 0b001 => Ok(Instruction::Fsgnjns(RType(i))),
123 0b010 => Ok(Instruction::Fsgnjxs(RType(i))),
124 _ => Err(DecodingError::Unknown),
125 },
126 0b0010100 => match i >> 12 & 0b111 {
127 0b000 => Ok(Instruction::Fmins(RType(i))),
128 0b001 => Ok(Instruction::Fmaxs(RType(i))),
129 _ => Err(DecodingError::Unknown),
130 },
131 0b1100000 => match i >> 20 & 0b11111 {
132 0b00000 => Ok(Instruction::Fcvtws(RType(i))),
133 0b00001 => Ok(Instruction::Fcvtwus(RType(i))),
134 _ => Err(DecodingError::Unknown),
135 },
136 0b1110000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0 => {
137 Ok(Instruction::Fmvxw(RType(i)))
138 }
139 0b1010000 => match i >> 12 & 0b111 {
140 0b010 => Ok(Instruction::Feqs(RType(i))),
141 0b001 => Ok(Instruction::Flts(RType(i))),
142 0b000 => Ok(Instruction::Fles(RType(i))),
143 _ => Err(DecodingError::Unknown),
144 },
145 0b1110000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0b001 => {
146 Ok(Instruction::Fclasss(RType(i)))
147 }
148 0b1101000 if i >> 20 & 0b11111 == 0 => Ok(Instruction::Fcvtsw(RType(i))),
149 0b1101000 if i >> 20 & 0b11111 == 1 => Ok(Instruction::Fcvtswu(RType(i))),
150 0b1111000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0 => {
151 Ok(Instruction::Fmvwx(RType(i)))
152 }
153 _ => Err(DecodingError::Unknown),
154 }
155}
156
157fn decode_load(i: u32) -> DecodingResult {
158 match (i >> 12) & 0b111 {
159 0b000 => Ok(Instruction::Lb(IType(i))),
160 0b001 => Ok(Instruction::Lh(IType(i))),
161 0b010 => Ok(Instruction::Lw(IType(i))),
162 0b011 => Ok(Instruction::Ld(IType(i))),
163 0b100 => Ok(Instruction::Lbu(IType(i))),
164 0b101 => Ok(Instruction::Lhu(IType(i))),
165 0b110 => Ok(Instruction::Lwu(IType(i))),
166 0b111 => Err(DecodingError::Reserved),
167 _ => unreachable!(),
168 }
169}
170
171fn decode_misc_mem(i: u32) -> DecodingResult {
172 if i == 0b001000000001111 {
173 Ok(Instruction::FenceI)
174 } else if i & 0xf00fff80 == 0 {
175 Ok(Instruction::Fence(FenceType(i)))
176 } else {
177 Err(DecodingError::Reserved)
178 }
179}
180
181fn decode_op_imm(i: u32) -> DecodingResult {
182 match (i >> 12) & 0b111 {
183 0b000 => Ok(Instruction::Addi(IType(i))),
184 0b001 => match i >> 26 {
185 0 => Ok(Instruction::Slli(ShiftType(i))),
186 _ => Err(DecodingError::Unknown),
187 },
188 0b010 => Ok(Instruction::Slti(IType(i))),
189 0b011 => Ok(Instruction::Sltiu(IType(i))),
190 0b100 => Ok(Instruction::Xori(IType(i))),
191 0b101 => match i >> 26 {
192 0b000000 => Ok(Instruction::Srli(ShiftType(i))),
193 0b010000 => Ok(Instruction::Srai(ShiftType(i))),
194 _ => Err(DecodingError::Unknown),
195 },
196 0b110 => Ok(Instruction::Ori(IType(i))),
197 0b111 => Ok(Instruction::Andi(IType(i))),
198 _ => unreachable!(),
199 }
200}
201
202fn decode_op_imm32(i: u32) -> DecodingResult {
203 match (i >> 25, (i >> 12) & 0b111) {
204 (_, 0b000) => Ok(Instruction::Addiw(IType(i))),
205 (0b0000000, 0b001) => Ok(Instruction::Slliw(ShiftType(i))),
206 (0b0000000, 0b101) => Ok(Instruction::Srliw(ShiftType(i))),
207 (0b0100000, 0b101) => Ok(Instruction::Sraiw(ShiftType(i))),
208 _ => Err(DecodingError::Unknown),
209 }
210}
211
212fn decode_store(i: u32) -> DecodingResult {
213 match (i >> 12) & 0b111 {
214 0b000 => Ok(Instruction::Sb(SType(i))),
215 0b001 => Ok(Instruction::Sh(SType(i))),
216 0b010 => Ok(Instruction::Sw(SType(i))),
217 0b011 => Ok(Instruction::Sd(SType(i))),
218 _ => Err(DecodingError::Unknown),
219 }
220}
221
222fn decode_op(i: u32) -> DecodingResult {
223 match (i >> 25, (i >> 12) & 0b111) {
224 (0b0000000, 0b000) => Ok(Instruction::Add(RType(i))),
225 (0b0100000, 0b000) => Ok(Instruction::Sub(RType(i))),
226 (0b0000000, 0b001) => Ok(Instruction::Sll(RType(i))),
227 (0b0000000, 0b010) => Ok(Instruction::Slt(RType(i))),
228 (0b0000000, 0b011) => Ok(Instruction::Sltu(RType(i))),
229 (0b0000000, 0b100) => Ok(Instruction::Xor(RType(i))),
230 (0b0000000, 0b101) => Ok(Instruction::Srl(RType(i))),
231 (0b0100000, 0b101) => Ok(Instruction::Sra(RType(i))),
232 (0b0000000, 0b110) => Ok(Instruction::Or(RType(i))),
233 (0b0000000, 0b111) => Ok(Instruction::And(RType(i))),
234
235 (0b0000001, 0b000) => Ok(Instruction::Mul(RType(i))),
236 (0b0000001, 0b001) => Ok(Instruction::Mulh(RType(i))),
237 (0b0000001, 0b010) => Ok(Instruction::Mulhsu(RType(i))),
238 (0b0000001, 0b011) => Ok(Instruction::Mulhu(RType(i))),
239 (0b0000001, 0b100) => Ok(Instruction::Div(RType(i))),
240 (0b0000001, 0b101) => Ok(Instruction::Divu(RType(i))),
241 (0b0000001, 0b110) => Ok(Instruction::Rem(RType(i))),
242 (0b0000001, 0b111) => Ok(Instruction::Remu(RType(i))),
243 _ => Err(DecodingError::Unknown),
244 }
245}
246
247fn decode_op32(i: u32) -> DecodingResult {
248 match (i >> 25, (i >> 12) & 0b111) {
249 (0b0000000, 0b000) => Ok(Instruction::Addw(RType(i))),
250 (0b0100000, 0b000) => Ok(Instruction::Subw(RType(i))),
251 (0b0000000, 0b001) => Ok(Instruction::Sllw(RType(i))),
252 (0b0000000, 0b101) => Ok(Instruction::Srlw(RType(i))),
253 (0b0100000, 0b101) => Ok(Instruction::Sraw(RType(i))),
254
255 (0b0000001, 0b000) => Ok(Instruction::Mulw(RType(i))),
256 (0b0000001, 0b100) => Ok(Instruction::Divw(RType(i))),
257 (0b0000001, 0b101) => Ok(Instruction::Divuw(RType(i))),
258 (0b0000001, 0b110) => Ok(Instruction::Remw(RType(i))),
259 (0b0000001, 0b111) => Ok(Instruction::Remuw(RType(i))),
260 _ => Err(DecodingError::Unknown),
261 }
262}
263
264fn decode_branch(i: u32) -> DecodingResult {
265 match (i >> 12) & 0b111 {
266 0b000 => Ok(Instruction::Beq(BType(i))),
267 0b001 => Ok(Instruction::Bne(BType(i))),
268 0b010 => Err(DecodingError::Unknown),
269 0b011 => Err(DecodingError::Unknown),
270 0b100 => Ok(Instruction::Blt(BType(i))),
271 0b101 => Ok(Instruction::Bge(BType(i))),
272 0b110 => Ok(Instruction::Bltu(BType(i))),
273 0b111 => Ok(Instruction::Bgeu(BType(i))),
274 _ => unreachable!(),
275 }
276}
277
278fn decode_system(i: u32) -> DecodingResult {
279 match i {
280 0b000000000000_00000_000_00000_1110011 => return Ok(Instruction::Ecall),
282 0b000000000001_00000_000_00000_1110011 => return Ok(Instruction::Ebreak),
283 0b0000000_00010_00000_000_00000_1110011 => return Ok(Instruction::Uret),
285 0b0001000_00010_00000_000_00000_1110011 => return Ok(Instruction::Sret),
286 0b0011000_00010_00000_000_00000_1110011 => return Ok(Instruction::Mret),
287 0b0001000_00101_00000_000_00000_1110011 => return Ok(Instruction::Wfi),
289 _ => {}
290 }
291
292 match (i >> 12) & 0b111 {
293 0b001 => return Ok(Instruction::Csrrw(CsrType(i))),
294 0b010 => return Ok(Instruction::Csrrs(CsrType(i))),
295 0b011 => return Ok(Instruction::Csrrc(CsrType(i))),
296 0b101 => return Ok(Instruction::Csrrwi(CsrIType(i))),
297 0b110 => return Ok(Instruction::Csrrsi(CsrIType(i))),
298 0b111 => return Ok(Instruction::Csrrci(CsrIType(i))),
299 _ => {}
300 }
301
302 const SFENCE_VMA_MASK: u32 = 0b1111111_00000_00000_111_11111_1111111;
304 const SFENCE_VMA_VALUE: u32 = 0b0001001_00000_00000_000_00000_1110011;
305 if i & SFENCE_VMA_MASK == SFENCE_VMA_VALUE {
306 return Ok(Instruction::SfenceVma(RType(i)));
307 }
308
309 Err(DecodingError::Unknown)
310}
311
312fn decode_amo(i: u32) -> DecodingResult {
313 match (i >> 27, (i >> 12) & 0b111) {
314 (0b00010, 0b010) => Ok(Instruction::LrW(RType(i))),
315 (0b00011, 0b010) => Ok(Instruction::ScW(RType(i))),
316 (0b00001, 0b010) => Ok(Instruction::AmoswapW(RType(i))),
317 (0b00000, 0b010) => Ok(Instruction::AmoaddW(RType(i))),
318 (0b00100, 0b010) => Ok(Instruction::AmoxorW(RType(i))),
319 (0b01100, 0b010) => Ok(Instruction::AmoandW(RType(i))),
320 (0b01000, 0b010) => Ok(Instruction::AmoorW(RType(i))),
321 (0b10000, 0b010) => Ok(Instruction::AmominW(RType(i))),
322 (0b10100, 0b010) => Ok(Instruction::AmomaxW(RType(i))),
323 (0b11000, 0b010) => Ok(Instruction::AmominuW(RType(i))),
324 (0b11100, 0b010) => Ok(Instruction::AmomaxuW(RType(i))),
325
326 (0b00010, 0b011) => Ok(Instruction::LrD(RType(i))),
327 (0b00011, 0b011) => Ok(Instruction::ScD(RType(i))),
328 (0b00001, 0b011) => Ok(Instruction::AmoswapD(RType(i))),
329 (0b00000, 0b011) => Ok(Instruction::AmoaddD(RType(i))),
330 (0b00100, 0b011) => Ok(Instruction::AmoxorD(RType(i))),
331 (0b01100, 0b011) => Ok(Instruction::AmoandD(RType(i))),
332 (0b01000, 0b011) => Ok(Instruction::AmoorD(RType(i))),
333 (0b10000, 0b011) => Ok(Instruction::AmominD(RType(i))),
334 (0b10100, 0b011) => Ok(Instruction::AmomaxD(RType(i))),
335 (0b11000, 0b011) => Ok(Instruction::AmominuD(RType(i))),
336 (0b11100, 0b011) => Ok(Instruction::AmomaxuD(RType(i))),
337 _ => Err(DecodingError::Unknown),
338 }
339}
340
341#[cfg(test)]
342mod tests {
343 use super::*;
344 use Instruction::*;
345
346 #[test]
355 fn decoding() {
356 assert_eq!(decode(0x00001a37).unwrap(), Lui(UType(0x00001a37))); assert_eq!(decode(0x800002b7).unwrap(), Lui(UType(0x800002b7))); assert_eq!(decode(0x212120b7).unwrap(), Lui(UType(0x212120b7))); assert_eq!(decode(0xffffe517).unwrap(), Auipc(UType(0xffffe517))); assert_eq!(decode(0xfffff797).unwrap(), Auipc(UType(0xfffff797))); assert_eq!(decode(0xfffff797).unwrap(), Auipc(UType(0xfffff797))); assert_eq!(decode(0xfe1ff06f).unwrap(), Jal(JType(0xfe1ff06f))); assert_eq!(decode(0x0000006f).unwrap(), Jal(JType(0x0000006f))); assert_eq!(decode(0xf89ff06f).unwrap(), Jal(JType(0xf89ff06f))); assert_eq!(decode(0x00008067).unwrap(), Jalr(IType(0x00008067))); assert_eq!(decode(0x00008067).unwrap(), Jalr(IType(0x00008067))); assert_eq!(decode(0x000f0067).unwrap(), Jalr(IType(0x000f0067))); }
369
370 #[test]
371 fn load() {
372 assert_eq!(decode(0x02008283).unwrap(), Lb(IType(0x02008283))); assert_eq!(decode(0x00708283).unwrap(), Lb(IType(0x00708283))); assert_eq!(decode(0x00108f03).unwrap(), Lb(IType(0x00108f03))); assert_eq!(decode(0x00411f03).unwrap(), Lh(IType(0x00411f03))); assert_eq!(decode(0x00611f03).unwrap(), Lh(IType(0x00611f03))); assert_eq!(decode(0x00811f03).unwrap(), Lh(IType(0x00811f03))); assert_eq!(decode(0x02052403).unwrap(), Lw(IType(0x02052403))); assert_eq!(decode(0x03452683).unwrap(), Lw(IType(0x03452683))); assert_eq!(decode(0x0006a703).unwrap(), Lw(IType(0x0006a703))); assert_eq!(decode(0x0006c783).unwrap(), Lbu(IType(0x0006c783))); assert_eq!(decode(0x0006c703).unwrap(), Lbu(IType(0x0006c703))); assert_eq!(decode(0x0007c683).unwrap(), Lbu(IType(0x0007c683))); assert_eq!(decode(0x0060df03).unwrap(), Lhu(IType(0x0060df03))); assert_eq!(decode(0xffe0df03).unwrap(), Lhu(IType(0xffe0df03))); assert_eq!(decode(0x0002d303).unwrap(), Lhu(IType(0x0002d303))); assert_eq!(decode(0x00346303).unwrap(), Lwu(IType(0x00346303))); assert_eq!(decode(0x0080ef03).unwrap(), Lwu(IType(0x0080ef03))); assert_eq!(decode(0x0000ef03).unwrap(), Lwu(IType(0x0000ef03))); assert_eq!(decode(0x01853683).unwrap(), Ld(IType(0x01853683))); assert_eq!(decode(0x02013c03).unwrap(), Ld(IType(0x02013c03))); assert_eq!(decode(0x0007b703).unwrap(), Ld(IType(0x0007b703))); }
394
395 #[test]
396 fn misc_mem() {
397 assert_eq!(decode(0x0310000f).unwrap(), Fence(FenceType(0x0310000f))); assert_eq!(decode(0x0820000f).unwrap(), Fence(FenceType(0x0820000f))); assert_eq!(decode(0x0ff0000f).unwrap(), Fence(FenceType(0x0ff0000f))); assert_eq!(decode(0x0000100f).unwrap(), FenceI); }
402
403 #[test]
404 fn op_imm() {
405 assert_eq!(decode(0x00200793).unwrap(), Addi(IType(0x00200793))); assert_eq!(decode(0x00000013).unwrap(), Addi(IType(0x00000013))); assert_eq!(decode(0x00000013).unwrap(), Addi(IType(0x00000013))); assert_eq!(decode(0x00381813).unwrap(), Slli(ShiftType(0x00381813))); assert_eq!(decode(0x01059793).unwrap(), Slli(ShiftType(0x01059793))); assert_eq!(decode(0x03079793).unwrap(), Slli(ShiftType(0x03079793))); assert_eq!(decode(0x0010af13).unwrap(), Slti(IType(0x0010af13))); assert_eq!(decode(0x7ff0af13).unwrap(), Slti(IType(0x7ff0af13))); assert_eq!(decode(0x8000af13).unwrap(), Slti(IType(0x8000af13))); assert_eq!(decode(0x0017b613).unwrap(), Sltiu(IType(0x0017b613))); assert_eq!(decode(0xfff0bf13).unwrap(), Sltiu(IType(0xfff0bf13))); assert_eq!(decode(0x0017b613).unwrap(), Sltiu(IType(0x0017b613))); assert_eq!(decode(0xfff6c693).unwrap(), Xori(IType(0xfff6c693))); assert_eq!(decode(0x999ac093).unwrap(), Xori(IType(0x999ac093))); assert_eq!(decode(0xfff6c693).unwrap(), Xori(IType(0xfff6c693))); assert_eq!(decode(0x00c7d793).unwrap(), Srli(ShiftType(0x00c7d793))); assert_eq!(decode(0x0207d793).unwrap(), Srli(ShiftType(0x0207d793))); assert_eq!(decode(0x00c7d793).unwrap(), Srli(ShiftType(0x00c7d793))); assert_eq!(decode(0x40e0df13).unwrap(), Srai(ShiftType(0x40e0df13))); assert_eq!(decode(0x41f55893).unwrap(), Srai(ShiftType(0x41f55893))); assert_eq!(decode(0x40e0df13).unwrap(), Srai(ShiftType(0x40e0df13))); assert_eq!(decode(0x00156513).unwrap(), Ori(IType(0x00156513))); assert_eq!(decode(0x04076713).unwrap(), Ori(IType(0x04076713))); assert_eq!(decode(0x5391e193).unwrap(), Ori(IType(0x5391e193))); assert_eq!(decode(0xff867693).unwrap(), Andi(IType(0xff867693))); assert_eq!(decode(0x08077693).unwrap(), Andi(IType(0x08077693))); assert_eq!(decode(0x04077693).unwrap(), Andi(IType(0x04077693))); }
433
434 #[test]
435 fn op_imm32() {
436 assert_eq!(decode(0x0010009b).unwrap(), Addiw(IType(0x0010009b))); assert_eq!(decode(0xfff0809b).unwrap(), Addiw(IType(0xfff0809b))); assert_eq!(decode(0xfff0809b).unwrap(), Addiw(IType(0xfff0809b))); assert_eq!(decode(0x0057979b).unwrap(), Slliw(ShiftType(0x0057979b))); assert_eq!(decode(0x0057979b).unwrap(), Slliw(ShiftType(0x0057979b))); assert_eq!(decode(0x00e09f1b).unwrap(), Slliw(ShiftType(0x00e09f1b))); assert_eq!(decode(0x0017d61b).unwrap(), Srliw(ShiftType(0x0017d61b))); assert_eq!(decode(0x01f0df1b).unwrap(), Srliw(ShiftType(0x01f0df1b))); assert_eq!(decode(0x0017d61b).unwrap(), Srliw(ShiftType(0x0017d61b))); assert_eq!(decode(0x41f0df1b).unwrap(), Sraiw(ShiftType(0x41f0df1b))); assert_eq!(decode(0x4000df1b).unwrap(), Sraiw(ShiftType(0x4000df1b))); assert_eq!(decode(0x4070d09b).unwrap(), Sraiw(ShiftType(0x4070d09b))); }
449
450 #[test]
451 fn store() {
452 assert_eq!(decode(0x00e78023).unwrap(), Sb(SType(0x00e78023))); assert_eq!(decode(0x001101a3).unwrap(), Sb(SType(0x001101a3))); assert_eq!(decode(0xfee78fa3).unwrap(), Sb(SType(0xfee78fa3))); assert_eq!(decode(0xfe209d23).unwrap(), Sh(SType(0xfe209d23))); assert_eq!(decode(0x00111223).unwrap(), Sh(SType(0x00111223))); assert_eq!(decode(0x00111523).unwrap(), Sh(SType(0x00111523))); assert_eq!(decode(0x05612c23).unwrap(), Sw(SType(0x05612c23))); assert_eq!(decode(0x01b12e23).unwrap(), Sw(SType(0x01b12e23))); assert_eq!(decode(0x01052223).unwrap(), Sw(SType(0x01052223))); assert_eq!(decode(0x0b613823).unwrap(), Sd(SType(0x0b613823))); assert_eq!(decode(0x09213823).unwrap(), Sd(SType(0x09213823))); assert_eq!(decode(0x00f6b423).unwrap(), Sd(SType(0x00f6b423))); }
465
466 #[test]
467 fn op() {
468 assert_eq!(decode(0x00c58633).unwrap(), Add(RType(0x00c58633))); assert_eq!(decode(0x00d506b3).unwrap(), Add(RType(0x00d506b3))); assert_eq!(decode(0x00a70533).unwrap(), Add(RType(0x00a70533))); assert_eq!(decode(0x40b50533).unwrap(), Sub(RType(0x40b50533))); assert_eq!(decode(0x40e78533).unwrap(), Sub(RType(0x40e78533))); assert_eq!(decode(0x41060633).unwrap(), Sub(RType(0x41060633))); assert_eq!(decode(0x00209f33).unwrap(), Sll(RType(0x00209f33))); assert_eq!(decode(0x00209f33).unwrap(), Sll(RType(0x00209f33))); assert_eq!(decode(0x00209f33).unwrap(), Sll(RType(0x00209f33))); assert_eq!(decode(0x0020af33).unwrap(), Slt(RType(0x0020af33))); assert_eq!(decode(0x0020af33).unwrap(), Slt(RType(0x0020af33))); assert_eq!(decode(0x0020af33).unwrap(), Slt(RType(0x0020af33))); assert_eq!(decode(0x0020bf33).unwrap(), Sltu(RType(0x0020bf33))); assert_eq!(decode(0x0020bf33).unwrap(), Sltu(RType(0x0020bf33))); assert_eq!(decode(0x000030b3).unwrap(), Sltu(RType(0x000030b3))); assert_eq!(decode(0x00f647b3).unwrap(), Xor(RType(0x00f647b3))); assert_eq!(decode(0x0020cf33).unwrap(), Xor(RType(0x0020cf33))); assert_eq!(decode(0x0020c133).unwrap(), Xor(RType(0x0020c133))); assert_eq!(decode(0x0020d0b3).unwrap(), Srl(RType(0x0020d0b3))); assert_eq!(decode(0x0020df33).unwrap(), Srl(RType(0x0020df33))); assert_eq!(decode(0x0020df33).unwrap(), Srl(RType(0x0020df33))); assert_eq!(decode(0x4020df33).unwrap(), Sra(RType(0x4020df33))); assert_eq!(decode(0x400050b3).unwrap(), Sra(RType(0x400050b3))); assert_eq!(decode(0x4020d133).unwrap(), Sra(RType(0x4020d133))); assert_eq!(decode(0x00b7e5b3).unwrap(), Or(RType(0x00b7e5b3))); assert_eq!(decode(0x00f665b3).unwrap(), Or(RType(0x00f665b3))); assert_eq!(decode(0x00b7e7b3).unwrap(), Or(RType(0x00b7e7b3))); assert_eq!(decode(0x00d57533).unwrap(), And(RType(0x00d57533))); assert_eq!(decode(0x00b7f733).unwrap(), And(RType(0x00b7f733))); assert_eq!(decode(0x00c7f733).unwrap(), And(RType(0x00c7f733))); assert_eq!(decode(0x021080b3).unwrap(), Mul(RType(0x021080b3))); assert_eq!(decode(0x02208f33).unwrap(), Mul(RType(0x02208f33))); assert_eq!(decode(0x02208133).unwrap(), Mul(RType(0x02208133))); assert_eq!(decode(0x02209133).unwrap(), Mulh(RType(0x02209133))); assert_eq!(decode(0x02209f33).unwrap(), Mulh(RType(0x02209f33))); assert_eq!(decode(0x02209f33).unwrap(), Mulh(RType(0x02209f33))); assert_eq!(decode(0x0220a133).unwrap(), Mulhsu(RType(0x0220a133))); assert_eq!(decode(0x0220af33).unwrap(), Mulhsu(RType(0x0220af33))); assert_eq!(decode(0x0220af33).unwrap(), Mulhsu(RType(0x0220af33))); assert_eq!(decode(0x0220bf33).unwrap(), Mulhu(RType(0x0220bf33))); assert_eq!(decode(0x0220bf33).unwrap(), Mulhu(RType(0x0220bf33))); assert_eq!(decode(0x0220bf33).unwrap(), Mulhu(RType(0x0220bf33))); assert_eq!(decode(0x0220cf33).unwrap(), Div(RType(0x0220cf33))); assert_eq!(decode(0x0220cf33).unwrap(), Div(RType(0x0220cf33))); assert_eq!(decode(0x0220cf33).unwrap(), Div(RType(0x0220cf33))); assert_eq!(decode(0x0220df33).unwrap(), Divu(RType(0x0220df33))); assert_eq!(decode(0x0220df33).unwrap(), Divu(RType(0x0220df33))); assert_eq!(decode(0x0220df33).unwrap(), Divu(RType(0x0220df33))); assert_eq!(decode(0x0220ef33).unwrap(), Rem(RType(0x0220ef33))); assert_eq!(decode(0x0220ef33).unwrap(), Rem(RType(0x0220ef33))); assert_eq!(decode(0x0220ef33).unwrap(), Rem(RType(0x0220ef33))); assert_eq!(decode(0x0220ff33).unwrap(), Remu(RType(0x0220ff33))); assert_eq!(decode(0x0220ff33).unwrap(), Remu(RType(0x0220ff33))); assert_eq!(decode(0x0220ff33).unwrap(), Remu(RType(0x0220ff33))); }
523
524 #[test]
525 fn op32() {
526 assert_eq!(decode(0x00c687bb).unwrap(), Addw(RType(0x00c687bb))); assert_eq!(decode(0x00c687bb).unwrap(), Addw(RType(0x00c687bb))); assert_eq!(decode(0x00208f3b).unwrap(), Addw(RType(0x00208f3b))); assert_eq!(decode(0x40e5053b).unwrap(), Subw(RType(0x40e5053b))); assert_eq!(decode(0x40e5053b).unwrap(), Subw(RType(0x40e5053b))); assert_eq!(decode(0x40e5053b).unwrap(), Subw(RType(0x40e5053b))); assert_eq!(decode(0x001090bb).unwrap(), Sllw(RType(0x001090bb))); assert_eq!(decode(0x00209f3b).unwrap(), Sllw(RType(0x00209f3b))); assert_eq!(decode(0x00209f3b).unwrap(), Sllw(RType(0x00209f3b))); assert_eq!(decode(0x0020df3b).unwrap(), Srlw(RType(0x0020df3b))); assert_eq!(decode(0x0020df3b).unwrap(), Srlw(RType(0x0020df3b))); assert_eq!(decode(0x0020d13b).unwrap(), Srlw(RType(0x0020d13b))); assert_eq!(decode(0x4020df3b).unwrap(), Sraw(RType(0x4020df3b))); assert_eq!(decode(0x4020df3b).unwrap(), Sraw(RType(0x4020df3b))); assert_eq!(decode(0x4020df3b).unwrap(), Sraw(RType(0x4020df3b))); assert_eq!(decode(0x02208f3b).unwrap(), Mulw(RType(0x02208f3b))); assert_eq!(decode(0x02208f3b).unwrap(), Mulw(RType(0x02208f3b))); assert_eq!(decode(0x02208f3b).unwrap(), Mulw(RType(0x02208f3b))); assert_eq!(decode(0x0220cf3b).unwrap(), Divw(RType(0x0220cf3b))); assert_eq!(decode(0x0220cf3b).unwrap(), Divw(RType(0x0220cf3b))); assert_eq!(decode(0x0220cf3b).unwrap(), Divw(RType(0x0220cf3b))); assert_eq!(decode(0x0220df3b).unwrap(), Divuw(RType(0x0220df3b))); assert_eq!(decode(0x0220df3b).unwrap(), Divuw(RType(0x0220df3b))); assert_eq!(decode(0x0220df3b).unwrap(), Divuw(RType(0x0220df3b))); assert_eq!(decode(0x0220ef3b).unwrap(), Remw(RType(0x0220ef3b))); assert_eq!(decode(0x0220ef3b).unwrap(), Remw(RType(0x0220ef3b))); assert_eq!(decode(0x0220ef3b).unwrap(), Remw(RType(0x0220ef3b))); assert_eq!(decode(0x0220ff3b).unwrap(), Remuw(RType(0x0220ff3b))); assert_eq!(decode(0x0220ff3b).unwrap(), Remuw(RType(0x0220ff3b))); assert_eq!(decode(0x0220ff3b).unwrap(), Remuw(RType(0x0220ff3b))); }
557
558 #[test]
559 fn branch() {
560 assert_eq!(decode(0x10e78463).unwrap(), Beq(BType(0x10e78463))); assert_eq!(decode(0x00050a63).unwrap(), Beq(BType(0x00050a63))); assert_eq!(decode(0x1b5a0463).unwrap(), Beq(BType(0x1b5a0463))); assert_eq!(decode(0xfe5210e3).unwrap(), Bne(BType(0xfe5210e3))); assert_eq!(decode(0x00e79a63).unwrap(), Bne(BType(0x00e79a63))); assert_eq!(decode(0x25df1863).unwrap(), Bne(BType(0x25df1863))); assert_eq!(decode(0x1220c063).unwrap(), Blt(BType(0x1220c063))); assert_eq!(decode(0x00054863).unwrap(), Blt(BType(0x00054863))); assert_eq!(decode(0xfe20cee3).unwrap(), Blt(BType(0xfe20cee3))); assert_eq!(decode(0x000f5463).unwrap(), Bge(BType(0x000f5463))); assert_eq!(decode(0x0020d663).unwrap(), Bge(BType(0x0020d663))); assert_eq!(decode(0x0620d463).unwrap(), Bge(BType(0x0620d463))); assert_eq!(decode(0xfec7ece3).unwrap(), Bltu(BType(0xfec7ece3))); assert_eq!(decode(0xfec7ece3).unwrap(), Bltu(BType(0xfec7ece3))); assert_eq!(decode(0x0020e663).unwrap(), Bltu(BType(0x0020e663))); assert_eq!(decode(0x00f5f463).unwrap(), Bgeu(BType(0x00f5f463))); assert_eq!(decode(0x00f5f463).unwrap(), Bgeu(BType(0x00f5f463))); assert_eq!(decode(0xfec572e3).unwrap(), Bgeu(BType(0xfec572e3))); }
579
580 #[test]
581 fn system() {
582 assert_eq!(decode(0x00000073).unwrap(), Ecall); assert_eq!(decode(0x10200073).unwrap(), Sret); assert_eq!(decode(0x30200073).unwrap(), Mret); assert_eq!(decode(0x10500073).unwrap(), Wfi); assert_eq!(decode(0x10569073).unwrap(), Csrrw(CsrType(0x10569073))); assert_eq!(decode(0x18079073).unwrap(), Csrrw(CsrType(0x18079073))); assert_eq!(decode(0x10551073).unwrap(), Csrrw(CsrType(0x10551073))); assert_eq!(decode(0x1007a073).unwrap(), Csrrs(CsrType(0x1007a073))); assert_eq!(decode(0x1006a073).unwrap(), Csrrs(CsrType(0x1006a073))); assert_eq!(decode(0x1004b073).unwrap(), Csrrc(CsrType(0x1004b073))); assert_eq!(decode(0x100db073).unwrap(), Csrrc(CsrType(0x100db073))); assert_eq!(decode(0x1006b073).unwrap(), Csrrc(CsrType(0x1006b073))); assert_eq!(decode(0x14005073).unwrap(), Csrrwi(CsrIType(0x14005073))); assert_eq!(decode(0x10016073).unwrap(), Csrrsi(CsrIType(0x10016073))); assert_eq!(decode(0x100176f3).unwrap(), Csrrci(CsrIType(0x100176f3))); assert_eq!(decode(0x10017773).unwrap(), Csrrci(CsrIType(0x10017773))); }
599
600 #[test]
601 fn float() {
602 assert_eq!(decode(0x0004a787).unwrap(), Flw(IType(0x0004a787))); assert_eq!(decode(0x1e872687).unwrap(), Flw(IType(0x1e872687))); assert_eq!(decode(0x1e472707).unwrap(), Flw(IType(0x1e472707))); assert_eq!(decode(0x00aa2027).unwrap(), Fsw(SType(0x00aa2027))); assert_eq!(decode(0x00f4a027).unwrap(), Fsw(SType(0x00f4a027))); assert_eq!(decode(0x00fba827).unwrap(), Fsw(SType(0x00fba827))); assert_eq!(decode(0xd19b1543).unwrap(), Fmadds(R4Type(0xd19b1543))); assert_eq!(decode(0x114f8bc3).unwrap(), Fmadds(R4Type(0x114f8bc3))); assert_eq!(decode(0x08cf53c3).unwrap(), Fmadds(R4Type(0x08cf53c3))); assert_eq!(decode(0x3166dd47).unwrap(), Fmsubs(R4Type(0x3166dd47))); assert_eq!(decode(0x50077347).unwrap(), Fmsubs(R4Type(0x50077347))); assert_eq!(decode(0xb903e1c7).unwrap(), Fmsubs(R4Type(0xb903e1c7))); assert_eq!(decode(0xc9cd48cb).unwrap(), Fnmsubs(R4Type(0xc9cd48cb))); assert_eq!(decode(0xa1ee44cb).unwrap(), Fnmsubs(R4Type(0xa1ee44cb))); assert_eq!(decode(0xf8db734b).unwrap(), Fnmsubs(R4Type(0xf8db734b))); assert_eq!(decode(0x19613e4f).unwrap(), Fnmadds(R4Type(0x19613e4f))); assert_eq!(decode(0xc944cfcf).unwrap(), Fnmadds(R4Type(0xc944cfcf))); assert_eq!(decode(0x191506cf).unwrap(), Fnmadds(R4Type(0x191506cf))); assert_eq!(decode(0x0127f553).unwrap(), Fadds(RType(0x0127f553))); assert_eq!(decode(0x01257553).unwrap(), Fadds(RType(0x01257553))); assert_eq!(decode(0x0135f9d3).unwrap(), Fadds(RType(0x0135f9d3))); assert_eq!(decode(0x0897f7d3).unwrap(), Fsubs(RType(0x0897f7d3))); assert_eq!(decode(0x0957f7d3).unwrap(), Fsubs(RType(0x0957f7d3))); assert_eq!(decode(0x0935f753).unwrap(), Fsubs(RType(0x0935f753))); assert_eq!(decode(0x10f97953).unwrap(), Fmuls(RType(0x10f97953))); assert_eq!(decode(0x1187f7d3).unwrap(), Fmuls(RType(0x1187f7d3))); assert_eq!(decode(0x116b7553).unwrap(), Fmuls(RType(0x116b7553))); assert_eq!(decode(0x1947f553).unwrap(), Fdivs(RType(0x1947f553))); assert_eq!(decode(0x18a7f553).unwrap(), Fdivs(RType(0x18a7f553))); assert_eq!(decode(0x18f777d3).unwrap(), Fdivs(RType(0x18f777d3))); assert_eq!(decode(0x58057553).unwrap(), Fsqrts(RType(0x58057553))); assert_eq!(decode(0x580e35d3).unwrap(), Fsqrts(RType(0x580e35d3))); assert_eq!(decode(0x5808c0d3).unwrap(), Fsqrts(RType(0x5808c0d3))); assert_eq!(decode(0x21ca0ed3).unwrap(), Fsgnjs(RType(0x21ca0ed3))); assert_eq!(decode(0x20d103d3).unwrap(), Fsgnjs(RType(0x20d103d3))); assert_eq!(decode(0x209c0d53).unwrap(), Fsgnjs(RType(0x209c0d53))); assert_eq!(decode(0x21dd1b53).unwrap(), Fsgnjns(RType(0x21dd1b53))); assert_eq!(decode(0x20971153).unwrap(), Fsgnjns(RType(0x20971153))); assert_eq!(decode(0x211d1953).unwrap(), Fsgnjns(RType(0x211d1953))); assert_eq!(decode(0x20eb2153).unwrap(), Fsgnjxs(RType(0x20eb2153))); assert_eq!(decode(0x219fa7d3).unwrap(), Fsgnjxs(RType(0x219fa7d3))); assert_eq!(decode(0x215baad3).unwrap(), Fsgnjxs(RType(0x215baad3))); assert_eq!(decode(0x286b82d3).unwrap(), Fmins(RType(0x286b82d3))); assert_eq!(decode(0x29ac88d3).unwrap(), Fmins(RType(0x29ac88d3))); assert_eq!(decode(0x29728c53).unwrap(), Fmins(RType(0x29728c53))); assert_eq!(decode(0x29441153).unwrap(), Fmaxs(RType(0x29441153))); assert_eq!(decode(0x29689fd3).unwrap(), Fmaxs(RType(0x29689fd3))); assert_eq!(decode(0x286a1fd3).unwrap(), Fmaxs(RType(0x286a1fd3))); assert_eq!(decode(0xc0056553).unwrap(), Fcvtws(RType(0xc0056553))); assert_eq!(decode(0xc006fad3).unwrap(), Fcvtws(RType(0xc006fad3))); assert_eq!(decode(0xc00fa8d3).unwrap(), Fcvtws(RType(0xc00fa8d3))); assert_eq!(decode(0xc014cb53).unwrap(), Fcvtwus(RType(0xc014cb53))); assert_eq!(decode(0xc01698d3).unwrap(), Fcvtwus(RType(0xc01698d3))); assert_eq!(decode(0xc01e5dd3).unwrap(), Fcvtwus(RType(0xc01e5dd3))); assert_eq!(decode(0xe00482d3).unwrap(), Fmvxw(RType(0xe00482d3))); assert_eq!(decode(0xe00d86d3).unwrap(), Fmvxw(RType(0xe00d86d3))); assert_eq!(decode(0xe0088053).unwrap(), Fmvxw(RType(0xe0088053))); assert_eq!(decode(0xa0742153).unwrap(), Feqs(RType(0xa0742153))); assert_eq!(decode(0xa0a0a153).unwrap(), Feqs(RType(0xa0a0a153))); assert_eq!(decode(0xa1aba853).unwrap(), Feqs(RType(0xa1aba853))); assert_eq!(decode(0xa0651953).unwrap(), Flts(RType(0xa0651953))); assert_eq!(decode(0xa0ab9f53).unwrap(), Flts(RType(0xa0ab9f53))); assert_eq!(decode(0xa19595d3).unwrap(), Flts(RType(0xa19595d3))); assert_eq!(decode(0xa1ff8d53).unwrap(), Fles(RType(0xa1ff8d53))); assert_eq!(decode(0xa0f40653).unwrap(), Fles(RType(0xa0f40653))); assert_eq!(decode(0xa1ab0c53).unwrap(), Fles(RType(0xa1ab0c53))); assert_eq!(decode(0xe00a1e53).unwrap(), Fclasss(RType(0xe00a1e53))); assert_eq!(decode(0xe00f1c53).unwrap(), Fclasss(RType(0xe00f1c53))); assert_eq!(decode(0xe00e9d53).unwrap(), Fclasss(RType(0xe00e9d53))); assert_eq!(decode(0xd009d7d3).unwrap(), Fcvtsw(RType(0xd009d7d3))); assert_eq!(decode(0xd001a953).unwrap(), Fcvtsw(RType(0xd001a953))); assert_eq!(decode(0xd00507d3).unwrap(), Fcvtsw(RType(0xd00507d3))); assert_eq!(decode(0xd01c27d3).unwrap(), Fcvtswu(RType(0xd01c27d3))); assert_eq!(decode(0xd019edd3).unwrap(), Fcvtswu(RType(0xd019edd3))); assert_eq!(decode(0xd012c3d3).unwrap(), Fcvtswu(RType(0xd012c3d3))); assert_eq!(decode(0xf0000e53).unwrap(), Fmvwx(RType(0xf0000e53))); assert_eq!(decode(0xf0098053).unwrap(), Fmvwx(RType(0xf0098053))); assert_eq!(decode(0xf00081d3).unwrap(), Fmvwx(RType(0xf00081d3))); }
681
682 #[test]
683 fn amo() {
684 assert_eq!(decode(0x08b6a72f).unwrap(), AmoswapW(RType(0x08b6a72f))); assert_eq!(decode(0x00b6a72f).unwrap(), AmoaddW(RType(0x00b6a72f))); assert_eq!(decode(0x20b6a72f).unwrap(), AmoxorW(RType(0x20b6a72f))); assert_eq!(decode(0x60b6a72f).unwrap(), AmoandW(RType(0x60b6a72f))); assert_eq!(decode(0x40b6a72f).unwrap(), AmoorW(RType(0x40b6a72f))); assert_eq!(decode(0x80b6a72f).unwrap(), AmominW(RType(0x80b6a72f))); assert_eq!(decode(0xa0b6a72f).unwrap(), AmomaxW(RType(0xa0b6a72f))); assert_eq!(decode(0xc0b6a72f).unwrap(), AmominuW(RType(0xc0b6a72f))); assert_eq!(decode(0xe0b6a72f).unwrap(), AmomaxuW(RType(0xe0b6a72f))); assert_eq!(decode(0x100525af).unwrap(), LrW(RType(0x100525af))); assert_eq!(decode(0x180525af).unwrap(), ScW(RType(0x180525af))); assert_eq!(decode(0x08b6b72f).unwrap(), AmoswapD(RType(0x08b6b72f))); assert_eq!(decode(0x00b6b72f).unwrap(), AmoaddD(RType(0x00b6b72f))); assert_eq!(decode(0x20b6b72f).unwrap(), AmoxorD(RType(0x20b6b72f))); assert_eq!(decode(0x60b6b72f).unwrap(), AmoandD(RType(0x60b6b72f))); assert_eq!(decode(0x40b6b72f).unwrap(), AmoorD(RType(0x40b6b72f))); assert_eq!(decode(0x80b6b72f).unwrap(), AmominD(RType(0x80b6b72f))); assert_eq!(decode(0xa0b6b72f).unwrap(), AmomaxD(RType(0xa0b6b72f))); assert_eq!(decode(0xc0b6b72f).unwrap(), AmominuD(RType(0xc0b6b72f))); assert_eq!(decode(0xe0b6b72f).unwrap(), AmomaxuD(RType(0xe0b6b72f))); assert_eq!(decode(0x1005372f).unwrap(), LrD(RType(0x1005372f))); assert_eq!(decode(0x180535af).unwrap(), ScD(RType(0x180535af))); }
707}