1 use crate::isa::riscv64::inst::*;
2 use crate::isa::riscv64::lower::isle::generated_code::FpuOPWidth;
3 use alloc::borrow::Cow;
4 
fa7() -> Reg5 fn fa7() -> Reg {
6     f_reg(17)
7 }
8 
9 #[test]
test_riscv64_binemit()10 fn test_riscv64_binemit() {
11     struct TestUnit {
12         inst: Inst,
13         assembly: &'static str,
14         code: TestEncoding,
15     }
16 
17     struct TestEncoding(Cow<'static, str>);
18 
19     impl From<&'static str> for TestEncoding {
20         fn from(value: &'static str) -> Self {
21             Self(value.into())
22         }
23     }
24 
25     impl From<u32> for TestEncoding {
26         fn from(value: u32) -> Self {
27             let value = value.swap_bytes();
28             let value = format!("{value:08X}");
29             Self(value.into())
30         }
31     }
32 
33     impl TestUnit {
34         fn new(inst: Inst, assembly: &'static str, code: impl Into<TestEncoding>) -> Self {
35             let code = code.into();
36             Self {
37                 inst,
38                 assembly,
39                 code,
40             }
41         }
42     }
43 
44     let mut insns = Vec::<TestUnit>::with_capacity(500);
45 
46     insns.push(TestUnit::new(Inst::Ret {}, "ret", 0x00008067));
47 
48     insns.push(TestUnit::new(
49         Inst::Mov {
50             rd: writable_fa0(),
51             rm: fa1(),
52             ty: F32,
53         },
54         "fmv.s fa0,fa1",
55         0x20b58553,
56     ));
57 
58     insns.push(TestUnit::new(
59         Inst::Mov {
60             rd: writable_fa0(),
61             rm: fa1(),
62             ty: F64,
63         },
64         "fmv.d fa0,fa1",
65         0x22b58553,
66     ));
67 
68     insns.push(TestUnit::new(
69         Inst::AluRRImm12 {
70             alu_op: AluOPRRI::Brev8,
71             rd: writable_a1(),
72             rs: a0(),
73             imm12: Imm12::ZERO,
74         },
75         "brev8 a1,a0",
76         0x68755593,
77     ));
78     insns.push(TestUnit::new(
79         Inst::AluRRImm12 {
80             alu_op: AluOPRRI::Rev8,
81             rd: writable_a1(),
82             rs: a0(),
83             imm12: Imm12::ZERO,
84         },
85         "rev8 a1,a0",
86         0x6b855593,
87     ));
88 
89     //
90     insns.push(TestUnit::new(
91         Inst::AluRRImm12 {
92             alu_op: AluOPRRI::Bclri,
93             rd: writable_a1(),
94             rs: a0(),
95             imm12: Imm12::from_i16(5),
96         },
97         "bclri a1,a0,5",
98         0x48551593,
99     ));
100     insns.push(TestUnit::new(
101         Inst::AluRRImm12 {
102             alu_op: AluOPRRI::Bexti,
103             rd: writable_a1(),
104             rs: a0(),
105             imm12: Imm12::from_i16(5),
106         },
107         "bexti a1,a0,5",
108         0x48555593,
109     ));
110 
111     insns.push(TestUnit::new(
112         Inst::AluRRImm12 {
113             alu_op: AluOPRRI::Binvi,
114             rd: writable_a1(),
115             rs: a0(),
116             imm12: Imm12::from_i16(5),
117         },
118         "binvi a1,a0,5",
119         0x68551593,
120     ));
121 
122     insns.push(TestUnit::new(
123         Inst::AluRRImm12 {
124             alu_op: AluOPRRI::Bseti,
125             rd: writable_a1(),
126             rs: a0(),
127             imm12: Imm12::from_i16(5),
128         },
129         "bseti a1,a0,5",
130         0x28551593,
131     ));
132 
133     insns.push(TestUnit::new(
134         Inst::AluRRImm12 {
135             alu_op: AluOPRRI::Rori,
136             rd: writable_a1(),
137             rs: a0(),
138             imm12: Imm12::from_i16(5),
139         },
140         "rori a1,a0,5",
141         0x60555593,
142     ));
143     insns.push(TestUnit::new(
144         Inst::AluRRImm12 {
145             alu_op: AluOPRRI::Roriw,
146             rd: writable_a1(),
147             rs: a0(),
148             imm12: Imm12::from_i16(5),
149         },
150         "roriw a1,a0,5",
151         0x6055559b,
152     ));
153 
154     insns.push(TestUnit::new(
155         Inst::AluRRImm12 {
156             alu_op: AluOPRRI::SlliUw,
157             rd: writable_a1(),
158             rs: a0(),
159             imm12: Imm12::from_i16(5),
160         },
161         "slli.uw a1,a0,5",
162         0x855159b,
163     ));
164 
165     insns.push(TestUnit::new(
166         Inst::AluRRImm12 {
167             alu_op: AluOPRRI::Clz,
168             rd: writable_a1(),
169             rs: a0(),
170             imm12: Imm12::ZERO,
171         },
172         "clz a1,a0",
173         0x60051593,
174     ));
175 
176     insns.push(TestUnit::new(
177         Inst::AluRRImm12 {
178             alu_op: AluOPRRI::Clzw,
179             rd: writable_a1(),
180             rs: a0(),
181             imm12: Imm12::ZERO,
182         },
183         "clzw a1,a0",
184         0x6005159b,
185     ));
186 
187     insns.push(TestUnit::new(
188         Inst::AluRRImm12 {
189             alu_op: AluOPRRI::Cpop,
190             rd: writable_a1(),
191             rs: a0(),
192             imm12: Imm12::ZERO,
193         },
194         "cpop a1,a0",
195         0x60251593,
196     ));
197 
198     insns.push(TestUnit::new(
199         Inst::AluRRImm12 {
200             alu_op: AluOPRRI::Cpopw,
201             rd: writable_a1(),
202             rs: a0(),
203             imm12: Imm12::ZERO,
204         },
205         "cpopw a1,a0",
206         0x6025159b,
207     ));
208 
209     insns.push(TestUnit::new(
210         Inst::AluRRImm12 {
211             alu_op: AluOPRRI::Ctz,
212             rd: writable_a1(),
213             rs: a0(),
214             imm12: Imm12::ZERO,
215         },
216         "ctz a1,a0",
217         0x60151593,
218     ));
219 
220     insns.push(TestUnit::new(
221         Inst::AluRRImm12 {
222             alu_op: AluOPRRI::Ctzw,
223             rd: writable_a1(),
224             rs: a0(),
225             imm12: Imm12::ZERO,
226         },
227         "ctzw a1,a0",
228         0x6015159b,
229     ));
230 
231     insns.push(TestUnit::new(
232         Inst::AluRRImm12 {
233             alu_op: AluOPRRI::Sextb,
234             rd: writable_a1(),
235             rs: a0(),
236             imm12: Imm12::ZERO,
237         },
238         "sext.b a1,a0",
239         0x60451593,
240     ));
241     insns.push(TestUnit::new(
242         Inst::AluRRImm12 {
243             alu_op: AluOPRRI::Sexth,
244             rd: writable_a1(),
245             rs: a0(),
246             imm12: Imm12::ZERO,
247         },
248         "sext.h a1,a0",
249         0x60551593,
250     ));
251     insns.push(TestUnit::new(
252         Inst::AluRRImm12 {
253             alu_op: AluOPRRI::Zexth,
254             rd: writable_a1(),
255             rs: a0(),
256             imm12: Imm12::ZERO,
257         },
258         "zext.h a1,a0",
259         0x80545bb,
260     ));
261     insns.push(TestUnit::new(
262         Inst::AluRRImm12 {
263             alu_op: AluOPRRI::Orcb,
264             rd: writable_a1(),
265             rs: a0(),
266             imm12: Imm12::ZERO,
267         },
268         "orc.b a1,a0",
269         0x28755593,
270     ));
271 
272     insns.push(TestUnit::new(
273         Inst::AluRRR {
274             alu_op: AluOPRRR::Adduw,
275             rd: writable_a1(),
276             rs1: a0(),
277             rs2: zero_reg(),
278         },
279         "zext.w a1,a0",
280         0x80505bb,
281     ));
282 
283     insns.push(TestUnit::new(
284         Inst::AluRRR {
285             alu_op: AluOPRRR::Adduw,
286             rd: writable_a1(),
287             rs1: a0(),
288             rs2: a1(),
289         },
290         "add.uw a1,a0,a1",
291         0x08b505bb,
292     ));
293 
294     insns.push(TestUnit::new(
295         Inst::AluRRR {
296             alu_op: AluOPRRR::Andn,
297             rd: writable_a1(),
298             rs1: a0(),
299             rs2: zero_reg(),
300         },
301         "andn a1,a0,zero",
302         0x400575b3,
303     ));
304     insns.push(TestUnit::new(
305         Inst::AluRRR {
306             alu_op: AluOPRRR::Bclr,
307             rd: writable_a1(),
308             rs1: a0(),
309             rs2: zero_reg(),
310         },
311         "bclr a1,a0,zero",
312         0x480515b3,
313     ));
314 
315     insns.push(TestUnit::new(
316         Inst::AluRRR {
317             alu_op: AluOPRRR::Bext,
318             rd: writable_a1(),
319             rs1: a0(),
320             rs2: zero_reg(),
321         },
322         "bext a1,a0,zero",
323         0x480555b3,
324     ));
325 
326     insns.push(TestUnit::new(
327         Inst::AluRRR {
328             alu_op: AluOPRRR::Binv,
329             rd: writable_a1(),
330             rs1: a0(),
331             rs2: zero_reg(),
332         },
333         "binv a1,a0,zero",
334         0x680515b3,
335     ));
336     insns.push(TestUnit::new(
337         Inst::AluRRR {
338             alu_op: AluOPRRR::Bset,
339             rd: writable_a1(),
340             rs1: a0(),
341             rs2: zero_reg(),
342         },
343         "bset a1,a0,zero",
344         0x280515b3,
345     ));
346 
347     insns.push(TestUnit::new(
348         Inst::AluRRR {
349             alu_op: AluOPRRR::Clmul,
350             rd: writable_a1(),
351             rs1: a0(),
352             rs2: zero_reg(),
353         },
354         "clmul a1,a0,zero",
355         0xa0515b3,
356     ));
357 
358     insns.push(TestUnit::new(
359         Inst::AluRRR {
360             alu_op: AluOPRRR::Clmulh,
361             rd: writable_a1(),
362             rs1: a0(),
363             rs2: zero_reg(),
364         },
365         "clmulh a1,a0,zero",
366         0xa0535b3,
367     ));
368 
369     insns.push(TestUnit::new(
370         Inst::AluRRR {
371             alu_op: AluOPRRR::Clmulr,
372             rd: writable_a1(),
373             rs1: a0(),
374             rs2: zero_reg(),
375         },
376         "clmulr a1,a0,zero",
377         0xa0525b3,
378     ));
379 
380     insns.push(TestUnit::new(
381         Inst::AluRRR {
382             alu_op: AluOPRRR::Max,
383             rd: writable_a1(),
384             rs1: a0(),
385             rs2: zero_reg(),
386         },
387         "max a1,a0,zero",
388         0xa0565b3,
389     ));
390 
391     insns.push(TestUnit::new(
392         Inst::AluRRR {
393             alu_op: AluOPRRR::Maxu,
394             rd: writable_a1(),
395             rs1: a0(),
396             rs2: zero_reg(),
397         },
398         "maxu a1,a0,zero",
399         0xa0575b3,
400     ));
401 
402     insns.push(TestUnit::new(
403         Inst::AluRRR {
404             alu_op: AluOPRRR::Min,
405             rd: writable_a1(),
406             rs1: a0(),
407             rs2: zero_reg(),
408         },
409         "min a1,a0,zero",
410         0xa0545b3,
411     ));
412 
413     insns.push(TestUnit::new(
414         Inst::AluRRR {
415             alu_op: AluOPRRR::Minu,
416             rd: writable_a1(),
417             rs1: a0(),
418             rs2: zero_reg(),
419         },
420         "minu a1,a0,zero",
421         0xa0555b3,
422     ));
423 
424     insns.push(TestUnit::new(
425         Inst::AluRRR {
426             alu_op: AluOPRRR::Orn,
427             rd: writable_a1(),
428             rs1: a0(),
429             rs2: zero_reg(),
430         },
431         "orn a1,a0,zero",
432         0x400565b3,
433     ));
434 
435     insns.push(TestUnit::new(
436         Inst::AluRRR {
437             alu_op: AluOPRRR::Rol,
438             rd: writable_a1(),
439             rs1: a0(),
440             rs2: zero_reg(),
441         },
442         "rol a1,a0,zero",
443         0x600515b3,
444     ));
445 
446     insns.push(TestUnit::new(
447         Inst::AluRRR {
448             alu_op: AluOPRRR::Rolw,
449             rd: writable_a1(),
450             rs1: a0(),
451             rs2: zero_reg(),
452         },
453         "rolw a1,a0,zero",
454         0x600515bb,
455     ));
456     insns.push(TestUnit::new(
457         Inst::AluRRR {
458             alu_op: AluOPRRR::Ror,
459             rd: writable_a1(),
460             rs1: a0(),
461             rs2: zero_reg(),
462         },
463         "ror a1,a0,zero",
464         0x600555b3,
465     ));
466     insns.push(TestUnit::new(
467         Inst::AluRRR {
468             alu_op: AluOPRRR::Rorw,
469             rd: writable_a1(),
470             rs1: a0(),
471             rs2: zero_reg(),
472         },
473         "rorw a1,a0,zero",
474         0x600555bb,
475     ));
476     insns.push(TestUnit::new(
477         Inst::AluRRR {
478             alu_op: AluOPRRR::Sh1add,
479             rd: writable_a1(),
480             rs1: a0(),
481             rs2: zero_reg(),
482         },
483         "sh1add a1,a0,zero",
484         0x200525b3,
485     ));
486 
487     insns.push(TestUnit::new(
488         Inst::AluRRR {
489             alu_op: AluOPRRR::Sh1adduw,
490             rd: writable_a1(),
491             rs1: a0(),
492             rs2: zero_reg(),
493         },
494         "sh1add.uw a1,a0,zero",
495         0x200525bb,
496     ));
497     insns.push(TestUnit::new(
498         Inst::AluRRR {
499             alu_op: AluOPRRR::Sh2add,
500             rd: writable_a1(),
501             rs1: a0(),
502             rs2: zero_reg(),
503         },
504         "sh2add a1,a0,zero",
505         0x200545b3,
506     ));
507     insns.push(TestUnit::new(
508         Inst::AluRRR {
509             alu_op: AluOPRRR::Sh2adduw,
510             rd: writable_a1(),
511             rs1: a0(),
512             rs2: zero_reg(),
513         },
514         "sh2add.uw a1,a0,zero",
515         0x200545bb,
516     ));
517     insns.push(TestUnit::new(
518         Inst::AluRRR {
519             alu_op: AluOPRRR::Sh3add,
520             rd: writable_a1(),
521             rs1: a0(),
522             rs2: zero_reg(),
523         },
524         "sh3add a1,a0,zero",
525         0x200565b3,
526     ));
527     insns.push(TestUnit::new(
528         Inst::AluRRR {
529             alu_op: AluOPRRR::Sh3adduw,
530             rd: writable_a1(),
531             rs1: a0(),
532             rs2: zero_reg(),
533         },
534         "sh3add.uw a1,a0,zero",
535         0x200565bb,
536     ));
537     insns.push(TestUnit::new(
538         Inst::AluRRR {
539             alu_op: AluOPRRR::Xnor,
540             rd: writable_a1(),
541             rs1: a0(),
542             rs2: zero_reg(),
543         },
544         "xnor a1,a0,zero",
545         0x400545b3,
546     ));
547 
548     // Zbkb
549     insns.push(TestUnit::new(
550         Inst::AluRRR {
551             alu_op: AluOPRRR::Pack,
552             rd: writable_a1(),
553             rs1: a0(),
554             rs2: zero_reg(),
555         },
556         "pack a1,a0,zero",
557         0x080545b3,
558     ));
559     insns.push(TestUnit::new(
560         Inst::AluRRR {
561             alu_op: AluOPRRR::Packw,
562             rd: writable_a1(),
563             rs1: a0(),
564             rs2: zero_reg(),
565         },
566         "packw a1,a0,zero",
567         0x080545bb,
568     ));
569     insns.push(TestUnit::new(
570         Inst::AluRRR {
571             alu_op: AluOPRRR::Packh,
572             rd: writable_a1(),
573             rs1: a0(),
574             rs2: zero_reg(),
575         },
576         "packh a1,a0,zero",
577         0x080575b3,
578     ));
579 
580     //
581     insns.push(TestUnit::new(
582         Inst::AluRRR {
583             alu_op: AluOPRRR::Add,
584             rd: writable_fp_reg(),
585             rs1: fp_reg(),
586             rs2: zero_reg(),
587         },
588         "add fp,fp,zero",
589         0x40433,
590     ));
591     insns.push(TestUnit::new(
592         Inst::AluRRImm12 {
593             alu_op: AluOPRRI::Addi,
594             rd: writable_fp_reg(),
595             rs: stack_reg(),
596             imm12: Imm12::maybe_from_u64(100).unwrap(),
597         },
598         "addi fp,sp,100",
599         0x6410413,
600     ));
601     insns.push(TestUnit::new(
602         Inst::Lui {
603             rd: writable_zero_reg(),
604             imm: Imm20::from_i32(120),
605         },
606         "lui zero,120",
607         0x78037,
608     ));
609     insns.push(TestUnit::new(
610         Inst::Auipc {
611             rd: writable_zero_reg(),
612             imm: Imm20::from_i32(120),
613         },
614         "auipc zero,120",
615         0x78017,
616     ));
617 
618     insns.push(TestUnit::new(
619         Inst::Jalr {
620             rd: writable_a0(),
621             base: a0(),
622             offset: Imm12::from_i16(100),
623         },
624         "jalr a0,100(a0)",
625         0x6450567,
626     ));
627 
628     insns.push(TestUnit::new(
629         Inst::Load {
630             rd: writable_a0(),
631             op: LoadOP::Lb,
632             flags: MemFlags::new(),
633             from: AMode::RegOffset(a1(), 100),
634         },
635         "lb a0,100(a1)",
636         0x6458503,
637     ));
638     insns.push(TestUnit::new(
639         Inst::Load {
640             rd: writable_a0(),
641             op: LoadOP::Lh,
642             flags: MemFlags::new(),
643             from: AMode::RegOffset(a1(), 100),
644         },
645         "lh a0,100(a1)",
646         0x6459503,
647     ));
648 
649     insns.push(TestUnit::new(
650         Inst::Load {
651             rd: writable_a0(),
652             op: LoadOP::Lw,
653             flags: MemFlags::new(),
654             from: AMode::RegOffset(a1(), 100),
655         },
656         "lw a0,100(a1)",
657         0x645a503,
658     ));
659 
660     insns.push(TestUnit::new(
661         Inst::Load {
662             rd: writable_a0(),
663             op: LoadOP::Ld,
664             flags: MemFlags::new(),
665             from: AMode::RegOffset(a1(), 100),
666         },
667         "ld a0,100(a1)",
668         0x645b503,
669     ));
670     insns.push(TestUnit::new(
671         Inst::Load {
672             rd: Writable::from_reg(fa0()),
673             op: LoadOP::Flw,
674             flags: MemFlags::new(),
675             from: AMode::RegOffset(a1(), 100),
676         },
677         "flw fa0,100(a1)",
678         0x645a507,
679     ));
680 
681     insns.push(TestUnit::new(
682         Inst::Load {
683             rd: Writable::from_reg(fa0()),
684             op: LoadOP::Fld,
685             flags: MemFlags::new(),
686             from: AMode::RegOffset(a1(), 100),
687         },
688         "fld fa0,100(a1)",
689         0x645b507,
690     ));
691     insns.push(TestUnit::new(
692         Inst::Store {
693             to: AMode::SPOffset(100),
694             op: StoreOP::Sb,
695             flags: MemFlags::new(),
696             src: a0(),
697         },
698         "sb a0,100(sp)",
699         0x6a10223,
700     ));
701     insns.push(TestUnit::new(
702         Inst::Store {
703             to: AMode::SPOffset(100),
704             op: StoreOP::Sh,
705             flags: MemFlags::new(),
706             src: a0(),
707         },
708         "sh a0,100(sp)",
709         0x6a11223,
710     ));
711     insns.push(TestUnit::new(
712         Inst::Store {
713             to: AMode::SPOffset(100),
714             op: StoreOP::Sw,
715             flags: MemFlags::new(),
716             src: a0(),
717         },
718         "sw a0,100(sp)",
719         0x6a12223,
720     ));
721     insns.push(TestUnit::new(
722         Inst::Store {
723             to: AMode::SPOffset(100),
724             op: StoreOP::Sd,
725             flags: MemFlags::new(),
726             src: a0(),
727         },
728         "sd a0,100(sp)",
729         0x6a13223,
730     ));
731     insns.push(TestUnit::new(
732         Inst::Store {
733             to: AMode::SPOffset(100),
734             op: StoreOP::Fsw,
735             flags: MemFlags::new(),
736             src: fa0(),
737         },
738         "fsw fa0,100(sp)",
739         0x6a12227,
740     ));
741     insns.push(TestUnit::new(
742         Inst::Store {
743             to: AMode::SPOffset(100),
744             op: StoreOP::Fsd,
745             flags: MemFlags::new(),
746             src: fa0(),
747         },
748         "fsd fa0,100(sp)",
749         0x6a13227,
750     ));
751     insns.push(TestUnit::new(
752         Inst::AluRRImm12 {
753             alu_op: AluOPRRI::Addi,
754             rd: writable_a0(),
755             rs: a0(),
756             imm12: Imm12::from_i16(100),
757         },
758         "addi a0,a0,100",
759         0x6450513,
760     ));
761     insns.push(TestUnit::new(
762         Inst::AluRRImm12 {
763             alu_op: AluOPRRI::Slti,
764             rd: writable_a0(),
765             rs: a0(),
766             imm12: Imm12::from_i16(100),
767         },
768         "slti a0,a0,100",
769         0x6452513,
770     ));
771     insns.push(TestUnit::new(
772         Inst::AluRRImm12 {
773             alu_op: AluOPRRI::SltiU,
774             rd: writable_a0(),
775             rs: a0(),
776             imm12: Imm12::from_i16(100),
777         },
778         "sltiu a0,a0,100",
779         0x6453513,
780     ));
781     insns.push(TestUnit::new(
782         Inst::AluRRImm12 {
783             alu_op: AluOPRRI::Xori,
784             rd: writable_a0(),
785             rs: a0(),
786             imm12: Imm12::from_i16(100),
787         },
788         "xori a0,a0,100",
789         0x6454513,
790     ));
791     insns.push(TestUnit::new(
792         Inst::AluRRImm12 {
793             alu_op: AluOPRRI::Andi,
794             rd: writable_a0(),
795             rs: a0(),
796             imm12: Imm12::from_i16(100),
797         },
798         "andi a0,a0,100",
799         0x6457513,
800     ));
801     insns.push(TestUnit::new(
802         Inst::AluRRImm12 {
803             alu_op: AluOPRRI::Slli,
804             rd: writable_a0(),
805             rs: a0(),
806             imm12: Imm12::from_i16(5),
807         },
808         "slli a0,a0,5",
809         0x551513,
810     ));
811     insns.push(TestUnit::new(
812         Inst::AluRRImm12 {
813             alu_op: AluOPRRI::Srli,
814             rd: writable_a0(),
815             rs: a0(),
816             imm12: Imm12::from_i16(5),
817         },
818         "srli a0,a0,5",
819         0x555513,
820     ));
821     insns.push(TestUnit::new(
822         Inst::AluRRImm12 {
823             alu_op: AluOPRRI::Srai,
824             rd: writable_a0(),
825             rs: a0(),
826             imm12: Imm12::from_i16(5),
827         },
828         "srai a0,a0,5",
829         0x40555513,
830     ));
831     insns.push(TestUnit::new(
832         Inst::AluRRImm12 {
833             alu_op: AluOPRRI::Addiw,
834             rd: writable_a0(),
835             rs: a0(),
836             imm12: Imm12::from_i16(120),
837         },
838         "addiw a0,a0,120",
839         0x785051b,
840     ));
841     insns.push(TestUnit::new(
842         Inst::AluRRImm12 {
843             alu_op: AluOPRRI::Slliw,
844             rd: writable_a0(),
845             rs: a0(),
846             imm12: Imm12::from_i16(5),
847         },
848         "slliw a0,a0,5",
849         0x55151b,
850     ));
851     insns.push(TestUnit::new(
852         Inst::AluRRImm12 {
853             alu_op: AluOPRRI::SrliW,
854             rd: writable_a0(),
855             rs: a0(),
856             imm12: Imm12::from_i16(5),
857         },
858         "srliw a0,a0,5",
859         0x55551b,
860     ));
861     insns.push(TestUnit::new(
862         Inst::AluRRImm12 {
863             alu_op: AluOPRRI::Sraiw,
864             rd: writable_a0(),
865             rs: a0(),
866             imm12: Imm12::from_i16(5),
867         },
868         "sraiw a0,a0,5",
869         0x4055551b,
870     ));
871 
872     insns.push(TestUnit::new(
873         Inst::AluRRImm12 {
874             alu_op: AluOPRRI::Sraiw,
875             rd: writable_a0(),
876             rs: a0(),
877             imm12: Imm12::from_i16(5),
878         },
879         "sraiw a0,a0,5",
880         0x4055551b,
881     ));
882     insns.push(TestUnit::new(
883         Inst::AluRRR {
884             alu_op: AluOPRRR::Add,
885             rd: writable_a0(),
886             rs1: a0(),
887             rs2: a1(),
888         },
889         "add a0,a0,a1",
890         0xb50533,
891     ));
892     insns.push(TestUnit::new(
893         Inst::AluRRR {
894             alu_op: AluOPRRR::Sub,
895             rd: writable_a0(),
896             rs1: a0(),
897             rs2: a1(),
898         },
899         "sub a0,a0,a1",
900         0x40b50533,
901     ));
902     insns.push(TestUnit::new(
903         Inst::AluRRR {
904             alu_op: AluOPRRR::Sll,
905             rd: writable_a0(),
906             rs1: a0(),
907             rs2: a1(),
908         },
909         "sll a0,a0,a1",
910         0xb51533,
911     ));
912 
913     insns.push(TestUnit::new(
914         Inst::AluRRR {
915             alu_op: AluOPRRR::Slt,
916             rd: writable_a0(),
917             rs1: a0(),
918             rs2: a1(),
919         },
920         "slt a0,a0,a1",
921         0xb52533,
922     ));
923     insns.push(TestUnit::new(
924         Inst::AluRRR {
925             alu_op: AluOPRRR::SltU,
926             rd: writable_a0(),
927             rs1: a0(),
928             rs2: a1(),
929         },
930         "sltu a0,a0,a1",
931         0xb53533,
932     ));
933     insns.push(TestUnit::new(
934         Inst::AluRRR {
935             alu_op: AluOPRRR::Xor,
936             rd: writable_a0(),
937             rs1: a0(),
938             rs2: a1(),
939         },
940         "xor a0,a0,a1",
941         0xb54533,
942     ));
943     insns.push(TestUnit::new(
944         Inst::AluRRR {
945             alu_op: AluOPRRR::Srl,
946             rd: writable_a0(),
947             rs1: a0(),
948             rs2: a1(),
949         },
950         "srl a0,a0,a1",
951         0xb55533,
952     ));
953     insns.push(TestUnit::new(
954         Inst::AluRRR {
955             alu_op: AluOPRRR::Sra,
956             rd: writable_a0(),
957             rs1: a0(),
958             rs2: a1(),
959         },
960         "sra a0,a0,a1",
961         0x40b55533,
962     ));
963     insns.push(TestUnit::new(
964         Inst::AluRRR {
965             alu_op: AluOPRRR::Or,
966             rd: writable_a0(),
967             rs1: a0(),
968             rs2: a1(),
969         },
970         "or a0,a0,a1",
971         0xb56533,
972     ));
973     insns.push(TestUnit::new(
974         Inst::AluRRR {
975             alu_op: AluOPRRR::And,
976             rd: writable_a0(),
977             rs1: a0(),
978             rs2: a1(),
979         },
980         "and a0,a0,a1",
981         0xb57533,
982     ));
983     insns.push(TestUnit::new(
984         Inst::AluRRR {
985             alu_op: AluOPRRR::Addw,
986             rd: writable_a0(),
987             rs1: a0(),
988             rs2: a1(),
989         },
990         "addw a0,a0,a1",
991         0xb5053b,
992     ));
993     insns.push(TestUnit::new(
994         Inst::AluRRR {
995             alu_op: AluOPRRR::Subw,
996             rd: writable_a0(),
997             rs1: a0(),
998             rs2: a1(),
999         },
1000         "subw a0,a0,a1",
1001         0x40b5053b,
1002     ));
1003     insns.push(TestUnit::new(
1004         Inst::AluRRR {
1005             alu_op: AluOPRRR::Sllw,
1006             rd: writable_a0(),
1007             rs1: a0(),
1008             rs2: a1(),
1009         },
1010         "sllw a0,a0,a1",
1011         0xb5153b,
1012     ));
1013     insns.push(TestUnit::new(
1014         Inst::AluRRR {
1015             alu_op: AluOPRRR::Srlw,
1016             rd: writable_a0(),
1017             rs1: a0(),
1018             rs2: a1(),
1019         },
1020         "srlw a0,a0,a1",
1021         0xb5553b,
1022     ));
1023     insns.push(TestUnit::new(
1024         Inst::AluRRR {
1025             alu_op: AluOPRRR::Sraw,
1026             rd: writable_a0(),
1027             rs1: a0(),
1028             rs2: a1(),
1029         },
1030         "sraw a0,a0,a1",
1031         0x40b5553b,
1032     ));
1033 
1034     insns.push(TestUnit::new(
1035         Inst::AluRRR {
1036             alu_op: AluOPRRR::Mul,
1037             rd: writable_a0(),
1038             rs1: a0(),
1039             rs2: a1(),
1040         },
1041         "mul a0,a0,a1",
1042         0x2b50533,
1043     ));
1044 
1045     insns.push(TestUnit::new(
1046         Inst::AluRRR {
1047             alu_op: AluOPRRR::Mulh,
1048             rd: writable_a0(),
1049             rs1: a0(),
1050             rs2: a1(),
1051         },
1052         "mulh a0,a0,a1",
1053         0x2b51533,
1054     ));
1055     insns.push(TestUnit::new(
1056         Inst::AluRRR {
1057             alu_op: AluOPRRR::Mulhsu,
1058             rd: writable_a0(),
1059             rs1: a0(),
1060             rs2: a1(),
1061         },
1062         "mulhsu a0,a0,a1",
1063         0x2b52533,
1064     ));
1065     insns.push(TestUnit::new(
1066         Inst::AluRRR {
1067             alu_op: AluOPRRR::Mulhu,
1068             rd: writable_a0(),
1069             rs1: a0(),
1070             rs2: a1(),
1071         },
1072         "mulhu a0,a0,a1",
1073         0x2b53533,
1074     ));
1075     insns.push(TestUnit::new(
1076         Inst::AluRRR {
1077             alu_op: AluOPRRR::Div,
1078             rd: writable_a0(),
1079             rs1: a0(),
1080             rs2: a1(),
1081         },
1082         "div a0,a0,a1",
1083         0x2b54533,
1084     ));
1085     insns.push(TestUnit::new(
1086         Inst::AluRRR {
1087             alu_op: AluOPRRR::DivU,
1088             rd: writable_a0(),
1089             rs1: a0(),
1090             rs2: a1(),
1091         },
1092         "divu a0,a0,a1",
1093         0x2b55533,
1094     ));
1095     insns.push(TestUnit::new(
1096         Inst::AluRRR {
1097             alu_op: AluOPRRR::Rem,
1098             rd: writable_a0(),
1099             rs1: a0(),
1100             rs2: a1(),
1101         },
1102         "rem a0,a0,a1",
1103         0x2b56533,
1104     ));
1105     insns.push(TestUnit::new(
1106         Inst::AluRRR {
1107             alu_op: AluOPRRR::RemU,
1108             rd: writable_a0(),
1109             rs1: a0(),
1110             rs2: a1(),
1111         },
1112         "remu a0,a0,a1",
1113         0x2b57533,
1114     ));
1115 
1116     insns.push(TestUnit::new(
1117         Inst::AluRRR {
1118             alu_op: AluOPRRR::Mulw,
1119             rd: writable_a0(),
1120             rs1: a0(),
1121             rs2: a1(),
1122         },
1123         "mulw a0,a0,a1",
1124         0x2b5053b,
1125     ));
1126     insns.push(TestUnit::new(
1127         Inst::AluRRR {
1128             alu_op: AluOPRRR::Divw,
1129             rd: writable_a0(),
1130             rs1: a0(),
1131             rs2: a1(),
1132         },
1133         "divw a0,a0,a1",
1134         0x2b5453b,
1135     ));
1136     insns.push(TestUnit::new(
1137         Inst::AluRRR {
1138             alu_op: AluOPRRR::Remw,
1139             rd: writable_a0(),
1140             rs1: a0(),
1141             rs2: a1(),
1142         },
1143         "remw a0,a0,a1",
1144         0x2b5653b,
1145     ));
1146     insns.push(TestUnit::new(
1147         Inst::AluRRR {
1148             alu_op: AluOPRRR::Remuw,
1149             rd: writable_a0(),
1150             rs1: a0(),
1151             rs2: a1(),
1152         },
1153         "remuw a0,a0,a1",
1154         0x2b5753b,
1155     ));
1156 
1157     //
1158     insns.push(TestUnit::new(
1159         Inst::FpuRRR {
1160             frm: FRM::RNE,
1161             width: FpuOPWidth::S,
1162             alu_op: FpuOPRRR::Fadd,
1163             rd: writable_fa0(),
1164             rs1: fa0(),
1165             rs2: fa1(),
1166         },
1167         "fadd.s fa0,fa0,fa1,rne",
1168         0xb50553,
1169     ));
1170     insns.push(TestUnit::new(
1171         Inst::FpuRRR {
1172             frm: FRM::RTZ,
1173             width: FpuOPWidth::S,
1174             alu_op: FpuOPRRR::Fsub,
1175             rd: writable_fa0(),
1176             rs1: fa0(),
1177             rs2: fa1(),
1178         },
1179         "fsub.s fa0,fa0,fa1,rtz",
1180         0x8b51553,
1181     ));
1182     insns.push(TestUnit::new(
1183         Inst::FpuRRR {
1184             frm: FRM::RUP,
1185             width: FpuOPWidth::S,
1186             alu_op: FpuOPRRR::Fmul,
1187             rd: writable_fa0(),
1188             rs1: fa0(),
1189             rs2: fa1(),
1190         },
1191         "fmul.s fa0,fa0,fa1,rup",
1192         0x10b53553,
1193     ));
1194     insns.push(TestUnit::new(
1195         Inst::FpuRRR {
1196             frm: FRM::Fcsr,
1197             width: FpuOPWidth::S,
1198             alu_op: FpuOPRRR::Fdiv,
1199             rd: writable_fa0(),
1200             rs1: fa0(),
1201             rs2: fa1(),
1202         },
1203         "fdiv.s fa0,fa0,fa1,fcsr",
1204         0x18b57553,
1205     ));
1206     insns.push(TestUnit::new(
1207         Inst::FpuRRR {
1208             frm: FRM::RNE,
1209             width: FpuOPWidth::S,
1210             alu_op: FpuOPRRR::Fsgnj,
1211             rd: writable_fa0(),
1212             rs1: fa0(),
1213             rs2: fa1(),
1214         },
1215         "fsgnj.s fa0,fa0,fa1",
1216         0x20b50553,
1217     ));
1218     insns.push(TestUnit::new(
1219         Inst::FpuRRR {
1220             frm: FRM::RTZ,
1221             width: FpuOPWidth::S,
1222             alu_op: FpuOPRRR::Fsgnjn,
1223             rd: writable_fa0(),
1224             rs1: fa0(),
1225             rs2: fa1(),
1226         },
1227         "fsgnjn.s fa0,fa0,fa1",
1228         0x20b51553,
1229     ));
1230 
1231     insns.push(TestUnit::new(
1232         Inst::FpuRRR {
1233             frm: FRM::RDN,
1234             width: FpuOPWidth::S,
1235             alu_op: FpuOPRRR::Fsgnjx,
1236             rd: writable_fa0(),
1237             rs1: fa0(),
1238             rs2: fa1(),
1239         },
1240         "fsgnjx.s fa0,fa0,fa1",
1241         0x20b52553,
1242     ));
1243     insns.push(TestUnit::new(
1244         Inst::FpuRRR {
1245             frm: FRM::RNE,
1246             width: FpuOPWidth::S,
1247             alu_op: FpuOPRRR::Fmin,
1248             rd: writable_fa0(),
1249             rs1: fa0(),
1250             rs2: fa1(),
1251         },
1252         "fmin.s fa0,fa0,fa1",
1253         0x28b50553,
1254     ));
1255 
1256     insns.push(TestUnit::new(
1257         Inst::FpuRRR {
1258             frm: FRM::RTZ,
1259             width: FpuOPWidth::S,
1260             alu_op: FpuOPRRR::Fmax,
1261             rd: writable_fa0(),
1262             rs1: fa0(),
1263             rs2: fa1(),
1264         },
1265         "fmax.s fa0,fa0,fa1",
1266         0x28b51553,
1267     ));
1268     insns.push(TestUnit::new(
1269         Inst::FpuRRR {
1270             frm: FRM::RDN,
1271             width: FpuOPWidth::S,
1272             alu_op: FpuOPRRR::Feq,
1273             rd: writable_a0(),
1274             rs1: fa0(),
1275             rs2: fa1(),
1276         },
1277         "feq.s a0,fa0,fa1",
1278         0xa0b52553,
1279     ));
1280     insns.push(TestUnit::new(
1281         Inst::FpuRRR {
1282             frm: FRM::RTZ,
1283             width: FpuOPWidth::S,
1284             alu_op: FpuOPRRR::Flt,
1285             rd: writable_a0(),
1286             rs1: fa0(),
1287             rs2: fa1(),
1288         },
1289         "flt.s a0,fa0,fa1",
1290         0xa0b51553,
1291     ));
1292     insns.push(TestUnit::new(
1293         Inst::FpuRRR {
1294             frm: FRM::RNE,
1295             width: FpuOPWidth::S,
1296             alu_op: FpuOPRRR::Fle,
1297             rd: writable_a0(),
1298             rs1: fa0(),
1299             rs2: fa1(),
1300         },
1301         "fle.s a0,fa0,fa1",
1302         0xa0b50553,
1303     ));
1304 
1305     //
1306     insns.push(TestUnit::new(
1307         Inst::FpuRRR {
1308             frm: FRM::Fcsr,
1309             width: FpuOPWidth::D,
1310             alu_op: FpuOPRRR::Fadd,
1311             rd: writable_fa0(),
1312             rs1: fa0(),
1313             rs2: fa1(),
1314         },
1315         "fadd.d fa0,fa0,fa1,fcsr",
1316         0x2b57553,
1317     ));
1318     insns.push(TestUnit::new(
1319         Inst::FpuRRR {
1320             frm: FRM::Fcsr,
1321             width: FpuOPWidth::D,
1322             alu_op: FpuOPRRR::Fsub,
1323             rd: writable_fa0(),
1324             rs1: fa0(),
1325             rs2: fa1(),
1326         },
1327         "fsub.d fa0,fa0,fa1,fcsr",
1328         0xab57553,
1329     ));
1330     insns.push(TestUnit::new(
1331         Inst::FpuRRR {
1332             frm: FRM::Fcsr,
1333             width: FpuOPWidth::D,
1334             alu_op: FpuOPRRR::Fmul,
1335             rd: writable_fa0(),
1336             rs1: fa0(),
1337             rs2: fa1(),
1338         },
1339         "fmul.d fa0,fa0,fa1,fcsr",
1340         0x12b57553,
1341     ));
1342     insns.push(TestUnit::new(
1343         Inst::FpuRRR {
1344             frm: FRM::Fcsr,
1345             width: FpuOPWidth::D,
1346             alu_op: FpuOPRRR::Fdiv,
1347             rd: writable_fa0(),
1348             rs1: fa0(),
1349             rs2: fa1(),
1350         },
1351         "fdiv.d fa0,fa0,fa1,fcsr",
1352         0x1ab57553,
1353     ));
1354     insns.push(TestUnit::new(
1355         Inst::FpuRRR {
1356             frm: FRM::RNE,
1357             width: FpuOPWidth::D,
1358             alu_op: FpuOPRRR::Fsgnj,
1359             rd: writable_fa0(),
1360             rs1: fa0(),
1361             rs2: fa1(),
1362         },
1363         "fsgnj.d fa0,fa0,fa1",
1364         0x22b50553,
1365     ));
1366     insns.push(TestUnit::new(
1367         Inst::FpuRRR {
1368             frm: FRM::RTZ,
1369             width: FpuOPWidth::D,
1370             alu_op: FpuOPRRR::Fsgnjn,
1371             rd: writable_fa0(),
1372             rs1: fa0(),
1373             rs2: fa1(),
1374         },
1375         "fsgnjn.d fa0,fa0,fa1",
1376         0x22b51553,
1377     ));
1378 
1379     insns.push(TestUnit::new(
1380         Inst::FpuRRR {
1381             frm: FRM::RDN,
1382             width: FpuOPWidth::D,
1383             alu_op: FpuOPRRR::Fsgnjx,
1384             rd: writable_fa0(),
1385             rs1: fa0(),
1386             rs2: fa1(),
1387         },
1388         "fsgnjx.d fa0,fa0,fa1",
1389         0x22b52553,
1390     ));
1391     insns.push(TestUnit::new(
1392         Inst::FpuRRR {
1393             frm: FRM::RNE,
1394             width: FpuOPWidth::D,
1395             alu_op: FpuOPRRR::Fmin,
1396             rd: writable_fa0(),
1397             rs1: fa0(),
1398             rs2: fa1(),
1399         },
1400         "fmin.d fa0,fa0,fa1",
1401         0x2ab50553,
1402     ));
1403 
1404     insns.push(TestUnit::new(
1405         Inst::FpuRRR {
1406             frm: FRM::RTZ,
1407             width: FpuOPWidth::D,
1408             alu_op: FpuOPRRR::Fmax,
1409             rd: writable_fa0(),
1410             rs1: fa0(),
1411             rs2: fa1(),
1412         },
1413         "fmax.d fa0,fa0,fa1",
1414         0x2ab51553,
1415     ));
1416     insns.push(TestUnit::new(
1417         Inst::FpuRRR {
1418             frm: FRM::RDN,
1419             width: FpuOPWidth::D,
1420             alu_op: FpuOPRRR::Feq,
1421             rd: writable_a0(),
1422             rs1: fa0(),
1423             rs2: fa1(),
1424         },
1425         "feq.d a0,fa0,fa1",
1426         0xa2b52553,
1427     ));
1428     insns.push(TestUnit::new(
1429         Inst::FpuRRR {
1430             frm: FRM::RTZ,
1431             width: FpuOPWidth::D,
1432             alu_op: FpuOPRRR::Flt,
1433             rd: writable_a0(),
1434             rs1: fa0(),
1435             rs2: fa1(),
1436         },
1437         "flt.d a0,fa0,fa1",
1438         0xa2b51553,
1439     ));
1440     insns.push(TestUnit::new(
1441         Inst::FpuRRR {
1442             frm: FRM::RNE,
1443             width: FpuOPWidth::D,
1444             alu_op: FpuOPRRR::Fle,
1445             rd: writable_a0(),
1446             rs1: fa0(),
1447             rs2: fa1(),
1448         },
1449         "fle.d a0,fa0,fa1",
1450         0xa2b50553,
1451     ));
1452 
1453     //
1454     insns.push(TestUnit::new(
1455         Inst::FpuRR {
1456             frm: FRM::RNE,
1457             width: FpuOPWidth::S,
1458             alu_op: FpuOPRR::Fsqrt,
1459             rd: writable_fa0(),
1460             rs: fa1(),
1461         },
1462         "fsqrt.s fa0,fa1,rne",
1463         0x58058553,
1464     ));
1465     insns.push(TestUnit::new(
1466         Inst::FpuRR {
1467             frm: FRM::Fcsr,
1468             width: FpuOPWidth::S,
1469             alu_op: FpuOPRR::FcvtWFmt,
1470             rd: writable_a0(),
1471             rs: fa1(),
1472         },
1473         "fcvt.w.s a0,fa1,fcsr",
1474         0xc005f553,
1475     ));
1476 
1477     insns.push(TestUnit::new(
1478         Inst::FpuRR {
1479             frm: FRM::Fcsr,
1480             width: FpuOPWidth::S,
1481             alu_op: FpuOPRR::FcvtWuFmt,
1482             rd: writable_a0(),
1483             rs: fa1(),
1484         },
1485         "fcvt.wu.s a0,fa1,fcsr",
1486         0xc015f553,
1487     ));
1488     insns.push(TestUnit::new(
1489         Inst::FpuRR {
1490             frm: FRM::RNE,
1491             width: FpuOPWidth::S,
1492             alu_op: FpuOPRR::FmvXFmt,
1493             rd: writable_a0(),
1494             rs: fa1(),
1495         },
1496         "fmv.x.w a0,fa1",
1497         0xe0058553,
1498     ));
1499     insns.push(TestUnit::new(
1500         Inst::FpuRR {
1501             frm: FRM::RTZ,
1502             width: FpuOPWidth::S,
1503             alu_op: FpuOPRR::Fclass,
1504             rd: writable_a0(),
1505             rs: fa1(),
1506         },
1507         "fclass.s a0,fa1",
1508         0xe0059553,
1509     ));
1510 
1511     insns.push(TestUnit::new(
1512         Inst::FpuRR {
1513             frm: FRM::Fcsr,
1514             width: FpuOPWidth::S,
1515             alu_op: FpuOPRR::FcvtFmtW,
1516             rd: writable_fa0(),
1517             rs: a0(),
1518         },
1519         "fcvt.s.w fa0,a0,fcsr",
1520         0xd0057553,
1521     ));
1522     insns.push(TestUnit::new(
1523         Inst::FpuRR {
1524             frm: FRM::Fcsr,
1525             width: FpuOPWidth::S,
1526             alu_op: FpuOPRR::FcvtFmtWu,
1527             rd: writable_fa0(),
1528             rs: a0(),
1529         },
1530         "fcvt.s.wu fa0,a0,fcsr",
1531         0xd0157553,
1532     ));
1533 
1534     insns.push(TestUnit::new(
1535         Inst::FpuRR {
1536             frm: FRM::RNE,
1537             width: FpuOPWidth::S,
1538             alu_op: FpuOPRR::FmvFmtX,
1539             rd: writable_fa0(),
1540             rs: a0(),
1541         },
1542         "fmv.w.x fa0,a0",
1543         0xf0050553,
1544     ));
1545     insns.push(TestUnit::new(
1546         Inst::FpuRR {
1547             frm: FRM::Fcsr,
1548             width: FpuOPWidth::S,
1549             alu_op: FpuOPRR::FcvtLFmt,
1550             rd: writable_a0(),
1551             rs: fa0(),
1552         },
1553         "fcvt.l.s a0,fa0,fcsr",
1554         0xc0257553,
1555     ));
1556     insns.push(TestUnit::new(
1557         Inst::FpuRR {
1558             frm: FRM::Fcsr,
1559             width: FpuOPWidth::S,
1560             alu_op: FpuOPRR::FcvtLuFmt,
1561             rd: writable_a0(),
1562             rs: fa0(),
1563         },
1564         "fcvt.lu.s a0,fa0,fcsr",
1565         0xc0357553,
1566     ));
1567     insns.push(TestUnit::new(
1568         Inst::FpuRR {
1569             frm: FRM::Fcsr,
1570             width: FpuOPWidth::S,
1571             alu_op: FpuOPRR::FcvtFmtL,
1572             rd: writable_fa0(),
1573             rs: a0(),
1574         },
1575         "fcvt.s.l fa0,a0,fcsr",
1576         0xd0257553,
1577     ));
1578     insns.push(TestUnit::new(
1579         Inst::FpuRR {
1580             frm: FRM::Fcsr,
1581             width: FpuOPWidth::S,
1582             alu_op: FpuOPRR::FcvtFmtLu,
1583             rd: writable_fa0(),
1584             rs: a0(),
1585         },
1586         "fcvt.s.lu fa0,a0,fcsr",
1587         0xd0357553,
1588     ));
1589 
1590     insns.push(TestUnit::new(
1591         Inst::FpuRR {
1592             frm: FRM::Fcsr,
1593             width: FpuOPWidth::D,
1594             alu_op: FpuOPRR::Fsqrt,
1595             rd: writable_fa0(),
1596             rs: fa1(),
1597         },
1598         "fsqrt.d fa0,fa1,fcsr",
1599         0x5a05f553,
1600     ));
1601     insns.push(TestUnit::new(
1602         Inst::FpuRR {
1603             frm: FRM::Fcsr,
1604             width: FpuOPWidth::D,
1605             alu_op: FpuOPRR::FcvtWFmt,
1606             rd: writable_a0(),
1607             rs: fa1(),
1608         },
1609         "fcvt.w.d a0,fa1,fcsr",
1610         0xc205f553,
1611     ));
1612 
1613     insns.push(TestUnit::new(
1614         Inst::FpuRR {
1615             frm: FRM::Fcsr,
1616             width: FpuOPWidth::D,
1617             alu_op: FpuOPRR::FcvtWuFmt,
1618             rd: writable_a0(),
1619             rs: fa1(),
1620         },
1621         "fcvt.wu.d a0,fa1,fcsr",
1622         0xc215f553,
1623     ));
1624     insns.push(TestUnit::new(
1625         Inst::FpuRR {
1626             frm: FRM::RNE,
1627             width: FpuOPWidth::D,
1628             alu_op: FpuOPRR::FmvXFmt,
1629             rd: writable_a0(),
1630             rs: fa1(),
1631         },
1632         "fmv.x.d a0,fa1",
1633         0xe2058553,
1634     ));
1635     insns.push(TestUnit::new(
1636         Inst::FpuRR {
1637             frm: FRM::RTZ,
1638             width: FpuOPWidth::D,
1639             alu_op: FpuOPRR::Fclass,
1640             rd: writable_a0(),
1641             rs: fa1(),
1642         },
1643         "fclass.d a0,fa1",
1644         0xe2059553,
1645     ));
1646 
1647     insns.push(TestUnit::new(
1648         Inst::FpuRR {
1649             frm: FRM::Fcsr,
1650             width: FpuOPWidth::S,
1651             alu_op: FpuOPRR::FcvtSD,
1652             rd: writable_fa0(),
1653             rs: fa0(),
1654         },
1655         "fcvt.s.d fa0,fa0,fcsr",
1656         0x40157553,
1657     ));
1658     insns.push(TestUnit::new(
1659         Inst::FpuRR {
1660             frm: FRM::RNE,
1661             width: FpuOPWidth::D,
1662             alu_op: FpuOPRR::FcvtFmtWu,
1663             rd: writable_fa0(),
1664             rs: a0(),
1665         },
1666         "fcvt.d.wu fa0,a0,rne",
1667         0xd2150553,
1668     ));
1669 
1670     insns.push(TestUnit::new(
1671         Inst::FpuRR {
1672             frm: FRM::RNE,
1673             width: FpuOPWidth::D,
1674             alu_op: FpuOPRR::FmvFmtX,
1675             rd: writable_fa0(),
1676             rs: a0(),
1677         },
1678         "fmv.d.x fa0,a0",
1679         0xf2050553,
1680     ));
1681     insns.push(TestUnit::new(
1682         Inst::FpuRR {
1683             frm: FRM::Fcsr,
1684             width: FpuOPWidth::D,
1685             alu_op: FpuOPRR::FcvtLFmt,
1686             rd: writable_a0(),
1687             rs: fa0(),
1688         },
1689         "fcvt.l.d a0,fa0,fcsr",
1690         0xc2257553,
1691     ));
1692     insns.push(TestUnit::new(
1693         Inst::FpuRR {
1694             frm: FRM::Fcsr,
1695             width: FpuOPWidth::D,
1696             alu_op: FpuOPRR::FcvtLuFmt,
1697             rd: writable_a0(),
1698             rs: fa0(),
1699         },
1700         "fcvt.lu.d a0,fa0,fcsr",
1701         0xc2357553,
1702     ));
1703     insns.push(TestUnit::new(
1704         Inst::FpuRR {
1705             frm: FRM::Fcsr,
1706             width: FpuOPWidth::D,
1707             alu_op: FpuOPRR::FcvtFmtL,
1708             rd: writable_fa0(),
1709             rs: a0(),
1710         },
1711         "fcvt.d.l fa0,a0,fcsr",
1712         0xd2257553,
1713     ));
1714     insns.push(TestUnit::new(
1715         Inst::FpuRR {
1716             frm: FRM::Fcsr,
1717             width: FpuOPWidth::D,
1718             alu_op: FpuOPRR::FcvtFmtLu,
1719             rd: writable_fa0(),
1720             rs: a0(),
1721         },
1722         "fcvt.d.lu fa0,a0,fcsr",
1723         0xd2357553,
1724     ));
1725     //////////////////////
1726 
1727     insns.push(TestUnit::new(
1728         Inst::FpuRRRR {
1729             frm: FRM::RNE,
1730             width: FpuOPWidth::S,
1731             alu_op: FpuOPRRRR::Fmadd,
1732             rd: writable_fa0(),
1733             rs1: fa0(),
1734             rs2: fa1(),
1735             rs3: fa7(),
1736         },
1737         "fmadd.s fa0,fa0,fa1,fa7,rne",
1738         0x88b50543,
1739     ));
1740     insns.push(TestUnit::new(
1741         Inst::FpuRRRR {
1742             frm: FRM::Fcsr,
1743             width: FpuOPWidth::S,
1744             alu_op: FpuOPRRRR::Fmsub,
1745             rd: writable_fa0(),
1746             rs1: fa0(),
1747             rs2: fa1(),
1748             rs3: fa7(),
1749         },
1750         "fmsub.s fa0,fa0,fa1,fa7,fcsr",
1751         0x88b57547,
1752     ));
1753     insns.push(TestUnit::new(
1754         Inst::FpuRRRR {
1755             frm: FRM::Fcsr,
1756             width: FpuOPWidth::S,
1757             alu_op: FpuOPRRRR::Fnmsub,
1758             rd: writable_fa0(),
1759             rs1: fa0(),
1760             rs2: fa1(),
1761             rs3: fa7(),
1762         },
1763         "fnmsub.s fa0,fa0,fa1,fa7,fcsr",
1764         0x88b5754b,
1765     ));
1766     insns.push(TestUnit::new(
1767         Inst::FpuRRRR {
1768             frm: FRM::Fcsr,
1769             width: FpuOPWidth::S,
1770             alu_op: FpuOPRRRR::Fnmadd,
1771             rd: writable_fa0(),
1772             rs1: fa0(),
1773             rs2: fa1(),
1774             rs3: fa7(),
1775         },
1776         "fnmadd.s fa0,fa0,fa1,fa7,fcsr",
1777         0x88b5754f,
1778     ));
1779 
1780     insns.push(TestUnit::new(
1781         Inst::FpuRRRR {
1782             frm: FRM::Fcsr,
1783             width: FpuOPWidth::D,
1784             alu_op: FpuOPRRRR::Fmadd,
1785             rd: writable_fa0(),
1786             rs1: fa0(),
1787             rs2: fa1(),
1788             rs3: fa7(),
1789         },
1790         "fmadd.d fa0,fa0,fa1,fa7,fcsr",
1791         0x8ab57543,
1792     ));
1793     insns.push(TestUnit::new(
1794         Inst::FpuRRRR {
1795             frm: FRM::Fcsr,
1796             width: FpuOPWidth::D,
1797             alu_op: FpuOPRRRR::Fmsub,
1798             rd: writable_fa0(),
1799             rs1: fa0(),
1800             rs2: fa1(),
1801             rs3: fa7(),
1802         },
1803         "fmsub.d fa0,fa0,fa1,fa7,fcsr",
1804         0x8ab57547,
1805     ));
1806     insns.push(TestUnit::new(
1807         Inst::FpuRRRR {
1808             frm: FRM::Fcsr,
1809             width: FpuOPWidth::D,
1810             alu_op: FpuOPRRRR::Fnmsub,
1811             rd: writable_fa0(),
1812             rs1: fa0(),
1813             rs2: fa1(),
1814             rs3: fa7(),
1815         },
1816         "fnmsub.d fa0,fa0,fa1,fa7,fcsr",
1817         0x8ab5754b,
1818     ));
1819     insns.push(TestUnit::new(
1820         Inst::FpuRRRR {
1821             frm: FRM::Fcsr,
1822             width: FpuOPWidth::D,
1823             alu_op: FpuOPRRRR::Fnmadd,
1824             rd: writable_fa0(),
1825             rs1: fa0(),
1826             rs2: fa1(),
1827             rs3: fa7(),
1828         },
1829         "fnmadd.d fa0,fa0,fa1,fa7,fcsr",
1830         0x8ab5754f,
1831     ));
1832 
1833     insns.push(TestUnit::new(
1834         Inst::Atomic {
1835             op: AtomicOP::LrW,
1836             rd: writable_a0(),
1837             addr: a1(),
1838             src: zero_reg(),
1839             amo: AMO::Relax,
1840         },
1841         "lr.w a0,(a1)",
1842         0x1005a52f,
1843     ));
1844     insns.push(TestUnit::new(
1845         Inst::Atomic {
1846             op: AtomicOP::ScW,
1847             rd: writable_a0(),
1848             addr: a1(),
1849             src: a2(),
1850             amo: AMO::Release,
1851         },
1852         "sc.w.rl a0,a2,(a1)",
1853         0x1ac5a52f,
1854     ));
1855     insns.push(TestUnit::new(
1856         Inst::Atomic {
1857             op: AtomicOP::AmoswapW,
1858             rd: writable_a0(),
1859             addr: a1(),
1860             src: a2(),
1861             amo: AMO::Acquire,
1862         },
1863         "amoswap.w.aq a0,a2,(a1)",
1864         0xcc5a52f,
1865     ));
1866 
1867     insns.push(TestUnit::new(
1868         Inst::Atomic {
1869             op: AtomicOP::AmoaddW,
1870             rd: writable_a0(),
1871             addr: a1(),
1872             src: a2(),
1873             amo: AMO::SeqCst,
1874         },
1875         "amoadd.w.aqrl a0,a2,(a1)",
1876         0x6c5a52f,
1877     ));
1878     insns.push(TestUnit::new(
1879         Inst::Atomic {
1880             op: AtomicOP::AmoxorW,
1881             rd: writable_a0(),
1882             addr: a1(),
1883             src: a2(),
1884             amo: AMO::Relax,
1885         },
1886         "amoxor.w a0,a2,(a1)",
1887         0x20c5a52f,
1888     ));
1889     insns.push(TestUnit::new(
1890         Inst::Atomic {
1891             op: AtomicOP::AmoandW,
1892             rd: writable_a0(),
1893             addr: a1(),
1894             src: a2(),
1895             amo: AMO::Relax,
1896         },
1897         "amoand.w a0,a2,(a1)",
1898         0x60c5a52f,
1899     ));
1900 
1901     insns.push(TestUnit::new(
1902         Inst::Atomic {
1903             op: AtomicOP::AmoorW,
1904             rd: writable_a0(),
1905             addr: a1(),
1906             src: a2(),
1907             amo: AMO::Relax,
1908         },
1909         "amoor.w a0,a2,(a1)",
1910         0x40c5a52f,
1911     ));
1912     insns.push(TestUnit::new(
1913         Inst::Atomic {
1914             op: AtomicOP::AmominW,
1915             rd: writable_a0(),
1916             addr: a1(),
1917             src: a2(),
1918             amo: AMO::Relax,
1919         },
1920         "amomin.w a0,a2,(a1)",
1921         0x80c5a52f,
1922     ));
1923     insns.push(TestUnit::new(
1924         Inst::Atomic {
1925             op: AtomicOP::AmomaxW,
1926             rd: writable_a0(),
1927             addr: a1(),
1928             src: a2(),
1929             amo: AMO::Relax,
1930         },
1931         "amomax.w a0,a2,(a1)",
1932         0xa0c5a52f,
1933     ));
1934     insns.push(TestUnit::new(
1935         Inst::Atomic {
1936             op: AtomicOP::AmominuW,
1937             rd: writable_a0(),
1938             addr: a1(),
1939             src: a2(),
1940             amo: AMO::Relax,
1941         },
1942         "amominu.w a0,a2,(a1)",
1943         0xc0c5a52f,
1944     ));
1945     insns.push(TestUnit::new(
1946         Inst::Atomic {
1947             op: AtomicOP::AmomaxuW,
1948             rd: writable_a0(),
1949             addr: a1(),
1950             src: a2(),
1951             amo: AMO::Relax,
1952         },
1953         "amomaxu.w a0,a2,(a1)",
1954         0xe0c5a52f,
1955     ));
1956 
1957     insns.push(TestUnit::new(
1958         Inst::Atomic {
1959             op: AtomicOP::LrD,
1960             rd: writable_a0(),
1961             addr: a1(),
1962             src: zero_reg(),
1963             amo: AMO::Relax,
1964         },
1965         "lr.d a0,(a1)",
1966         0x1005b52f,
1967     ));
1968     insns.push(TestUnit::new(
1969         Inst::Atomic {
1970             op: AtomicOP::ScD,
1971             rd: writable_a0(),
1972             addr: a1(),
1973             src: a2(),
1974             amo: AMO::Relax,
1975         },
1976         "sc.d a0,a2,(a1)",
1977         0x18c5b52f,
1978     ));
1979 
1980     insns.push(TestUnit::new(
1981         Inst::Atomic {
1982             op: AtomicOP::AmoswapD,
1983             rd: writable_a0(),
1984             addr: a1(),
1985             src: a2(),
1986             amo: AMO::Relax,
1987         },
1988         "amoswap.d a0,a2,(a1)",
1989         0x8c5b52f,
1990     ));
1991 
1992     insns.push(TestUnit::new(
1993         Inst::Atomic {
1994             op: AtomicOP::AmoaddD,
1995             rd: writable_a0(),
1996             addr: a1(),
1997             src: a2(),
1998             amo: AMO::Relax,
1999         },
2000         "amoadd.d a0,a2,(a1)",
2001         0xc5b52f,
2002     ));
2003     insns.push(TestUnit::new(
2004         Inst::Atomic {
2005             op: AtomicOP::AmoxorD,
2006             rd: writable_a0(),
2007             addr: a1(),
2008             src: a2(),
2009             amo: AMO::Relax,
2010         },
2011         "amoxor.d a0,a2,(a1)",
2012         0x20c5b52f,
2013     ));
2014     insns.push(TestUnit::new(
2015         Inst::Atomic {
2016             op: AtomicOP::AmoandD,
2017             rd: writable_a0(),
2018             addr: a1(),
2019             src: a2(),
2020             amo: AMO::Relax,
2021         },
2022         "amoand.d a0,a2,(a1)",
2023         0x60c5b52f,
2024     ));
2025 
2026     insns.push(TestUnit::new(
2027         Inst::Atomic {
2028             op: AtomicOP::AmoorD,
2029             rd: writable_a0(),
2030             addr: a1(),
2031             src: a2(),
2032             amo: AMO::Relax,
2033         },
2034         "amoor.d a0,a2,(a1)",
2035         0x40c5b52f,
2036     ));
2037     insns.push(TestUnit::new(
2038         Inst::Atomic {
2039             op: AtomicOP::AmominD,
2040             rd: writable_a0(),
2041             addr: a1(),
2042             src: a2(),
2043             amo: AMO::Relax,
2044         },
2045         "amomin.d a0,a2,(a1)",
2046         0x80c5b52f,
2047     ));
2048     insns.push(TestUnit::new(
2049         Inst::Atomic {
2050             op: AtomicOP::AmomaxD,
2051             rd: writable_a0(),
2052             addr: a1(),
2053             src: a2(),
2054             amo: AMO::Relax,
2055         },
2056         "amomax.d a0,a2,(a1)",
2057         0xa0c5b52f,
2058     ));
2059     insns.push(TestUnit::new(
2060         Inst::Atomic {
2061             op: AtomicOP::AmominuD,
2062             rd: writable_a0(),
2063             addr: a1(),
2064             src: a2(),
2065             amo: AMO::Relax,
2066         },
2067         "amominu.d a0,a2,(a1)",
2068         0xc0c5b52f,
2069     ));
2070     insns.push(TestUnit::new(
2071         Inst::Atomic {
2072             op: AtomicOP::AmomaxuD,
2073             rd: writable_a0(),
2074             addr: a1(),
2075             src: a2(),
2076             amo: AMO::Relax,
2077         },
2078         "amomaxu.d a0,a2,(a1)",
2079         0xe0c5b52f,
2080     ));
2081 
2082     /////////
2083     insns.push(TestUnit::new(
2084         Inst::Fence {
2085             pred: 1,
2086             succ: 1 << 1,
2087         },
2088         "fence w,r",
2089         0x120000f,
2090     ));
2091     insns.push(TestUnit::new(Inst::EBreak {}, "ebreak", 0x100073));
2092 
2093     insns.push(TestUnit::new(
2094         Inst::FpuRRR {
2095             alu_op: FpuOPRRR::Fsgnj,
2096             width: FpuOPWidth::S,
2097             frm: FRM::RNE,
2098             rd: writable_fa0(),
2099             rs1: fa1(),
2100             rs2: fa1(),
2101         },
2102         "fmv.s fa0,fa1",
2103         0x20b58553,
2104     ));
2105     insns.push(TestUnit::new(
2106         Inst::FpuRRR {
2107             alu_op: FpuOPRRR::Fsgnj,
2108             width: FpuOPWidth::D,
2109             frm: FRM::RNE,
2110             rd: writable_fa0(),
2111             rs1: fa1(),
2112             rs2: fa1(),
2113         },
2114         "fmv.d fa0,fa1",
2115         0x22b58553,
2116     ));
2117 
2118     insns.push(TestUnit::new(
2119         Inst::FpuRRR {
2120             alu_op: FpuOPRRR::Fsgnjn,
2121             width: FpuOPWidth::S,
2122             frm: FRM::RTZ,
2123             rd: writable_fa0(),
2124             rs1: fa1(),
2125             rs2: fa1(),
2126         },
2127         "fneg.s fa0,fa1",
2128         0x20b59553,
2129     ));
2130     insns.push(TestUnit::new(
2131         Inst::FpuRRR {
2132             alu_op: FpuOPRRR::Fsgnjn,
2133             width: FpuOPWidth::D,
2134             frm: FRM::RTZ,
2135             rd: writable_fa0(),
2136             rs1: fa1(),
2137             rs2: fa1(),
2138         },
2139         "fneg.d fa0,fa1",
2140         0x22b59553,
2141     ));
2142 
2143     insns.push(TestUnit::new(
2144         Inst::Fli {
2145             width: FpuOPWidth::H,
2146             rd: writable_fa0(),
2147             imm: FliConstant::new(3),
2148         },
2149         "fli.h fa0,2^-15",
2150         0xf4118553,
2151     ));
2152 
2153     insns.push(TestUnit::new(
2154         Inst::Fli {
2155             width: FpuOPWidth::S,
2156             rd: writable_fa0(),
2157             imm: FliConstant::new(0),
2158         },
2159         "fli.s fa0,-1.0",
2160         0xf0100553,
2161     ));
2162 
2163     insns.push(TestUnit::new(
2164         Inst::Fli {
2165             width: FpuOPWidth::D,
2166             rd: writable_fa0(),
2167             imm: FliConstant::new(13),
2168         },
2169         "fli.d fa0,0.625",
2170         0xf2168553,
2171     ));
2172 
2173     let (flags, isa_flags) = make_test_flags();
2174     let emit_info = EmitInfo::new(flags, isa_flags);
2175 
2176     for unit in insns.iter() {
2177         println!("Riscv64: {:?}, {}", unit.inst, unit.assembly);
2178         // Check the printed text is as expected.
2179         let actual_printing = unit.inst.print_with_state(&mut EmitState::default());
2180         assert_eq!(unit.assembly, actual_printing);
2181         let mut buffer = MachBuffer::new();
2182         unit.inst
2183             .emit(&mut buffer, &emit_info, &mut Default::default());
2184         let buffer = buffer.finish(&Default::default(), &mut Default::default());
2185         let actual_encoding = buffer.stringify_code_bytes();
2186 
2187         assert_eq!(actual_encoding, unit.code.0);
2188     }
2189 }
2190 
make_test_flags() -> (settings::Flags, super::super::riscv_settings::Flags)2191 fn make_test_flags() -> (settings::Flags, super::super::riscv_settings::Flags) {
2192     let b = settings::builder();
2193     let flags = settings::Flags::new(b.clone());
2194     let b2 = super::super::riscv_settings::builder();
2195     let isa_flags = super::super::riscv_settings::Flags::new(&flags, &b2);
2196     (flags, isa_flags)
2197 }
2198 
2199 #[test]
riscv64_worst_case_instruction_size()2200 fn riscv64_worst_case_instruction_size() {
2201     let (flags, isa_flags) = make_test_flags();
2202     let emit_info = EmitInfo::new(flags, isa_flags);
2203 
2204     // These are all candidate instructions with potential to generate a lot of bytes.
2205     let mut candidates: Vec<MInst> = vec![];
2206 
2207     candidates.push(Inst::Popcnt {
2208         sum: writable_a0(),
2209         tmp: writable_a0(),
2210         step: writable_a0(),
2211         rs: a0(),
2212         ty: I64,
2213     });
2214 
2215     candidates.push(Inst::Cltz {
2216         sum: writable_a0(),
2217         tmp: writable_a0(),
2218         step: writable_a0(),
2219         rs: a0(),
2220         leading: true,
2221         ty: I64,
2222     });
2223 
2224     candidates.push(Inst::Brev8 {
2225         rd: writable_a0(),
2226         tmp: writable_a0(),
2227         step: writable_a0(),
2228         tmp2: writable_a0(),
2229         rs: a0(),
2230         ty: I64,
2231     });
2232 
2233     candidates.push(Inst::AtomicCas {
2234         offset: a0(),
2235         t0: writable_a0(),
2236         dst: writable_a0(),
2237         e: a0(),
2238         addr: a0(),
2239         v: a0(),
2240         ty: I64,
2241     });
2242 
2243     candidates.push(Inst::AtomicCas {
2244         offset: a0(),
2245         t0: writable_a0(),
2246         dst: writable_a0(),
2247         e: a0(),
2248         addr: a0(),
2249         v: a0(),
2250         ty: I16,
2251     });
2252 
2253     candidates.extend(
2254         crate::ir::AtomicRmwOp::all()
2255             .iter()
2256             .map(|op| Inst::AtomicRmwLoop {
2257                 op: *op,
2258                 offset: a0(),
2259                 dst: writable_a1(),
2260                 ty: I16,
2261                 p: a1(),
2262                 x: a2(),
2263                 t0: writable_a0(),
2264             }),
2265     );
2266 
2267     // Return Call Indirect and BrTable are the largest instructions possible. However they
2268     // emit their own island, so we don't account them here.
2269 
2270     let mut max: (u32, MInst) = (0, Inst::Nop0);
2271     for i in candidates {
2272         let mut buffer = MachBuffer::new();
2273         let mut emit_state = Default::default();
2274         i.emit(&mut buffer, &emit_info, &mut emit_state);
2275         let buffer = buffer.finish(&Default::default(), &mut Default::default());
2276         let length = buffer.data().len() as u32;
2277         if length > max.0 {
2278             let length = buffer.data().len() as u32;
2279             max = (length, i.clone());
2280         }
2281         println!("insn:{i:?}  length: {length}");
2282     }
2283     println!("calculate max size is {} , inst is {:?}", max.0, max.1);
2284     assert!(max.0 <= Inst::worst_case_size());
2285 }
2286