1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
#![no_std]
mod compressed;
mod instruction;
pub mod types;
use types::*;
pub use instruction::Instruction;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum DecodingError {
Custom,
Reserved,
Unknown,
Truncated,
Unimplemented,
}
type DecodingResult = Result<Instruction, DecodingError>;
pub fn instruction_length(i: u16) -> usize {
if i & 0b11 != 0b11 {
2
} else if i & 0b11100 != 0b11100 {
4
} else if i & 0b111111 == 0b011111 {
6
} else if i & 0b1111111 == 0b011111 {
8
} else {
10 + 2 * ((i >> 12) & 0b111) as usize
}
}
pub fn decode(i: u32) -> DecodingResult {
match i & 0b11 {
0b00 => compressed::decode_q00(i),
0b01 => compressed::decode_q01(i),
0b10 => compressed::decode_q10(i),
0b11 => match (i >> 2) & 0b11111 {
0b00000 => decode_load(i),
0b00001 => match (i >> 12) & 0b111 {
0b010 => Ok(Instruction::Flw(IType(i))),
_ => Err(DecodingError::Unknown),
},
0b00010 => Err(DecodingError::Custom),
0b00011 => decode_misc_mem(i),
0b00100 => decode_op_imm(i),
0b00101 => Ok(Instruction::Auipc(UType(i))),
0b00110 => decode_op_imm32(i),
0b00111 => Err(DecodingError::Reserved),
0b01000 => decode_store(i),
0b01001 => match (i >> 12) & 0b111 {
0b010 => Ok(Instruction::Fsw(SType(i))),
_ => Err(DecodingError::Unknown),
},
0b01010 => Err(DecodingError::Custom),
0b01011 => Err(DecodingError::Unimplemented),
0b01100 => decode_op(i),
0b01101 => Ok(Instruction::Lui(UType(i))),
0b01110 => decode_op32(i),
0b01111 => Err(DecodingError::Reserved),
0b10000 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fmadds(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10001 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fmsubs(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10010 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fnmsubs(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10011 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fnmadds(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10100 => decode_opfp(i),
0b10101 => Err(DecodingError::Reserved),
0b10110 => Err(DecodingError::Custom),
0b10111 => Err(DecodingError::Reserved),
0b11000 => decode_branch(i),
0b11001 => Ok(Instruction::Jalr(IType(i))),
0b11010 => Err(DecodingError::Reserved),
0b11011 => Ok(Instruction::Jal(JType(i))),
0b11100 => decode_system(i),
0b11101 => Err(DecodingError::Reserved),
0b11110 => Err(DecodingError::Custom),
0b11111 => Err(DecodingError::Reserved),
_ => unreachable!(),
},
_ => unreachable!(),
}
}
fn decode_opfp(i: u32) -> Result<Instruction, DecodingError> {
match (i >> 25) & 0b1111111 {
0b0000000 => Ok(Instruction::Fadds(RType(i))),
0b0000100 => Ok(Instruction::Fsubs(RType(i))),
0b0001000 => Ok(Instruction::Fmuls(RType(i))),
0b0001100 => Ok(Instruction::Fdivs(RType(i))),
0b0101100 if i >> 20 & 0b11111 == 0 => Ok(Instruction::Fsqrts(RType(i))),
0b0010000 => match i >> 12 & 0b111 {
0b000 => Ok(Instruction::Fsgnjs(RType(i))),
0b001 => Ok(Instruction::Fsgnjns(RType(i))),
0b010 => Ok(Instruction::Fsgnjxs(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b0010100 => match i >> 12 & 0b111 {
0b000 => Ok(Instruction::Fmins(RType(i))),
0b001 => Ok(Instruction::Fmaxs(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b1100000 => match i >> 20 & 0b11111 {
0b00000 => Ok(Instruction::Fcvtws(RType(i))),
0b00001 => Ok(Instruction::Fcvtwus(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b1110000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0 => {
Ok(Instruction::Fmvxw(RType(i)))
}
0b1010000 => match i >> 12 & 0b111 {
0b010 => Ok(Instruction::Feqs(RType(i))),
0b001 => Ok(Instruction::Flts(RType(i))),
0b000 => Ok(Instruction::Fles(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b1110000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0b001 => {
Ok(Instruction::Fclasss(RType(i)))
}
0b1101000 if i >> 20 & 0b11111 == 0 => Ok(Instruction::Fcvtsw(RType(i))),
0b1101000 if i >> 20 & 0b11111 == 1 => Ok(Instruction::Fcvtswu(RType(i))),
0b1111000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0 => {
Ok(Instruction::Fmvwx(RType(i)))
}
_ => Err(DecodingError::Unknown),
}
}
fn decode_load(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Lb(IType(i))),
0b001 => Ok(Instruction::Lh(IType(i))),
0b010 => Ok(Instruction::Lw(IType(i))),
0b011 => Ok(Instruction::Ld(IType(i))),
0b100 => Ok(Instruction::Lbu(IType(i))),
0b101 => Ok(Instruction::Lhu(IType(i))),
0b110 => Ok(Instruction::Lwu(IType(i))),
0b111 => Err(DecodingError::Reserved),
_ => unreachable!(),
}
}
fn decode_misc_mem(i: u32) -> DecodingResult {
if i == 0b001000000001111 {
Ok(Instruction::FenceI)
} else if i & 0xf00fff80 == 0 {
Ok(Instruction::Fence(FenceType(i)))
} else {
Err(DecodingError::Reserved)
}
}
fn decode_op_imm(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Addi(IType(i))),
0b001 => match i >> 26 {
0 => Ok(Instruction::Slli(ShiftType(i))),
_ => Err(DecodingError::Unknown),
},
0b010 => Ok(Instruction::Slti(IType(i))),
0b011 => Ok(Instruction::Sltiu(IType(i))),
0b100 => Ok(Instruction::Xori(IType(i))),
0b101 => match i >> 26 {
0b000000 => Ok(Instruction::Srli(ShiftType(i))),
0b010000 => Ok(Instruction::Srai(ShiftType(i))),
_ => Err(DecodingError::Unknown),
},
0b110 => Ok(Instruction::Ori(IType(i))),
0b111 => Ok(Instruction::Andi(IType(i))),
_ => unreachable!(),
}
}
fn decode_op_imm32(i: u32) -> DecodingResult {
match (i >> 25, (i >> 12) & 0b111) {
(_, 0b000) => Ok(Instruction::Addiw(IType(i))),
(0b0000000, 0b001) => Ok(Instruction::Slliw(ShiftType(i))),
(0b0000000, 0b101) => Ok(Instruction::Srliw(ShiftType(i))),
(0b0100000, 0b101) => Ok(Instruction::Sraiw(ShiftType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_store(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Sb(SType(i))),
0b001 => Ok(Instruction::Sh(SType(i))),
0b010 => Ok(Instruction::Sw(SType(i))),
0b011 => Ok(Instruction::Sd(SType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_op(i: u32) -> DecodingResult {
match (i >> 25, (i >> 12) & 0b111) {
(0b0000000, 0b000) => Ok(Instruction::Add(RType(i))),
(0b0100000, 0b000) => Ok(Instruction::Sub(RType(i))),
(0b0000000, 0b001) => Ok(Instruction::Sll(RType(i))),
(0b0000000, 0b010) => Ok(Instruction::Slt(RType(i))),
(0b0000000, 0b011) => Ok(Instruction::Sltu(RType(i))),
(0b0000000, 0b100) => Ok(Instruction::Xor(RType(i))),
(0b0000000, 0b101) => Ok(Instruction::Srl(RType(i))),
(0b0100000, 0b101) => Ok(Instruction::Sra(RType(i))),
(0b0000000, 0b110) => Ok(Instruction::Or(RType(i))),
(0b0000000, 0b111) => Ok(Instruction::And(RType(i))),
(0b0000001, 0b000) => Ok(Instruction::Mul(RType(i))),
(0b0000001, 0b001) => Ok(Instruction::Mulh(RType(i))),
(0b0000001, 0b010) => Ok(Instruction::Mulhsu(RType(i))),
(0b0000001, 0b011) => Ok(Instruction::Mulhu(RType(i))),
(0b0000001, 0b100) => Ok(Instruction::Div(RType(i))),
(0b0000001, 0b101) => Ok(Instruction::Divu(RType(i))),
(0b0000001, 0b110) => Ok(Instruction::Rem(RType(i))),
(0b0000001, 0b111) => Ok(Instruction::Remu(RType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_op32(i: u32) -> DecodingResult {
match (i >> 25, (i >> 12) & 0b111) {
(0b0000000, 0b000) => Ok(Instruction::Addw(RType(i))),
(0b0100000, 0b000) => Ok(Instruction::Subw(RType(i))),
(0b0000000, 0b001) => Ok(Instruction::Sllw(RType(i))),
(0b0000000, 0b101) => Ok(Instruction::Srlw(RType(i))),
(0b0100000, 0b101) => Ok(Instruction::Sraw(RType(i))),
(0b0000001, 0b000) => Ok(Instruction::Mulw(RType(i))),
(0b0000001, 0b100) => Ok(Instruction::Divw(RType(i))),
(0b0000001, 0b101) => Ok(Instruction::Divuw(RType(i))),
(0b0000001, 0b110) => Ok(Instruction::Remw(RType(i))),
(0b0000001, 0b111) => Ok(Instruction::Remuw(RType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_branch(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Beq(BType(i))),
0b001 => Ok(Instruction::Bne(BType(i))),
0b010 => Err(DecodingError::Unknown),
0b011 => Err(DecodingError::Unknown),
0b100 => Ok(Instruction::Blt(BType(i))),
0b101 => Ok(Instruction::Bge(BType(i))),
0b110 => Ok(Instruction::Bltu(BType(i))),
0b111 => Ok(Instruction::Bgeu(BType(i))),
_ => unreachable!(),
}
}
fn decode_system(i: u32) -> DecodingResult {
match i {
0b000000000000_00000_000_00000_1110011 => return Ok(Instruction::Ecall),
0b000000000001_00000_000_00000_1110011 => return Ok(Instruction::Ebreak),
0b0000000_00010_00000_000_00000_1110011 => return Ok(Instruction::Uret),
0b0001000_00010_00000_000_00000_1110011 => return Ok(Instruction::Sret),
0b0011000_00010_00000_000_00000_1110011 => return Ok(Instruction::Mret),
0b0001000_00101_00000_000_00000_1110011 => return Ok(Instruction::Wfi),
_ => {}
}
match (i >> 12) & 0b111 {
0b001 => return Ok(Instruction::Csrrw(CsrType(i))),
0b010 => return Ok(Instruction::Csrrs(CsrType(i))),
0b011 => return Ok(Instruction::Csrrc(CsrType(i))),
0b101 => return Ok(Instruction::Csrrwi(CsrIType(i))),
0b110 => return Ok(Instruction::Csrrsi(CsrIType(i))),
0b111 => return Ok(Instruction::Csrrci(CsrIType(i))),
_ => {}
}
const SFENCE_VMA_MASK: u32 = 0b1111111_00000_00000_111_11111_1111111;
const SFENCE_VMA_VALUE: u32 = 0b0001001_00000_00000_000_00000_1110011;
if i & SFENCE_VMA_MASK == SFENCE_VMA_VALUE {
return Ok(Instruction::SfenceVma(RType(i)));
}
Err(DecodingError::Unknown)
}
#[cfg(test)]
mod tests {
use super::*;
use Instruction::*;
#[test]
fn decoding() {
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)));
}
#[test]
fn load() {
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)));
}
#[test]
fn misc_mem() {
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);
}
#[test]
fn op_imm() {
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)));
}
#[test]
fn op_imm32() {
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)));
}
#[test]
fn store() {
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)));
}
#[test]
fn op() {
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)));
}
#[test]
fn op32() {
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)));
}
#[test]
fn branch() {
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)));
}
#[test]
fn system() {
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)));
}
#[test]
fn float() {
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)));
}
}