1pub const OPCODE_LOAD: u32 = 0x03;
12pub const OPCODE_MISC_MEM: u32 = 0x0f;
13pub const OPCODE_OP_IMM: u32 = 0x13;
14pub const OPCODE_AUIPC: u32 = 0x17;
15pub const OPCODE_STORE: u32 = 0x23;
16pub const OPCODE_OP: u32 = 0x33;
17pub const OPCODE_LUI: u32 = 0x37;
18pub const OPCODE_BRANCH: u32 = 0x63;
19pub const OPCODE_JALR: u32 = 0x67;
20pub const OPCODE_JAL: u32 = 0x6f;
21pub const OPCODE_SYSTEM: u32 = 0x73;
22
23#[derive(Debug, PartialEq)]
24pub struct RType {
25 pub funct7: u32,
26 pub rs2: usize,
27 pub rs1: usize,
28 pub funct3: u32,
29 pub rd: usize,
30}
31
32impl RType {
33 pub fn new(insn: u32) -> RType {
34 RType {
35 funct7: (insn >> 25) & 0x7f,
36 rs2: ((insn >> 20) & 0x1f) as usize,
37 rs1: ((insn >> 15) & 0x1f) as usize,
38 funct3: (insn >> 12) & 0x7,
39 rd: ((insn >> 7) & 0x1f) as usize,
40 }
41 }
42}
43
44#[derive(Debug, PartialEq)]
45pub struct IType {
46 pub imm: i32,
47 pub rs1: usize,
48 pub funct3: u32,
49 pub rd: usize,
50}
51
52impl IType {
53 pub fn new(insn: u32) -> IType {
54 let uimm: i32 = ((insn >> 20) & 0x7ff) as i32;
55
56 let imm: i32 = if (insn & 0x8000_0000) != 0 {
57 uimm - (1 << 11)
58 } else {
59 uimm
60 };
61
62 IType {
63 imm,
64 rs1: ((insn >> 15) & 0x1f) as usize,
65 funct3: (insn >> 12) & 0x7,
66 rd: ((insn >> 7) & 0x1f) as usize,
67 }
68 }
69}
70
71#[derive(Debug, PartialEq)]
72pub struct ITypeShamt {
73 pub funct7: u32,
74 pub shamt: u32,
75 pub rs1: usize,
76 pub funct3: u32,
77 pub rd: usize,
78}
79
80impl ITypeShamt {
81 pub fn new(insn: u32) -> ITypeShamt {
82 let itype = IType::new(insn);
83 let shamt = (itype.imm as u32) & 0x1f;
84
85 ITypeShamt {
86 funct7: (insn >> 25) & 0x7f,
87 shamt,
88 rs1: itype.rs1,
89 funct3: itype.funct3,
90 rd: itype.rd,
91 }
92 }
93}
94
95#[derive(Debug, PartialEq)]
96pub struct SType {
97 pub imm: i32,
98 pub rs2: usize,
99 pub rs1: usize,
100 pub funct3: u32,
101}
102
103impl SType {
104 pub fn new(insn: u32) -> SType {
105 let uimm: i32 = (((insn >> 20) & 0x7e0) | ((insn >> 7) & 0x1f)) as i32;
106
107 let imm: i32 = if (insn & 0x8000_0000) != 0 {
108 uimm - (1 << 11)
109 } else {
110 uimm
111 };
112
113 SType {
114 imm,
115 rs2: ((insn >> 20) & 0x1f) as usize,
116 rs1: ((insn >> 15) & 0x1f) as usize,
117 funct3: (insn >> 12) & 0x7,
118 }
119 }
120}
121
122#[derive(Debug, PartialEq)]
123pub struct BType {
124 pub imm: i32,
125 pub rs2: usize,
126 pub rs1: usize,
127 pub funct3: u32,
128}
129
130impl BType {
131 pub fn new(insn: u32) -> BType {
132 let uimm: i32 =
133 (((insn >> 20) & 0x7e0) | ((insn >> 7) & 0x1e) | ((insn & 0x80) << 4)) as i32;
134
135 let imm: i32 = if (insn & 0x8000_0000) != 0 {
136 uimm - (1 << 12)
137 } else {
138 uimm
139 };
140
141 BType {
142 imm,
143 rs2: ((insn >> 20) & 0x1f) as usize,
144 rs1: ((insn >> 15) & 0x1f) as usize,
145 funct3: (insn >> 12) & 0x7,
146 }
147 }
148}
149
150#[derive(Debug, PartialEq)]
151pub struct UType {
152 pub imm: i32,
153 pub rd: usize,
154}
155
156impl UType {
157 pub fn new(insn: u32) -> UType {
158 UType {
159 imm: (insn & 0xffff_f000) as i32,
160 rd: ((insn >> 7) & 0x1f) as usize,
161 }
162 }
163}
164
165#[derive(Debug, PartialEq)]
166pub struct JType {
167 pub imm: i32,
168 pub rd: usize,
169}
170
171impl JType {
172 pub fn new(insn: u32) -> JType {
173 let uimm: i32 =
174 ((insn & 0xff000) | ((insn & 0x100000) >> 9) | ((insn >> 20) & 0x7fe)) as i32;
175
176 let imm: i32 = if (insn & 0x8000_0000) != 0 {
177 uimm - (1 << 20)
178 } else {
179 uimm
180 };
181
182 JType {
183 imm,
184 rd: ((insn >> 7) & 0x1f) as usize,
185 }
186 }
187}
188
189#[cfg(test)]
190
191mod tests {
192 use super::*;
193
194 #[test]
195 fn test_rtype() {
196 assert_eq!(
197 RType::new(0x0),
198 RType {
199 funct7: 0,
200 rs2: 0,
201 rs1: 0,
202 funct3: 0,
203 rd: 0
204 }
205 )
206 }
207
208 #[test]
209 fn test_itype() {
210 assert_eq!(
212 IType::new(0x7fff8b93),
213 IType {
214 imm: 2047,
215 rs1: 31,
216 funct3: 0,
217 rd: 23
218 }
219 );
220
221 assert_eq!(
223 IType::new(0xffff8b93),
224 IType {
225 imm: -1,
226 rs1: 31,
227 funct3: 0,
228 rd: 23
229 }
230 );
231
232 assert_eq!(
234 IType::new(0xffef8b93),
235 IType {
236 imm: -2,
237 rs1: 31,
238 funct3: 0,
239 rd: 23
240 }
241 );
242
243 assert_eq!(
245 IType::new(0x8003e693),
246 IType {
247 imm: -2048,
248 rs1: 7,
249 funct3: 0b110,
250 rd: 13
251 }
252 );
253 }
254
255 #[test]
256 fn test_itype_shamt() {
257 assert_eq!(
259 ITypeShamt::new(0x00d29613),
260 ITypeShamt {
261 funct7: 0,
262 shamt: 13,
263 rs1: 5,
264 funct3: 0b001,
265 rd: 12
266 }
267 );
268
269 assert_eq!(
271 ITypeShamt::new(0x01f9df13),
272 ITypeShamt {
273 funct7: 0,
274 shamt: 31,
275 rs1: 19,
276 funct3: 0b101,
277 rd: 30
278 }
279 );
280
281 assert_eq!(
283 ITypeShamt::new(0x400bd393),
284 ITypeShamt {
285 funct7: 0b0100000,
286 shamt: 0,
287 rs1: 23,
288 funct3: 0b101,
289 rd: 7
290 }
291 );
292 }
293
294 #[test]
295 fn test_stype() {
296 assert_eq!(
298 SType::new(0x81f78023),
299 SType {
300 imm: -2048,
301 rs2: 31,
302 rs1: 15,
303 funct3: 0,
304 }
305 );
306
307 assert_eq!(
309 SType::new(0x7f219fa3),
310 SType {
311 imm: 2047,
312 rs2: 18,
313 rs1: 3,
314 funct3: 1,
315 }
316 );
317
318 assert_eq!(
320 SType::new(0x008ba0a3),
321 SType {
322 imm: 1,
323 rs2: 8,
324 rs1: 23,
325 funct3: 2,
326 }
327 );
328
329 assert_eq!(
331 SType::new(0xfe5cafa3),
332 SType {
333 imm: -1,
334 rs2: 5,
335 rs1: 25,
336 funct3: 2,
337 }
338 );
339
340 assert_eq!(
342 SType::new(0x00d623a3),
343 SType {
344 imm: 7,
345 rs2: 13,
346 rs1: 12,
347 funct3: 2,
348 }
349 );
350
351 assert_eq!(
353 SType::new(0xfed62ca3),
354 SType {
355 imm: -7,
356 rs2: 13,
357 rs1: 12,
358 funct3: 2,
359 }
360 );
361 }
362
363 #[test]
364 fn test_btype() {
365 assert_eq!(
367 BType::new(0x80e50063),
368 BType {
369 imm: -4096,
370 rs1: 10,
371 rs2: 14,
372 funct3: 0b000
373 }
374 );
375
376 assert_eq!(
378 BType::new(0x7f51cfe3),
379 BType {
380 imm: 4094,
381 rs1: 3,
382 rs2: 21,
383 funct3: 0b100
384 }
385 );
386
387 assert_eq!(
389 BType::new(0xfe095fe3),
390 BType {
391 imm: -2,
392 rs1: 18,
393 rs2: 0,
394 funct3: 0b101
395 }
396 );
397
398 assert_eq!(
400 BType::new(0x01079163),
401 BType {
402 imm: 2,
403 rs1: 15,
404 rs2: 16,
405 funct3: 0b001
406 }
407 );
408
409 assert_eq!(
411 BType::new(0x008ff963),
412 BType {
413 imm: 18,
414 rs1: 31,
415 rs2: 8,
416 funct3: 0b111
417 }
418 );
419
420 assert_eq!(
422 BType::new(0xfe8ff7e3),
423 BType {
424 imm: -18,
425 rs1: 31,
426 rs2: 8,
427 funct3: 0b111
428 }
429 );
430 }
431
432 #[test]
433 fn test_utype() {
434 assert_eq!(
436 UType::new(0xfffff037),
437 UType {
438 imm: (0xfffff000 as u32) as i32,
439 rd: 0,
440 }
441 );
442
443 assert_eq!(UType::new(0x00000fb7), UType { imm: 0x0, rd: 31 });
445
446 assert_eq!(
448 UType::new(0x123ab8b7),
449 UType {
450 imm: 0x123ab000,
451 rd: 17,
452 }
453 );
454 }
455
456 #[test]
457 fn test_jtype() {
458 assert_eq!(
460 JType::new(0x7ffff06f),
461 JType {
462 imm: 0xffffe,
463 rd: 0,
464 }
465 );
466
467 assert_eq!(
469 JType::new(0x80000fef),
470 JType {
471 imm: -0x100000,
472 rd: 31,
473 }
474 );
475
476 assert_eq!(JType::new(0xfffff6ef), JType { imm: -2, rd: 13 });
478
479 assert_eq!(JType::new(0x002006ef), JType { imm: 2, rd: 13 });
481
482 assert_eq!(JType::new(0xfd3ffd6f), JType { imm: -46, rd: 26 });
484
485 assert_eq!(JType::new(0x02e00d6f), JType { imm: 46, rd: 26 });
487 }
488}