1 // See LICENSE for license details.
2 
3 #include "disasm.h"
4 #include <cassert>
5 #include <string>
6 #include <vector>
7 #include <cstdarg>
8 #include <sstream>
9 #include <stdlib.h>
10 
11 // Indicates that the next arg (only) is optional.
12 // If the result of converting the next arg to a string is ""
13 // then it will not be printed.
14 static const arg_t* opt = nullptr;
15 
16 struct : public arg_t {
to_string__anoncb812a75010817   std::string to_string(insn_t insn) const {
18     return std::to_string((int)insn.i_imm()) + '(' + xpr_name[insn.rs1()] + ')';
19   }
20 } load_address;
21 
22 struct : public arg_t {
to_string__anoncb812a75020823   std::string to_string(insn_t insn) const {
24     return std::to_string((int)insn.s_imm()) + '(' + xpr_name[insn.rs1()] + ')';
25   }
26 } store_address;
27 
28 struct : public arg_t {
to_string__anoncb812a75030829   std::string to_string(insn_t insn) const {
30     return std::string("(") + xpr_name[insn.rs1()] + ')';
31   }
32 } base_only_address;
33 
34 struct : public arg_t {
to_string__anoncb812a75040835   std::string to_string(insn_t insn) const {
36     return xpr_name[insn.rd()];
37   }
38 } xrd;
39 
40 struct : public arg_t {
to_string__anoncb812a75050841   std::string to_string(insn_t insn) const {
42     return xpr_name[insn.rs1()];
43   }
44 } xrs1;
45 
46 struct : public arg_t {
to_string__anoncb812a75060847   std::string to_string(insn_t insn) const {
48     return xpr_name[insn.rs2()];
49   }
50 } xrs2;
51 
52 struct : public arg_t {
to_string__anoncb812a75070853   std::string to_string(insn_t insn) const {
54     return xpr_name[insn.rs3()];
55   }
56 } xrs3;
57 
58 struct : public arg_t {
to_string__anoncb812a75080859   std::string to_string(insn_t insn) const {
60     return fpr_name[insn.rd()];
61   }
62 } frd;
63 
64 struct : public arg_t {
to_string__anoncb812a75090865   std::string to_string(insn_t insn) const {
66     return fpr_name[insn.rs1()];
67   }
68 } frs1;
69 
70 struct : public arg_t {
to_string__anoncb812a750a0871   std::string to_string(insn_t insn) const {
72     return fpr_name[insn.rs2()];
73   }
74 } frs2;
75 
76 struct : public arg_t {
to_string__anoncb812a750b0877   std::string to_string(insn_t insn) const {
78     return fpr_name[insn.rs3()];
79   }
80 } frs3;
81 
82 struct : public arg_t {
to_string__anoncb812a750c0883   std::string to_string(insn_t insn) const {
84     switch (insn.csr())
85     {
86       #define DECLARE_CSR(name, num) case num: return #name;
87       #include "encoding.h"
88       #undef DECLARE_CSR
89       default:
90       {
91         char buf[16];
92         snprintf(buf, sizeof buf, "unknown_%03" PRIx64, insn.csr());
93         return std::string(buf);
94       }
95     }
96   }
97 } csr;
98 
99 struct : public arg_t {
to_string__anoncb812a750d08100   std::string to_string(insn_t insn) const {
101     return std::to_string((int)insn.i_imm());
102   }
103 } imm;
104 
105 struct : public arg_t {
to_string__anoncb812a750e08106   std::string to_string(insn_t insn) const {
107     return std::to_string((int)insn.shamt());
108   }
109 } shamt;
110 
111 struct : public arg_t {
to_string__anoncb812a750f08112   std::string to_string(insn_t insn) const {
113     std::stringstream s;
114     s << std::hex << "0x" << ((uint32_t)insn.u_imm() >> 12);
115     return s.str();
116   }
117 } bigimm;
118 
119 struct : public arg_t {
to_string__anoncb812a751008120   std::string to_string(insn_t insn) const {
121     return std::to_string(insn.rs1());
122   }
123 } zimm5;
124 
125 struct : public arg_t {
to_string__anoncb812a751108126   std::string to_string(insn_t insn) const {
127     std::stringstream s;
128     int32_t target = insn.sb_imm();
129     char sign = target >= 0 ? '+' : '-';
130     s << "pc " << sign << ' ' << abs(target);
131     return s.str();
132   }
133 } branch_target;
134 
135 struct : public arg_t {
to_string__anoncb812a751208136   std::string to_string(insn_t insn) const {
137     std::stringstream s;
138     int32_t target = insn.uj_imm();
139     char sign = target >= 0 ? '+' : '-';
140     s << "pc " << sign << std::hex << " 0x" << abs(target);
141     return s.str();
142   }
143 } jump_target;
144 
145 struct : public arg_t {
to_string__anoncb812a751308146   std::string to_string(insn_t insn) const {
147     return xpr_name[insn.rvc_rs1()];
148   }
149 } rvc_rs1;
150 
151 struct : public arg_t {
to_string__anoncb812a751408152   std::string to_string(insn_t insn) const {
153     return xpr_name[insn.rvc_rs2()];
154   }
155 } rvc_rs2;
156 
157 struct : public arg_t {
to_string__anoncb812a751508158   std::string to_string(insn_t insn) const {
159     return fpr_name[insn.rvc_rs2()];
160   }
161 } rvc_fp_rs2;
162 
163 struct : public arg_t {
to_string__anoncb812a751608164   std::string to_string(insn_t insn) const {
165     return xpr_name[insn.rvc_rs1s()];
166   }
167 } rvc_rs1s;
168 
169 struct : public arg_t {
to_string__anoncb812a751708170   std::string to_string(insn_t insn) const {
171     return xpr_name[insn.rvc_rs2s()];
172   }
173 } rvc_rs2s;
174 
175 struct : public arg_t {
to_string__anoncb812a751808176   std::string to_string(insn_t insn) const {
177     return fpr_name[insn.rvc_rs2s()];
178   }
179 } rvc_fp_rs2s;
180 
181 struct : public arg_t {
to_string__anoncb812a751908182   std::string to_string(insn_t insn) const {
183     return xpr_name[X_SP];
184   }
185 } rvc_sp;
186 
187 struct : public arg_t {
to_string__anoncb812a751a08188   std::string to_string(insn_t insn) const {
189     return std::to_string((int)insn.rvc_imm());
190   }
191 } rvc_imm;
192 
193 struct : public arg_t {
to_string__anoncb812a751b08194   std::string to_string(insn_t insn) const {
195     return std::to_string((int)insn.rvc_addi4spn_imm());
196   }
197 } rvc_addi4spn_imm;
198 
199 struct : public arg_t {
to_string__anoncb812a751c08200   std::string to_string(insn_t insn) const {
201     return std::to_string((int)insn.rvc_addi16sp_imm());
202   }
203 } rvc_addi16sp_imm;
204 
205 struct : public arg_t {
to_string__anoncb812a751d08206   std::string to_string(insn_t insn) const {
207     return std::to_string((int)insn.rvc_lwsp_imm());
208   }
209 } rvc_lwsp_imm;
210 
211 struct : public arg_t {
to_string__anoncb812a751e08212   std::string to_string(insn_t insn) const {
213     return std::to_string((int)(insn.rvc_imm() & 0x3f));
214   }
215 } rvc_shamt;
216 
217 struct : public arg_t {
to_string__anoncb812a751f08218   std::string to_string(insn_t insn) const {
219     std::stringstream s;
220     s << std::hex << "0x" << ((uint32_t)insn.rvc_imm() << 12 >> 12);
221     return s.str();
222   }
223 } rvc_uimm;
224 
225 struct : public arg_t {
to_string__anoncb812a752008226   std::string to_string(insn_t insn) const {
227     return std::to_string((int)insn.rvc_lwsp_imm()) + '(' + xpr_name[X_SP] + ')';
228   }
229 } rvc_lwsp_address;
230 
231 struct : public arg_t {
to_string__anoncb812a752108232   std::string to_string(insn_t insn) const {
233     return std::to_string((int)insn.rvc_ldsp_imm()) + '(' + xpr_name[X_SP] + ')';
234   }
235 } rvc_ldsp_address;
236 
237 struct : public arg_t {
to_string__anoncb812a752208238   std::string to_string(insn_t insn) const {
239     return std::to_string((int)insn.rvc_swsp_imm()) + '(' + xpr_name[X_SP] + ')';
240   }
241 } rvc_swsp_address;
242 
243 struct : public arg_t {
to_string__anoncb812a752308244   std::string to_string(insn_t insn) const {
245     return std::to_string((int)insn.rvc_sdsp_imm()) + '(' + xpr_name[X_SP] + ')';
246   }
247 } rvc_sdsp_address;
248 
249 struct : public arg_t {
to_string__anoncb812a752408250   std::string to_string(insn_t insn) const {
251     return std::to_string((int)insn.rvc_lw_imm()) + '(' + xpr_name[insn.rvc_rs1s()] + ')';
252   }
253 } rvc_lw_address;
254 
255 struct : public arg_t {
to_string__anoncb812a752508256   std::string to_string(insn_t insn) const {
257     return std::to_string((int)insn.rvc_ld_imm()) + '(' + xpr_name[insn.rvc_rs1s()] + ')';
258   }
259 } rvc_ld_address;
260 
261 struct : public arg_t {
to_string__anoncb812a752608262   std::string to_string(insn_t insn) const {
263     std::stringstream s;
264     int32_t target = insn.rvc_b_imm();
265     char sign = target >= 0 ? '+' : '-';
266     s << "pc " << sign << ' ' << abs(target);
267     return s.str();
268   }
269 } rvc_branch_target;
270 
271 struct : public arg_t {
to_string__anoncb812a752708272   std::string to_string(insn_t insn) const {
273     std::stringstream s;
274     int32_t target = insn.rvc_j_imm();
275     char sign = target >= 0 ? '+' : '-';
276     s << "pc " << sign << ' ' << abs(target);
277     return s.str();
278   }
279 } rvc_jump_target;
280 
281 struct : public arg_t {
to_string__anoncb812a752808282   std::string to_string(insn_t insn) const {
283     return std::string("(") + xpr_name[insn.rs1()] + ')';
284   }
285 } v_address;
286 
287 struct : public arg_t {
to_string__anoncb812a752908288   std::string to_string(insn_t insn) const {
289     return vr_name[insn.rd()];
290   }
291 } vd;
292 
293 struct : public arg_t {
to_string__anoncb812a752a08294   std::string to_string(insn_t insn) const {
295     return vr_name[insn.rs1()];
296   }
297 } vs1;
298 
299 struct : public arg_t {
to_string__anoncb812a752b08300   std::string to_string(insn_t insn) const {
301     return vr_name[insn.rs2()];
302   }
303 } vs2;
304 
305 struct : public arg_t {
to_string__anoncb812a752c08306   std::string to_string(insn_t insn) const {
307     return vr_name[insn.rd()];
308   }
309 } vs3;
310 
311 struct : public arg_t {
to_string__anoncb812a752d08312   std::string to_string(insn_t insn) const {
313     return insn.v_vm() ? "" : "v0.t";
314   }
315 } vm;
316 
317 struct : public arg_t {
to_string__anoncb812a752e08318   std::string to_string(insn_t insn) const {
319     return "v0";
320   }
321 } v0;
322 
323 struct : public arg_t {
to_string__anoncb812a752f08324   std::string to_string(insn_t insn) const {
325     return std::to_string((int)insn.v_simm5());
326   }
327 } v_simm5;
328 
329 struct : public arg_t {
to_string__anoncb812a753008330   std::string to_string(insn_t insn) const {
331     std::stringstream s;
332     int sew = insn.v_sew();
333     int lmul = insn.v_lmul();
334     auto vta = insn.v_vta() == 1 ? "ta" : "tu";
335     auto vma = insn.v_vma() == 1 ? "ma" : "mu";
336     s << "e" << sew;
337     if(insn.v_frac_lmul()) {
338       std::string lmul_str = "";
339       switch(lmul){
340         case 3:
341           lmul_str = "f2";
342           break;
343         case 2:
344           lmul_str = "f4";
345           break;
346         case 1:
347           lmul_str = "f8";
348           break;
349         default:
350           assert(true && "unsupport fractional LMUL");
351       }
352       s << ", m" << lmul_str;
353     } else {
354       s << ", m" << (1 << lmul);
355     }
356     s << ", " << vta << ", " << vma;
357     return s.str();
358   }
359 } v_vtype;
360 
361 struct : public arg_t {
to_string__anoncb812a753108362   std::string to_string(insn_t insn) const {
363     return "x0";
364   }
365 } x0;
366 
367 struct : public arg_t {
to_string__anoncb812a753208368   std::string to_string(insn_t insn) const {
369     std::stringstream s;
370     auto iorw = insn.iorw();
371     bool has_pre = false;
372     static const char type[] = "wroi";
373     for (int i = 7; i >= 4; --i) {
374       if (iorw & (1ul << i)) {
375         s << type[i - 4];
376         has_pre = true;
377       }
378     }
379 
380     s << (has_pre ? "," : "");
381     for (int i = 3; i >= 0; --i) {
382       if (iorw & (1ul << i)) {
383         s << type[i];
384       }
385     }
386 
387     return s.str();
388   }
389 } iorw;
390 
391 struct : public arg_t {
to_string__anoncb812a753308392   std::string to_string(insn_t insn) const {
393     return std::to_string((int)insn.p_imm2());
394   }
395 } p_imm2;
396 
397 struct : public arg_t {
to_string__anoncb812a753408398   std::string to_string(insn_t insn) const {
399     return std::to_string((int)insn.p_imm3());
400   }
401 } p_imm3;
402 
403 struct : public arg_t {
to_string__anoncb812a753508404   std::string to_string(insn_t insn) const {
405     return std::to_string((int)insn.p_imm4());
406   }
407 } p_imm4;
408 
409 struct : public arg_t {
to_string__anoncb812a753608410   std::string to_string(insn_t insn) const {
411     return std::to_string((int)insn.p_imm5());
412   }
413 } p_imm5;
414 
415 struct : public arg_t {
to_string__anoncb812a753708416   std::string to_string(insn_t insn) const {
417     return std::to_string((int)insn.p_imm6());
418   }
419 } p_imm6;
420 
421 typedef struct {
422   reg_t match;
423   reg_t mask;
424   const char *fmt;
425   std::vector<const arg_t*>& arg;
426 } custom_fmt_t;
427 
disassemble(insn_t insn) const428 std::string disassembler_t::disassemble(insn_t insn) const
429 {
430   const disasm_insn_t* disasm_insn = lookup(insn);
431   return disasm_insn ? disasm_insn->to_string(insn) : "unknown";
432 }
433 
add_noarg_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)434 static void NOINLINE add_noarg_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
435 {
436   d->add_insn(new disasm_insn_t(name, match, mask, {}));
437 }
438 
add_rtype_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)439 static void NOINLINE add_rtype_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
440 {
441   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &xrs2}));
442 }
443 
add_r1type_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)444 static void NOINLINE add_r1type_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
445 {
446   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1}));
447 }
448 
add_r3type_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)449 static void NOINLINE add_r3type_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
450 {
451   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &xrs2, &xrs3}));
452 }
453 
add_itype_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)454 static void NOINLINE add_itype_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
455 {
456   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &imm}));
457 }
458 
add_itype_shift_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)459 static void NOINLINE add_itype_shift_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
460 {
461   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &shamt}));
462 }
463 
add_xload_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)464 static void NOINLINE add_xload_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
465 {
466   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &load_address}));
467 }
468 
add_xstore_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)469 static void NOINLINE add_xstore_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
470 {
471   d->add_insn(new disasm_insn_t(name, match, mask, {&xrs2, &store_address}));
472 }
473 
add_fload_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)474 static void NOINLINE add_fload_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
475 {
476   d->add_insn(new disasm_insn_t(name, match, mask, {&frd, &load_address}));
477 }
478 
add_fstore_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)479 static void NOINLINE add_fstore_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
480 {
481   d->add_insn(new disasm_insn_t(name, match, mask, {&frs2, &store_address}));
482 }
483 
add_xamo_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)484 static void NOINLINE add_xamo_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
485 {
486   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs2, &base_only_address}));
487 }
488 
add_xlr_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)489 static void NOINLINE add_xlr_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
490 {
491   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &base_only_address}));
492 }
493 
add_xst_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)494 static void NOINLINE add_xst_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
495 {
496   d->add_insn(new disasm_insn_t(name, match, mask, {&xrs2, &base_only_address}));
497 }
498 
add_btype_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)499 static void NOINLINE add_btype_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
500 {
501   d->add_insn(new disasm_insn_t(name, match, mask, {&xrs1, &xrs2, &branch_target}));
502 }
503 
add_b1type_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)504 static void NOINLINE add_b1type_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
505 {
506   const uint32_t mask_rs2 = 0x1fUL << 20;
507   d->add_insn(new disasm_insn_t(name, match, mask | mask_rs2, {&xrs1, &branch_target}));
508 }
509 
add_frtype_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)510 static void NOINLINE add_frtype_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
511 {
512   d->add_insn(new disasm_insn_t(name, match, mask, {&frd, &frs1, &frs2}));
513 }
514 
add_fr1type_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)515 static void NOINLINE add_fr1type_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
516 {
517   d->add_insn(new disasm_insn_t(name, match, mask, {&frd, &frs1}));
518 }
519 
add_fr3type_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)520 static void NOINLINE add_fr3type_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
521 {
522   d->add_insn(new disasm_insn_t(name, match, mask, {&frd, &frs1, &frs2, &frs3}));
523 }
524 
add_fxtype_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)525 static void NOINLINE add_fxtype_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
526 {
527   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &frs1}));
528 }
529 
add_xftype_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)530 static void NOINLINE add_xftype_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
531 {
532   d->add_insn(new disasm_insn_t(name, match, mask, {&frd, &xrs1}));
533 }
534 
add_fx2type_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)535 static void NOINLINE add_fx2type_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
536 {
537   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &frs1, &frs2}));
538 }
539 
add_sfence_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)540 static void NOINLINE add_sfence_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
541 {
542   d->add_insn(new disasm_insn_t(name, match, mask, {&xrs1, &xrs2}));
543 }
544 
add_pitype3_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)545 static void NOINLINE add_pitype3_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
546 {
547   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &p_imm3}));
548 }
549 
add_pitype4_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)550 static void NOINLINE add_pitype4_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
551 {
552   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &p_imm4}));
553 }
554 
add_pitype5_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)555 static void NOINLINE add_pitype5_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
556 {
557   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &p_imm5}));
558 }
559 
add_pitype6_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)560 static void NOINLINE add_pitype6_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
561 {
562   d->add_insn(new disasm_insn_t(name, match, mask, {&xrd, &xrs1, &p_imm6}));
563 }
564 
add_vector_v_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)565 static void NOINLINE add_vector_v_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
566 {
567   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, opt, &vm}));
568 }
569 
add_vector_vv_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)570 static void NOINLINE add_vector_vv_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
571 {
572   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &vs1, opt, &vm}));
573 }
574 
add_vector_vx_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)575 static void NOINLINE add_vector_vx_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
576 {
577   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &xrs1, opt, &vm}));
578 }
579 
add_vector_vf_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)580 static void NOINLINE add_vector_vf_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
581 {
582   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &frs1, opt, &vm}));
583 }
584 
add_vector_vi_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)585 static void NOINLINE add_vector_vi_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
586 {
587   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &v_simm5, opt, &vm}));
588 }
589 
add_vector_viu_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)590 static void NOINLINE add_vector_viu_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
591 {
592   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &zimm5, opt, &vm}));
593 }
594 
add_vector_vvm_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)595 static void NOINLINE add_vector_vvm_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
596 {
597   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &vs1, &v0}));
598 }
599 
add_vector_vxm_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)600 static void NOINLINE add_vector_vxm_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
601 {
602   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &xrs1, &v0}));
603 }
604 
add_vector_vim_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)605 static void NOINLINE add_vector_vim_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
606 {
607   d->add_insn(new disasm_insn_t(name, match, mask, {&vd, &vs2, &v_simm5, &v0}));
608 }
609 
add_unknown_insn(disassembler_t * d,const char * name,uint32_t match,uint32_t mask)610 static void NOINLINE add_unknown_insn(disassembler_t* d, const char* name, uint32_t match, uint32_t mask)
611 {
612   std::string s = name;
613   s += " (args unknown)";
614 
615   d->add_insn(new disasm_insn_t(s.c_str(), match, mask, {}));
616 }
617 
618 
add_unknown_insns(disassembler_t * d)619 static void NOINLINE add_unknown_insns(disassembler_t* d)
620 {
621   // provide a default disassembly for all instructions as a fallback
622   #define DECLARE_INSN(code, match, mask) \
623    add_unknown_insn(d, #code, match, mask);
624   #include "encoding.h"
625   #undef DECLARE_INSN
626 }
627 
disassembler_t(int xlen)628 disassembler_t::disassembler_t(int xlen)
629 {
630   const uint32_t mask_rd = 0x1fUL << 7;
631   const uint32_t match_rd_ra = 1UL << 7;
632   const uint32_t mask_rs1 = 0x1fUL << 15;
633   const uint32_t match_rs1_ra = 1UL << 15;
634   const uint32_t mask_rs2 = 0x1fUL << 20;
635   const uint32_t mask_imm = 0xfffUL << 20;
636   const uint32_t imm_shift = 20;
637   const uint32_t mask_rvc_rs2 = 0x1fUL << 2;
638   const uint32_t mask_rvc_imm = mask_rvc_rs2 | 0x1000UL;
639   const uint32_t mask_nf = 0x7Ul << 29;
640   const uint32_t mask_wd = 0x1Ul << 26;
641   const uint32_t mask_vm = 0x1Ul << 25;
642   const uint32_t mask_vldst = 0x7Ul << 12 | 0x1UL << 28;
643   const uint32_t mask_amoop = 0x1fUl << 27;
644   const uint32_t mask_width = 0x7Ul << 12;
645 
646   #define DECLARE_INSN(code, match, mask) \
647    const uint32_t match_##code = match; \
648    const uint32_t mask_##code = mask;
649   #include "encoding.h"
650   #undef DECLARE_INSN
651 
652   // explicit per-instruction disassembly
653   #define DISASM_INSN(name, code, extra, ...) \
654     add_insn(new disasm_insn_t(name, match_##code, mask_##code | (extra), __VA_ARGS__));
655   #define DEFINE_NOARG(code) add_noarg_insn(this, #code, match_##code, mask_##code);
656   #define DEFINE_RTYPE(code) add_rtype_insn(this, #code, match_##code, mask_##code);
657   #define DEFINE_R1TYPE(code) add_r1type_insn(this, #code, match_##code, mask_##code);
658   #define DEFINE_R3TYPE(code) add_r3type_insn(this, #code, match_##code, mask_##code);
659   #define DEFINE_ITYPE(code) add_itype_insn(this, #code, match_##code, mask_##code);
660   #define DEFINE_ITYPE_SHIFT(code) add_itype_shift_insn(this, #code, match_##code, mask_##code);
661   #define DEFINE_I0TYPE(name, code) DISASM_INSN(name, code, mask_rs1, {&xrd, &imm})
662   #define DEFINE_I1TYPE(name, code) DISASM_INSN(name, code, mask_imm, {&xrd, &xrs1})
663   #define DEFINE_I2TYPE(name, code) DISASM_INSN(name, code, mask_rd | mask_imm, {&xrs1})
664   #define DEFINE_LTYPE(code) DISASM_INSN(#code, code, 0, {&xrd, &bigimm})
665   #define DEFINE_BTYPE(code) add_btype_insn(this, #code, match_##code, mask_##code);
666   #define DEFINE_B1TYPE(name, code) add_b1type_insn(this, name, match_##code, mask_##code);
667   #define DEFINE_XLOAD(code) add_xload_insn(this, #code, match_##code, mask_##code);
668   #define DEFINE_XSTORE(code) add_xstore_insn(this, #code, match_##code, mask_##code);
669   #define DEFINE_XAMO(code) add_xamo_insn(this, #code, match_##code, mask_##code);
670   #define DEFINE_XLOAD_BASE(code) add_xlr_insn(this, #code, match_##code, mask_##code);
671   #define DEFINE_XSTORE_BASE(code) add_xst_insn(this, #code, match_##code, mask_##code);
672   #define DEFINE_FLOAD(code) add_fload_insn(this, #code, match_##code, mask_##code);
673   #define DEFINE_FSTORE(code) add_fstore_insn(this, #code, match_##code, mask_##code);
674   #define DEFINE_FRTYPE(code) add_frtype_insn(this, #code, match_##code, mask_##code);
675   #define DEFINE_FR1TYPE(code) add_fr1type_insn(this, #code, match_##code, mask_##code);
676   #define DEFINE_FR3TYPE(code) add_fr3type_insn(this, #code, match_##code, mask_##code);
677   #define DEFINE_FXTYPE(code) add_fxtype_insn(this, #code, match_##code, mask_##code);
678   #define DEFINE_FX2TYPE(code) add_fx2type_insn(this, #code, match_##code, mask_##code);
679   #define DEFINE_XFTYPE(code) add_xftype_insn(this, #code, match_##code, mask_##code);
680   #define DEFINE_SFENCE_TYPE(code) add_sfence_insn(this, #code, match_##code, mask_##code);
681 
682   DEFINE_XLOAD(lb)
683   DEFINE_XLOAD(lbu)
684   DEFINE_XLOAD(lh)
685   DEFINE_XLOAD(lhu)
686   DEFINE_XLOAD(lw)
687   DEFINE_XLOAD(lwu)
688   DEFINE_XLOAD(ld)
689 
690   DEFINE_XSTORE(sb)
691   DEFINE_XSTORE(sh)
692   DEFINE_XSTORE(sw)
693   DEFINE_XSTORE(sd)
694 
695   DEFINE_XAMO(amoadd_w)
696   DEFINE_XAMO(amoswap_w)
697   DEFINE_XAMO(amoand_w)
698   DEFINE_XAMO(amoor_w)
699   DEFINE_XAMO(amoxor_w)
700   DEFINE_XAMO(amomin_w)
701   DEFINE_XAMO(amomax_w)
702   DEFINE_XAMO(amominu_w)
703   DEFINE_XAMO(amomaxu_w)
704   DEFINE_XAMO(amoadd_d)
705   DEFINE_XAMO(amoswap_d)
706   DEFINE_XAMO(amoand_d)
707   DEFINE_XAMO(amoor_d)
708   DEFINE_XAMO(amoxor_d)
709   DEFINE_XAMO(amomin_d)
710   DEFINE_XAMO(amomax_d)
711   DEFINE_XAMO(amominu_d)
712   DEFINE_XAMO(amomaxu_d)
713 
714   DEFINE_XLOAD_BASE(lr_w)
715   DEFINE_XAMO(sc_w)
716   DEFINE_XLOAD_BASE(lr_d)
717   DEFINE_XAMO(sc_d)
718 
719   DEFINE_FLOAD(flw)
720   DEFINE_FLOAD(fld)
721   DEFINE_FLOAD(flh)
722   DEFINE_FLOAD(flq)
723 
724   DEFINE_FSTORE(fsw)
725   DEFINE_FSTORE(fsd)
726   DEFINE_FSTORE(fsh)
727   DEFINE_FSTORE(fsq)
728 
729   add_insn(new disasm_insn_t("j", match_jal, mask_jal | mask_rd, {&jump_target}));
730   add_insn(new disasm_insn_t("jal", match_jal | match_rd_ra, mask_jal | mask_rd, {&jump_target}));
731   add_insn(new disasm_insn_t("jal", match_jal, mask_jal, {&xrd, &jump_target}));
732 
733   DEFINE_B1TYPE("beqz", beq);
734   DEFINE_B1TYPE("bnez", bne);
735   DEFINE_B1TYPE("bltz", blt);
736   DEFINE_B1TYPE("bgez", bge);
737   DEFINE_BTYPE(beq)
738   DEFINE_BTYPE(bne)
739   DEFINE_BTYPE(blt)
740   DEFINE_BTYPE(bge)
741   DEFINE_BTYPE(bltu)
742   DEFINE_BTYPE(bgeu)
743 
744   DEFINE_LTYPE(lui);
745   DEFINE_LTYPE(auipc);
746 
747   add_insn(new disasm_insn_t("ret", match_jalr | match_rs1_ra, mask_jalr | mask_rd | mask_rs1 | mask_imm, {}));
748   DEFINE_I2TYPE("jr", jalr);
749   add_insn(new disasm_insn_t("jalr", match_jalr | match_rd_ra, mask_jalr | mask_rd | mask_imm, {&xrs1}));
750   DEFINE_ITYPE(jalr);
751 
752   add_noarg_insn(this, "nop", match_addi, mask_addi | mask_rd | mask_rs1 | mask_imm);
753   DEFINE_I0TYPE("li", addi);
754   DEFINE_I1TYPE("mv", addi);
755   DEFINE_ITYPE(addi);
756   DEFINE_ITYPE(slti);
757   add_insn(new disasm_insn_t("seqz", match_sltiu | (1 << imm_shift), mask_sltiu | mask_imm, {&xrd, &xrs1}));
758   DEFINE_ITYPE(sltiu);
759   add_insn(new disasm_insn_t("not", match_xori | mask_imm, mask_xori | mask_imm, {&xrd, &xrs1}));
760   DEFINE_ITYPE(xori);
761 
762   DEFINE_ITYPE_SHIFT(slli);
763   DEFINE_ITYPE_SHIFT(srli);
764   DEFINE_ITYPE_SHIFT(srai);
765 
766   DEFINE_ITYPE(ori);
767   DEFINE_ITYPE(andi);
768   DEFINE_I1TYPE("sext.w", addiw);
769   DEFINE_ITYPE(addiw);
770 
771   DEFINE_ITYPE_SHIFT(slliw);
772   DEFINE_ITYPE_SHIFT(srliw);
773   DEFINE_ITYPE_SHIFT(sraiw);
774 
775   DEFINE_RTYPE(add);
776   DEFINE_RTYPE(sub);
777   DEFINE_RTYPE(sll);
778   DEFINE_RTYPE(slt);
779   add_insn(new disasm_insn_t("snez", match_sltu, mask_sltu | mask_rs1, {&xrd, &xrs2}));
780   DEFINE_RTYPE(sltu);
781   DEFINE_RTYPE(xor);
782   DEFINE_RTYPE(srl);
783   DEFINE_RTYPE(sra);
784   DEFINE_RTYPE(or);
785   DEFINE_RTYPE(and);
786   DEFINE_RTYPE(mul);
787   DEFINE_RTYPE(mulh);
788   DEFINE_RTYPE(mulhu);
789   DEFINE_RTYPE(mulhsu);
790   DEFINE_RTYPE(div);
791   DEFINE_RTYPE(divu);
792   DEFINE_RTYPE(rem);
793   DEFINE_RTYPE(remu);
794   DEFINE_RTYPE(addw);
795   DEFINE_RTYPE(subw);
796   DEFINE_RTYPE(sllw);
797   DEFINE_RTYPE(srlw);
798   DEFINE_RTYPE(sraw);
799   DEFINE_RTYPE(mulw);
800   DEFINE_RTYPE(divw);
801   DEFINE_RTYPE(divuw);
802   DEFINE_RTYPE(remw);
803   DEFINE_RTYPE(remuw);
804 
805   DEFINE_ITYPE_SHIFT(slli_uw);
806   add_insn(new disasm_insn_t("zext.w", match_add_uw, mask_add_uw | mask_rs2, {&xrd, &xrs1}));
807   DEFINE_RTYPE(add_uw);
808   DEFINE_RTYPE(sh1add);
809   DEFINE_RTYPE(sh2add);
810   DEFINE_RTYPE(sh3add);
811   DEFINE_RTYPE(sh1add_uw);
812   DEFINE_RTYPE(sh2add_uw);
813   DEFINE_RTYPE(sh3add_uw);
814   DEFINE_RTYPE(ror);
815   DEFINE_RTYPE(rorw);
816   DEFINE_RTYPE(rol);
817   DEFINE_RTYPE(rolw);
818   DEFINE_ITYPE_SHIFT(rori);
819   DEFINE_ITYPE_SHIFT(roriw);
820   DEFINE_R1TYPE(ctz);
821   DEFINE_R1TYPE(ctzw);
822   DEFINE_R1TYPE(clz);
823   DEFINE_R1TYPE(clzw);
824   DEFINE_R1TYPE(cpop);
825   DEFINE_R1TYPE(cpopw);
826   DEFINE_RTYPE(min);
827   DEFINE_RTYPE(minu);
828   DEFINE_RTYPE(max);
829   DEFINE_RTYPE(maxu);
830   DEFINE_RTYPE(andn);
831   DEFINE_RTYPE(orn);
832   DEFINE_RTYPE(xnor);
833   DEFINE_R1TYPE(sext_b);
834   DEFINE_R1TYPE(sext_h);
835   add_insn(new disasm_insn_t("zext.h", (xlen == 32 ? match_pack : match_packw), mask_pack | mask_rs2, {&xrd, &xrs1}));
836   DEFINE_RTYPE(pack);
837   DEFINE_RTYPE(packu);
838   DEFINE_RTYPE(packw);
839   DEFINE_RTYPE(grev);
840   add_insn(new disasm_insn_t("rev", match_grevi | ((xlen - 1) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1}));
841   add_insn(new disasm_insn_t("rev8", match_grevi | ((xlen - 8) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1}));
842   add_insn(new disasm_insn_t("rev.b", match_grevi | (0x7 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); // brev8
843   add_insn(new disasm_insn_t("rev8.h", match_grevi | (0x8 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); // swap16
844   DEFINE_ITYPE_SHIFT(grevi);
845   DEFINE_RTYPE(gorc);
846   add_insn(new disasm_insn_t("orc.b", match_gorci | (0x7 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1}));
847   DEFINE_ITYPE_SHIFT(gorci);
848   DEFINE_RTYPE(xperm_n);
849   DEFINE_RTYPE(xperm_b);
850   DEFINE_RTYPE(xperm_h);
851   DEFINE_RTYPE(xperm_w);
852 
853   DEFINE_R3TYPE(cmix);
854   DEFINE_R3TYPE(fsr);
855   DEFINE_R3TYPE(fsri);
856   DEFINE_R3TYPE(fsriw);
857   DEFINE_R3TYPE(fsrw);
858 
859   DEFINE_NOARG(ecall);
860   DEFINE_NOARG(ebreak);
861   DEFINE_NOARG(uret);
862   DEFINE_NOARG(sret);
863   DEFINE_NOARG(mret);
864   DEFINE_NOARG(dret);
865   DEFINE_NOARG(wfi);
866   add_insn(new disasm_insn_t("fence", match_fence, mask_fence, {&iorw}));
867   DEFINE_NOARG(fence_i);
868   DEFINE_SFENCE_TYPE(sfence_vma);
869   DEFINE_NOARG(sfence_w_inval);
870   DEFINE_NOARG(sfence_inval_ir);
871   DEFINE_SFENCE_TYPE(sinval_vma);
872   DEFINE_SFENCE_TYPE(hinval_vvma);
873   DEFINE_SFENCE_TYPE(hinval_gvma);
874 
875   add_insn(new disasm_insn_t("csrr", match_csrrs, mask_csrrs | mask_rs1, {&xrd, &csr}));
876   add_insn(new disasm_insn_t("csrw", match_csrrw, mask_csrrw | mask_rd, {&csr, &xrs1}));
877   add_insn(new disasm_insn_t("csrs", match_csrrs, mask_csrrs | mask_rd, {&csr, &xrs1}));
878   add_insn(new disasm_insn_t("csrc", match_csrrc, mask_csrrc | mask_rd, {&csr, &xrs1}));
879   add_insn(new disasm_insn_t("csrwi", match_csrrwi, mask_csrrwi | mask_rd, {&csr, &zimm5}));
880   add_insn(new disasm_insn_t("csrsi", match_csrrsi, mask_csrrsi | mask_rd, {&csr, &zimm5}));
881   add_insn(new disasm_insn_t("csrci", match_csrrci, mask_csrrci | mask_rd, {&csr, &zimm5}));
882   add_insn(new disasm_insn_t("csrrw", match_csrrw, mask_csrrw, {&xrd, &csr, &xrs1}));
883   add_insn(new disasm_insn_t("csrrs", match_csrrs, mask_csrrs, {&xrd, &csr, &xrs1}));
884   add_insn(new disasm_insn_t("csrrc", match_csrrc, mask_csrrc, {&xrd, &csr, &xrs1}));
885   add_insn(new disasm_insn_t("csrrwi", match_csrrwi, mask_csrrwi, {&xrd, &csr, &zimm5}));
886   add_insn(new disasm_insn_t("csrrsi", match_csrrsi, mask_csrrsi, {&xrd, &csr, &zimm5}));
887   add_insn(new disasm_insn_t("csrrci", match_csrrci, mask_csrrci, {&xrd, &csr, &zimm5}));
888 
889   DEFINE_FRTYPE(fadd_s);
890   DEFINE_FRTYPE(fsub_s);
891   DEFINE_FRTYPE(fmul_s);
892   DEFINE_FRTYPE(fdiv_s);
893   DEFINE_FR1TYPE(fsqrt_s);
894   DEFINE_FRTYPE(fmin_s);
895   DEFINE_FRTYPE(fmax_s);
896   DEFINE_FR3TYPE(fmadd_s);
897   DEFINE_FR3TYPE(fmsub_s);
898   DEFINE_FR3TYPE(fnmadd_s);
899   DEFINE_FR3TYPE(fnmsub_s);
900   DEFINE_FRTYPE(fsgnj_s);
901   DEFINE_FRTYPE(fsgnjn_s);
902   DEFINE_FRTYPE(fsgnjx_s);
903   DEFINE_FR1TYPE(fcvt_s_d);
904   DEFINE_FR1TYPE(fcvt_s_q);
905   DEFINE_XFTYPE(fcvt_s_l);
906   DEFINE_XFTYPE(fcvt_s_lu);
907   DEFINE_XFTYPE(fcvt_s_w);
908   DEFINE_XFTYPE(fcvt_s_wu);
909   DEFINE_XFTYPE(fcvt_s_wu);
910   DEFINE_XFTYPE(fmv_w_x);
911   DEFINE_FXTYPE(fcvt_l_s);
912   DEFINE_FXTYPE(fcvt_lu_s);
913   DEFINE_FXTYPE(fcvt_w_s);
914   DEFINE_FXTYPE(fcvt_wu_s);
915   DEFINE_FXTYPE(fclass_s);
916   DEFINE_FXTYPE(fmv_x_w);
917   DEFINE_FX2TYPE(feq_s);
918   DEFINE_FX2TYPE(flt_s);
919   DEFINE_FX2TYPE(fle_s);
920 
921   DEFINE_FRTYPE(fadd_d);
922   DEFINE_FRTYPE(fsub_d);
923   DEFINE_FRTYPE(fmul_d);
924   DEFINE_FRTYPE(fdiv_d);
925   DEFINE_FR1TYPE(fsqrt_d);
926   DEFINE_FRTYPE(fmin_d);
927   DEFINE_FRTYPE(fmax_d);
928   DEFINE_FR3TYPE(fmadd_d);
929   DEFINE_FR3TYPE(fmsub_d);
930   DEFINE_FR3TYPE(fnmadd_d);
931   DEFINE_FR3TYPE(fnmsub_d);
932   DEFINE_FRTYPE(fsgnj_d);
933   DEFINE_FRTYPE(fsgnjn_d);
934   DEFINE_FRTYPE(fsgnjx_d);
935   DEFINE_FR1TYPE(fcvt_d_s);
936   DEFINE_FR1TYPE(fcvt_d_q);
937   DEFINE_XFTYPE(fcvt_d_l);
938   DEFINE_XFTYPE(fcvt_d_lu);
939   DEFINE_XFTYPE(fcvt_d_w);
940   DEFINE_XFTYPE(fcvt_d_wu);
941   DEFINE_XFTYPE(fcvt_d_wu);
942   DEFINE_XFTYPE(fmv_d_x);
943   DEFINE_FXTYPE(fcvt_l_d);
944   DEFINE_FXTYPE(fcvt_lu_d);
945   DEFINE_FXTYPE(fcvt_w_d);
946   DEFINE_FXTYPE(fcvt_wu_d);
947   DEFINE_FXTYPE(fclass_d);
948   DEFINE_FXTYPE(fmv_x_d);
949   DEFINE_FX2TYPE(feq_d);
950   DEFINE_FX2TYPE(flt_d);
951   DEFINE_FX2TYPE(fle_d);
952 
953   DEFINE_FRTYPE(fadd_h);
954   DEFINE_FRTYPE(fsub_h);
955   DEFINE_FRTYPE(fmul_h);
956   DEFINE_FRTYPE(fdiv_h);
957   DEFINE_FR1TYPE(fsqrt_h);
958   DEFINE_FRTYPE(fmin_h);
959   DEFINE_FRTYPE(fmax_h);
960   DEFINE_FR3TYPE(fmadd_h);
961   DEFINE_FR3TYPE(fmsub_h);
962   DEFINE_FR3TYPE(fnmadd_h);
963   DEFINE_FR3TYPE(fnmsub_h);
964   DEFINE_FRTYPE(fsgnj_h);
965   DEFINE_FRTYPE(fsgnjn_h);
966   DEFINE_FRTYPE(fsgnjx_h);
967   DEFINE_FR1TYPE(fcvt_h_s);
968   DEFINE_FR1TYPE(fcvt_h_d);
969   DEFINE_FR1TYPE(fcvt_h_q);
970   DEFINE_FR1TYPE(fcvt_s_h);
971   DEFINE_FR1TYPE(fcvt_d_h);
972   DEFINE_FR1TYPE(fcvt_q_h);
973   DEFINE_XFTYPE(fcvt_h_l);
974   DEFINE_XFTYPE(fcvt_h_lu);
975   DEFINE_XFTYPE(fcvt_h_w);
976   DEFINE_XFTYPE(fcvt_h_wu);
977   DEFINE_XFTYPE(fcvt_h_wu);
978   DEFINE_XFTYPE(fmv_h_x);
979   DEFINE_FXTYPE(fcvt_l_h);
980   DEFINE_FXTYPE(fcvt_lu_h);
981   DEFINE_FXTYPE(fcvt_w_h);
982   DEFINE_FXTYPE(fcvt_wu_h);
983   DEFINE_FXTYPE(fclass_h);
984   DEFINE_FXTYPE(fmv_x_h);
985   DEFINE_FX2TYPE(feq_h);
986   DEFINE_FX2TYPE(flt_h);
987   DEFINE_FX2TYPE(fle_h);
988 
989   DEFINE_FRTYPE(fadd_q);
990   DEFINE_FRTYPE(fsub_q);
991   DEFINE_FRTYPE(fmul_q);
992   DEFINE_FRTYPE(fdiv_q);
993   DEFINE_FR1TYPE(fsqrt_q);
994   DEFINE_FRTYPE(fmin_q);
995   DEFINE_FRTYPE(fmax_q);
996   DEFINE_FR3TYPE(fmadd_q);
997   DEFINE_FR3TYPE(fmsub_q);
998   DEFINE_FR3TYPE(fnmadd_q);
999   DEFINE_FR3TYPE(fnmsub_q);
1000   DEFINE_FRTYPE(fsgnj_q);
1001   DEFINE_FRTYPE(fsgnjn_q);
1002   DEFINE_FRTYPE(fsgnjx_q);
1003   DEFINE_FR1TYPE(fcvt_q_s);
1004   DEFINE_FR1TYPE(fcvt_q_d);
1005   DEFINE_XFTYPE(fcvt_q_l);
1006   DEFINE_XFTYPE(fcvt_q_lu);
1007   DEFINE_XFTYPE(fcvt_q_w);
1008   DEFINE_XFTYPE(fcvt_q_wu);
1009   DEFINE_XFTYPE(fcvt_q_wu);
1010   DEFINE_FXTYPE(fcvt_l_q);
1011   DEFINE_FXTYPE(fcvt_lu_q);
1012   DEFINE_FXTYPE(fcvt_w_q);
1013   DEFINE_FXTYPE(fcvt_wu_q);
1014   DEFINE_FXTYPE(fclass_q);
1015   DEFINE_FX2TYPE(feq_q);
1016   DEFINE_FX2TYPE(flt_q);
1017   DEFINE_FX2TYPE(fle_q);
1018 
1019 
1020   // ext-h
1021   DEFINE_XLOAD_BASE(hlv_b)
1022   DEFINE_XLOAD_BASE(hlv_bu)
1023   DEFINE_XLOAD_BASE(hlv_h)
1024   DEFINE_XLOAD_BASE(hlv_hu)
1025   DEFINE_XLOAD_BASE(hlv_w)
1026   DEFINE_XLOAD_BASE(hlv_wu)
1027   DEFINE_XLOAD_BASE(hlv_d)
1028 
1029   DEFINE_XLOAD_BASE(hlvx_hu)
1030   DEFINE_XLOAD_BASE(hlvx_wu)
1031 
1032   DEFINE_XSTORE_BASE(hsv_b)
1033   DEFINE_XSTORE_BASE(hsv_h)
1034   DEFINE_XSTORE_BASE(hsv_w)
1035   DEFINE_XSTORE_BASE(hsv_d)
1036 
1037   DEFINE_SFENCE_TYPE(hfence_gvma);
1038   DEFINE_SFENCE_TYPE(hfence_vvma);
1039 
1040 
1041   // ext-c
1042   DISASM_INSN("c.ebreak", c_add, mask_rd | mask_rvc_rs2, {});
1043   add_insn(new disasm_insn_t("ret", match_c_jr | match_rd_ra, mask_c_jr | mask_rd | mask_rvc_imm, {}));
1044   DISASM_INSN("c.jr", c_jr, mask_rvc_imm, {&rvc_rs1});
1045   DISASM_INSN("c.jalr", c_jalr, mask_rvc_imm, {&rvc_rs1});
1046   DISASM_INSN("c.nop", c_addi, mask_rd | mask_rvc_imm, {});
1047   DISASM_INSN("c.addi16sp", c_addi16sp, mask_rd, {&rvc_sp, &rvc_addi16sp_imm});
1048   DISASM_INSN("c.addi4spn", c_addi4spn, 0, {&rvc_rs2s, &rvc_sp, &rvc_addi4spn_imm});
1049   DISASM_INSN("c.li", c_li, 0, {&xrd, &rvc_imm});
1050   DISASM_INSN("c.lui", c_lui, 0, {&xrd, &rvc_uimm});
1051   DISASM_INSN("c.addi", c_addi, 0, {&xrd, &rvc_imm});
1052   DISASM_INSN("c.slli", c_slli, 0, {&rvc_rs1, &rvc_shamt});
1053   DISASM_INSN("c.srli", c_srli, 0, {&rvc_rs1s, &rvc_shamt});
1054   DISASM_INSN("c.srai", c_srai, 0, {&rvc_rs1s, &rvc_shamt});
1055   DISASM_INSN("c.andi", c_andi, 0, {&rvc_rs1s, &rvc_imm});
1056   DISASM_INSN("c.mv", c_mv, 0, {&xrd, &rvc_rs2});
1057   DISASM_INSN("c.add", c_add, 0, {&xrd, &rvc_rs2});
1058   DISASM_INSN("c.addw", c_addw, 0, {&rvc_rs1s, &rvc_rs2s});
1059   DISASM_INSN("c.sub", c_sub, 0, {&rvc_rs1s, &rvc_rs2s});
1060   DISASM_INSN("c.subw", c_subw, 0, {&rvc_rs1s, &rvc_rs2s});
1061   DISASM_INSN("c.and", c_and, 0, {&rvc_rs1s, &rvc_rs2s});
1062   DISASM_INSN("c.or", c_or, 0, {&rvc_rs1s, &rvc_rs2s});
1063   DISASM_INSN("c.xor", c_xor, 0, {&rvc_rs1s, &rvc_rs2s});
1064   DISASM_INSN("c.lwsp", c_lwsp, 0, {&xrd, &rvc_lwsp_address});
1065   DISASM_INSN("c.fld", c_fld, 0, {&rvc_fp_rs2s, &rvc_ld_address});
1066   DISASM_INSN("c.swsp", c_swsp, 0, {&rvc_rs2, &rvc_swsp_address});
1067   DISASM_INSN("c.lw", c_lw, 0, {&rvc_rs2s, &rvc_lw_address});
1068   DISASM_INSN("c.sw", c_sw, 0, {&rvc_rs2s, &rvc_lw_address});
1069   DISASM_INSN("c.beqz", c_beqz, 0, {&rvc_rs1s, &rvc_branch_target});
1070   DISASM_INSN("c.bnez", c_bnez, 0, {&rvc_rs1s, &rvc_branch_target});
1071   DISASM_INSN("c.j", c_j, 0, {&rvc_jump_target});
1072   DISASM_INSN("c.fldsp", c_fldsp, 0, {&frd, &rvc_ldsp_address});
1073   DISASM_INSN("c.fsd", c_fsd, 0, {&rvc_fp_rs2s, &rvc_ld_address});
1074   DISASM_INSN("c.fsdsp", c_fsdsp, 0, {&rvc_fp_rs2, &rvc_sdsp_address});
1075 
1076   DISASM_INSN("vsetivli", vsetivli, 0, {&xrd, &zimm5, &v_vtype});
1077   DISASM_INSN("vsetvli", vsetvli, 0, {&xrd, &xrs1, &v_vtype});
1078   DEFINE_RTYPE(vsetvl);
1079 
1080   std::vector<const arg_t *> v_ld_unit = {&vd, &v_address, opt, &vm};
1081   std::vector<const arg_t *> v_st_unit = {&vs3, &v_address, opt, &vm};
1082   std::vector<const arg_t *> v_ld_stride = {&vd, &v_address, &xrs2, opt, &vm};
1083   std::vector<const arg_t *> v_st_stride = {&vs3, &v_address, &xrs2, opt, &vm};
1084   std::vector<const arg_t *> v_ld_index = {&vd, &v_address, &vs2, opt, &vm};
1085   std::vector<const arg_t *> v_st_index = {&vs3, &v_address, &vs2, opt, &vm};
1086 
1087   add_insn(new disasm_insn_t("vlm.v",  match_vlm_v,     mask_vlm_v, v_ld_unit));
1088   add_insn(new disasm_insn_t("vsm.v",  match_vsm_v,     mask_vsm_v, v_st_unit));
1089 
1090   // handle vector segment load/store
1091   for (size_t elt = 0; elt <= 7; ++elt) {
1092     const custom_fmt_t template_insn[] = {
1093       {match_vle8_v,   mask_vle8_v,   "vl%se%d.v",   v_ld_unit},
1094       {match_vse8_v,   mask_vse8_v,   "vs%se%d.v",   v_st_unit},
1095 
1096       {match_vluxei8_v, mask_vluxei8_v, "vlux%sei%d.v", v_ld_index},
1097       {match_vsuxei8_v, mask_vsuxei8_v, "vsux%sei%d.v", v_st_index},
1098 
1099       {match_vlse8_v,  mask_vlse8_v,  "vls%se%d.v",  v_ld_stride},
1100       {match_vsse8_v,  mask_vsse8_v,  "vss%se%d.v",  v_st_stride},
1101 
1102       {match_vloxei8_v, mask_vloxei8_v, "vlox%sei%d.v", v_ld_index},
1103       {match_vsoxei8_v, mask_vsoxei8_v, "vsox%sei%d.v", v_st_index},
1104 
1105       {match_vle8ff_v, mask_vle8ff_v, "vl%se%dff.v", v_ld_unit}
1106     };
1107 
1108     reg_t elt_map[] = {0x00000000, 0x00005000, 0x00006000, 0x00007000,
1109                        0x10000000, 0x10005000, 0x10006000, 0x10007000};
1110 
1111     for (unsigned nf = 0; nf <= 7; ++nf) {
1112       char seg_str[8] = "";
1113       if (nf)
1114         sprintf(seg_str, "seg%u", nf + 1);
1115 
1116       for (auto item : template_insn) {
1117         const reg_t match_nf = nf << 29;
1118         char buf[128];
1119         sprintf(buf, item.fmt, seg_str, 8 << elt);
1120         add_insn(new disasm_insn_t(
1121           buf,
1122           ((item.match | match_nf) & ~mask_vldst) | elt_map[elt],
1123           item.mask | mask_nf,
1124           item.arg
1125           ));
1126       }
1127     }
1128 
1129     const custom_fmt_t template_insn2[] = {
1130       {match_vl1re8_v,   mask_vl1re8_v,   "vl%dre%d.v",   v_ld_unit},
1131     };
1132 
1133     for (reg_t i = 0, nf = 7; i < 4; i++, nf >>= 1) {
1134       for (auto item : template_insn2) {
1135         const reg_t match_nf = nf << 29;
1136         char buf[128];
1137         sprintf(buf, item.fmt, nf + 1, 8 << elt);
1138         add_insn(new disasm_insn_t(
1139           buf,
1140           item.match | match_nf | elt_map[elt],
1141           item.mask | mask_nf,
1142           item.arg
1143         ));
1144       }
1145     }
1146   }
1147 
1148   #define DISASM_ST_WHOLE_INSN(name, nf) \
1149     add_insn(new disasm_insn_t(#name, match_vs1r_v | (nf << 29), \
1150                                       mask_vs1r_v | mask_nf, \
1151                                       {&vs3, &v_address}));
1152   DISASM_ST_WHOLE_INSN(vs1r.v, 0);
1153   DISASM_ST_WHOLE_INSN(vs2r.v, 1);
1154   DISASM_ST_WHOLE_INSN(vs4r.v, 3);
1155   DISASM_ST_WHOLE_INSN(vs8r.v, 7);
1156 
1157   #undef DISASM_ST_WHOLE_INSN
1158 
1159   #define DEFINE_VECTOR_V(code) add_vector_v_insn(this, #code, match_##code, mask_##code)
1160   #define DEFINE_VECTOR_VV(code) add_vector_vv_insn(this, #code, match_##code, mask_##code)
1161   #define DEFINE_VECTOR_VX(code) add_vector_vx_insn(this, #code, match_##code, mask_##code)
1162   #define DEFINE_VECTOR_VF(code) add_vector_vf_insn(this, #code, match_##code, mask_##code)
1163   #define DEFINE_VECTOR_VI(code) add_vector_vi_insn(this, #code, match_##code, mask_##code)
1164   #define DEFINE_VECTOR_VIU(code) add_vector_viu_insn(this, #code, match_##code, mask_##code)
1165 
1166   #define DISASM_OPIV_VXI_INSN(name, sign, suf) \
1167     DEFINE_VECTOR_VV(name##_##suf##v); \
1168     DEFINE_VECTOR_VX(name##_##suf##x); \
1169     if (sign) \
1170       DEFINE_VECTOR_VI(name##_##suf##i); \
1171     else \
1172       DEFINE_VECTOR_VIU(name##_##suf##i)
1173 
1174   #define DISASM_OPIV_VX__INSN(name, sign) \
1175     DEFINE_VECTOR_VV(name##_vv); \
1176     DEFINE_VECTOR_VX(name##_vx)
1177 
1178   #define DISASM_OPIV__XI_INSN(name, sign) \
1179     DEFINE_VECTOR_VX(name##_vx); \
1180     if (sign) \
1181       DEFINE_VECTOR_VI(name##_vi); \
1182     else \
1183       DEFINE_VECTOR_VIU(name##_vi)
1184 
1185   #define DISASM_OPIV_V___INSN(name, sign) DEFINE_VECTOR_VV(name##_vv)
1186 
1187   #define DISASM_OPIV_S___INSN(name, sign) DEFINE_VECTOR_VV(name##_vs)
1188 
1189   #define DISASM_OPIV_W___INSN(name, sign) \
1190     DEFINE_VECTOR_VV(name##_wv); \
1191     DEFINE_VECTOR_VX(name##_wx)
1192 
1193   #define DISASM_OPIV_M___INSN(name, sign) DEFINE_VECTOR_VV(name##_mm)
1194 
1195   #define DISASM_OPIV__X__INSN(name, sign) DEFINE_VECTOR_VX(name##_vx)
1196 
1197   #define DEFINE_VECTOR_VVM(name, has_vm) \
1198     add_vector_vvm_insn(this, #name, match_##name, mask_##name | mask_vm); \
1199     if (has_vm) \
1200       add_vector_vv_insn(this, #name, match_##name, mask_##name | mask_vm)
1201 
1202   #define DEFINE_VECTOR_VXM(name, has_vm) \
1203     add_vector_vxm_insn(this, #name, match_##name, mask_##name | mask_vm); \
1204     if (has_vm) \
1205       add_vector_vx_insn(this, #name, match_##name, mask_##name | mask_vm)
1206 
1207   #define DEFINE_VECTOR_VIM(name, has_vm) \
1208     add_vector_vim_insn(this, #name, match_##name, mask_##name | mask_vm); \
1209     if (has_vm) \
1210       add_vector_vi_insn(this, #name, match_##name, mask_##name | mask_vm)
1211 
1212   #define DISASM_OPIV_VXIM_INSN(name, sign, has_vm) \
1213     DEFINE_VECTOR_VVM(name##_vvm, has_vm); \
1214     DEFINE_VECTOR_VXM(name##_vxm, has_vm); \
1215     DEFINE_VECTOR_VIM(name##_vim, has_vm)
1216 
1217   #define DISASM_OPIV_VX_M_INSN(name, sign, has_vm) \
1218     DEFINE_VECTOR_VVM(name##_vvm, has_vm); \
1219     DEFINE_VECTOR_VXM(name##_vxm, has_vm)
1220 
1221   //OPFVV/OPFVF
1222   //0b00_0000
1223   DISASM_OPIV_VXI_INSN(vadd,         1, v);
1224   DISASM_OPIV_VX__INSN(vsub,         1);
1225   DISASM_OPIV__XI_INSN(vrsub,        1);
1226   DISASM_OPIV_VX__INSN(vminu,        0);
1227   DISASM_OPIV_VX__INSN(vmin,         1);
1228   DISASM_OPIV_VX__INSN(vmaxu,        1);
1229   DISASM_OPIV_VX__INSN(vmax,         0);
1230   DISASM_OPIV_VXI_INSN(vand,         1, v);
1231   DISASM_OPIV_VXI_INSN(vor,          1, v);
1232   DISASM_OPIV_VXI_INSN(vxor,         1, v);
1233   DISASM_OPIV_VXI_INSN(vrgather,     0, v);
1234   DISASM_OPIV_V___INSN(vrgatherei16, 0);
1235   DISASM_OPIV__XI_INSN(vslideup,     0);
1236   DISASM_OPIV__XI_INSN(vslidedown,   0);
1237 
1238   //0b01_0000
1239   DISASM_OPIV_VXIM_INSN(vadc,    1, 0);
1240   DISASM_OPIV_VXIM_INSN(vmadc,   1, 1);
1241   DISASM_OPIV_VX_M_INSN(vsbc,    1, 0);
1242   DISASM_OPIV_VX_M_INSN(vmsbc,   1, 1);
1243   DISASM_OPIV_VXIM_INSN(vmerge,  1, 0);
1244   DISASM_INSN("vmv.v.i", vmv_v_i, 0, {&vd, &v_simm5});
1245   DISASM_INSN("vmv.v.v", vmv_v_v, 0, {&vd, &vs1});
1246   DISASM_INSN("vmv.v.x", vmv_v_x, 0, {&vd, &xrs1});
1247   DISASM_OPIV_VXI_INSN(vmseq,     1, v);
1248   DISASM_OPIV_VXI_INSN(vmsne,     1, v);
1249   DISASM_OPIV_VX__INSN(vmsltu,    0);
1250   DISASM_OPIV_VX__INSN(vmslt,     1);
1251   DISASM_OPIV_VXI_INSN(vmsleu,    0, v);
1252   DISASM_OPIV_VXI_INSN(vmsle,     1, v);
1253   DISASM_OPIV__XI_INSN(vmsgtu,    0);
1254   DISASM_OPIV__XI_INSN(vmsgt,     1);
1255 
1256   //0b10_0000
1257   DISASM_OPIV_VXI_INSN(vsaddu,    0, v);
1258   DISASM_OPIV_VXI_INSN(vsadd,     1, v);
1259   DISASM_OPIV_VX__INSN(vssubu,    0);
1260   DISASM_OPIV_VX__INSN(vssub,     1);
1261   DISASM_OPIV_VXI_INSN(vsll,      1, v);
1262   DISASM_INSN("vmv1r.v", vmv1r_v, 0, {&vd, &vs2});
1263   DISASM_INSN("vmv2r.v", vmv2r_v, 0, {&vd, &vs2});
1264   DISASM_INSN("vmv4r.v", vmv4r_v, 0, {&vd, &vs2});
1265   DISASM_INSN("vmv8r.v", vmv8r_v, 0, {&vd, &vs2});
1266   DISASM_OPIV_VX__INSN(vsmul,     1);
1267   DISASM_OPIV_VXI_INSN(vsrl,      0, v);
1268   DISASM_OPIV_VXI_INSN(vsra,      0, v);
1269   DISASM_OPIV_VXI_INSN(vssrl,     0, v);
1270   DISASM_OPIV_VXI_INSN(vssra,     0, v);
1271   DISASM_OPIV_VXI_INSN(vnsrl,     0, w);
1272   DISASM_OPIV_VXI_INSN(vnsra,     0, w);
1273   DISASM_OPIV_VXI_INSN(vnclipu,   0, w);
1274   DISASM_OPIV_VXI_INSN(vnclip,    0, w);
1275 
1276   //0b11_0000
1277   DISASM_OPIV_S___INSN(vwredsumu, 0);
1278   DISASM_OPIV_S___INSN(vwredsum,  1);
1279 
1280   //OPMVV/OPMVX
1281   //0b00_0000
1282   DISASM_OPIV_VX__INSN(vaaddu,    0);
1283   DISASM_OPIV_VX__INSN(vaadd,     0);
1284   DISASM_OPIV_VX__INSN(vasubu,    0);
1285   DISASM_OPIV_VX__INSN(vasub,     0);
1286 
1287   DISASM_OPIV_S___INSN(vredsum,   1);
1288   DISASM_OPIV_S___INSN(vredand,   1);
1289   DISASM_OPIV_S___INSN(vredor,    1);
1290   DISASM_OPIV_S___INSN(vredxor,   1);
1291   DISASM_OPIV_S___INSN(vredminu,  0);
1292   DISASM_OPIV_S___INSN(vredmin,   1);
1293   DISASM_OPIV_S___INSN(vredmaxu,  0);
1294   DISASM_OPIV_S___INSN(vredmax,   1);
1295   DISASM_OPIV__X__INSN(vslide1up,  1);
1296   DISASM_OPIV__X__INSN(vslide1down,1);
1297 
1298   //0b01_0000
1299   //VWXUNARY0
1300   DISASM_INSN("vmv.x.s", vmv_x_s, 0, {&xrd, &vs2});
1301   DISASM_INSN("vcpop.m", vcpop_m, 0, {&xrd, &vs2, opt, &vm});
1302   DISASM_INSN("vfirst.m", vfirst_m, 0, {&xrd, &vs2, opt, &vm});
1303 
1304   //VRXUNARY0
1305   DISASM_INSN("vmv.s.x", vmv_s_x, 0, {&vd, &xrs1});
1306 
1307   //VXUNARY0
1308   DEFINE_VECTOR_V(vzext_vf2);
1309   DEFINE_VECTOR_V(vsext_vf2);
1310   DEFINE_VECTOR_V(vzext_vf4);
1311   DEFINE_VECTOR_V(vsext_vf4);
1312   DEFINE_VECTOR_V(vzext_vf8);
1313   DEFINE_VECTOR_V(vsext_vf8);
1314 
1315   //VMUNARY0
1316   DEFINE_VECTOR_V(vmsbf_m);
1317   DEFINE_VECTOR_V(vmsof_m);
1318   DEFINE_VECTOR_V(vmsif_m);
1319   DEFINE_VECTOR_V(viota_m);
1320   DISASM_INSN("vid.v", vid_v, 0, {&vd, opt, &vm});
1321 
1322   DISASM_INSN("vid.v", vid_v, 0, {&vd, opt, &vm});
1323 
1324   DISASM_INSN("vcompress.vm", vcompress_vm, 0, {&vd, &vs2, &vs1});
1325 
1326   DISASM_OPIV_M___INSN(vmandnot,  1);
1327   DISASM_OPIV_M___INSN(vmand,     1);
1328   DISASM_OPIV_M___INSN(vmor,      1);
1329   DISASM_OPIV_M___INSN(vmxor,     1);
1330   DISASM_OPIV_M___INSN(vmornot,   1);
1331   DISASM_OPIV_M___INSN(vmnand,    1);
1332   DISASM_OPIV_M___INSN(vmnor,     1);
1333   DISASM_OPIV_M___INSN(vmxnor,    1);
1334 
1335   //0b10_0000
1336   DISASM_OPIV_VX__INSN(vdivu,     0);
1337   DISASM_OPIV_VX__INSN(vdiv,      1);
1338   DISASM_OPIV_VX__INSN(vremu,     0);
1339   DISASM_OPIV_VX__INSN(vrem,      1);
1340   DISASM_OPIV_VX__INSN(vmulhu,    0);
1341   DISASM_OPIV_VX__INSN(vmul,      1);
1342   DISASM_OPIV_VX__INSN(vmulhsu,   0);
1343   DISASM_OPIV_VX__INSN(vmulh,     1);
1344   DISASM_OPIV_VX__INSN(vmadd,     1);
1345   DISASM_OPIV_VX__INSN(vnmsub,    1);
1346   DISASM_OPIV_VX__INSN(vmacc,     1);
1347   DISASM_OPIV_VX__INSN(vnmsac,    1);
1348 
1349   //0b11_0000
1350   DISASM_OPIV_VX__INSN(vwaddu,    0);
1351   DISASM_OPIV_VX__INSN(vwadd,     1);
1352   DISASM_OPIV_VX__INSN(vwsubu,    0);
1353   DISASM_OPIV_VX__INSN(vwsub,     1);
1354   DISASM_OPIV_W___INSN(vwaddu,    0);
1355   DISASM_OPIV_W___INSN(vwadd,     1);
1356   DISASM_OPIV_W___INSN(vwsubu,    0);
1357   DISASM_OPIV_W___INSN(vwsub,     1);
1358   DISASM_OPIV_VX__INSN(vwmulu,    0);
1359   DISASM_OPIV_VX__INSN(vwmulsu,   0);
1360   DISASM_OPIV_VX__INSN(vwmul,     1);
1361   DISASM_OPIV_VX__INSN(vwmaccu,   0);
1362   DISASM_OPIV_VX__INSN(vwmacc,    1);
1363   DISASM_OPIV__X__INSN(vwmaccus,  1);
1364   DISASM_OPIV_VX__INSN(vwmaccsu,  0);
1365 
1366   #undef DISASM_OPIV_VXI_INSN
1367   #undef DISASM_OPIV_VX__INSN
1368   #undef DISASM_OPIV__XI_INSN
1369   #undef DISASM_OPIV_V___INSN
1370   #undef DISASM_OPIV_S___INSN
1371   #undef DISASM_OPIV_W___INSN
1372   #undef DISASM_OPIV_M___INSN
1373   #undef DISASM_OPIV__X__INSN
1374   #undef DISASM_OPIV_VXIM_INSN
1375   #undef DISASM_OPIV_VX_M_INSN
1376 
1377   #define DISASM_OPIV_VF_INSN(name) \
1378     DEFINE_VECTOR_VV(name##_vv); \
1379     DEFINE_VECTOR_VF(name##_vf)
1380 
1381   #define DISASM_OPIV_WF_INSN(name) \
1382     DEFINE_VECTOR_VV(name##_wv); \
1383     DEFINE_VECTOR_VF(name##_wf)
1384 
1385   #define DISASM_OPIV_S__INSN(name) \
1386     DEFINE_VECTOR_VV(name##_vs)
1387 
1388   #define DISASM_OPIV__F_INSN(name) \
1389     DEFINE_VECTOR_VF(name##_vf)
1390 
1391   #define DISASM_VFUNARY0_INSN(name, suf) \
1392     DEFINE_VECTOR_V(name##cvt_rtz_xu_f_##suf); \
1393     DEFINE_VECTOR_V(name##cvt_rtz_x_f_##suf); \
1394     DEFINE_VECTOR_V(name##cvt_xu_f_##suf); \
1395     DEFINE_VECTOR_V(name##cvt_x_f_##suf); \
1396     DEFINE_VECTOR_V(name##cvt_f_xu_##suf); \
1397     DEFINE_VECTOR_V(name##cvt_f_x_##suf)
1398 
1399   //OPFVV/OPFVF
1400   //0b00_0000
1401   DISASM_OPIV_VF_INSN(vfadd);
1402   DISASM_OPIV_S__INSN(vfredusum);
1403   DISASM_OPIV_VF_INSN(vfsub);
1404   DISASM_OPIV_S__INSN(vfredosum);
1405   DISASM_OPIV_VF_INSN(vfmin);
1406   DISASM_OPIV_S__INSN(vfredmin);
1407   DISASM_OPIV_VF_INSN(vfmax);
1408   DISASM_OPIV_S__INSN(vfredmax);
1409   DISASM_OPIV_VF_INSN(vfsgnj);
1410   DISASM_OPIV_VF_INSN(vfsgnjn);
1411   DISASM_OPIV_VF_INSN(vfsgnjx);
1412   DISASM_INSN("vfmv.f.s", vfmv_f_s, 0, {&frd, &vs2});
1413   DISASM_INSN("vfmv.s.f", vfmv_s_f, mask_vfmv_s_f, {&vd, &frs1});
1414   DISASM_OPIV__F_INSN(vfslide1up);
1415   DISASM_OPIV__F_INSN(vfslide1down);
1416 
1417   //0b01_0000
1418   DISASM_INSN("vfmerge.vfm", vfmerge_vfm, 0, {&vd, &vs2, &frs1, &v0});
1419   DISASM_INSN("vfmv.v.f", vfmv_v_f, 0, {&vd, &frs1});
1420   DISASM_OPIV_VF_INSN(vmfeq);
1421   DISASM_OPIV_VF_INSN(vmfle);
1422   DISASM_OPIV_VF_INSN(vmflt);
1423   DISASM_OPIV_VF_INSN(vmfne);
1424   DISASM_OPIV__F_INSN(vmfgt);
1425   DISASM_OPIV__F_INSN(vmfge);
1426 
1427   //0b10_0000
1428   DISASM_OPIV_VF_INSN(vfdiv);
1429   DISASM_OPIV__F_INSN(vfrdiv);
1430 
1431   //vfunary0
1432   DISASM_VFUNARY0_INSN(vf,  v);
1433 
1434   DISASM_VFUNARY0_INSN(vfw, v);
1435   DEFINE_VECTOR_V(vfwcvt_f_f_v);
1436 
1437   DISASM_VFUNARY0_INSN(vfn, w);
1438   DEFINE_VECTOR_V(vfncvt_f_f_w);
1439   DEFINE_VECTOR_V(vfncvt_rod_f_f_w);
1440 
1441   //vfunary1
1442   DEFINE_VECTOR_V(vfsqrt_v);
1443   DEFINE_VECTOR_V(vfrsqrt7_v);
1444   DEFINE_VECTOR_V(vfrec7_v);
1445   DEFINE_VECTOR_V(vfclass_v);
1446 
1447   DISASM_OPIV_VF_INSN(vfmul);
1448   DISASM_OPIV__F_INSN(vfrsub);
1449   DISASM_OPIV_VF_INSN(vfmadd);
1450   DISASM_OPIV_VF_INSN(vfnmadd);
1451   DISASM_OPIV_VF_INSN(vfmsub);
1452   DISASM_OPIV_VF_INSN(vfnmsub);
1453   DISASM_OPIV_VF_INSN(vfmacc);
1454   DISASM_OPIV_VF_INSN(vfnmacc);
1455   DISASM_OPIV_VF_INSN(vfmsac);
1456   DISASM_OPIV_VF_INSN(vfnmsac);
1457 
1458   //0b11_0000
1459   DISASM_OPIV_VF_INSN(vfwadd);
1460   DISASM_OPIV_S__INSN(vfwredusum);
1461   DISASM_OPIV_VF_INSN(vfwsub);
1462   DISASM_OPIV_S__INSN(vfwredosum);
1463   DISASM_OPIV_WF_INSN(vfwadd);
1464   DISASM_OPIV_WF_INSN(vfwsub);
1465   DISASM_OPIV_VF_INSN(vfwmul);
1466   DISASM_OPIV_VF_INSN(vfwmacc);
1467   DISASM_OPIV_VF_INSN(vfwnmacc);
1468   DISASM_OPIV_VF_INSN(vfwmsac);
1469   DISASM_OPIV_VF_INSN(vfwnmsac);
1470 
1471   #undef DISASM_OPIV_VF_INSN
1472   #undef DISASM_OPIV__F_INSN
1473   #undef DISASM_OPIV_S__INSN
1474   #undef DISASM_OPIV_W__INSN
1475   #undef DISASM_VFUNARY0_INSN
1476 
1477   // vector amo
1478   std::vector<const arg_t *> v_fmt_amo_wd = {&vd, &v_address, &vs2, &vd, opt, &vm};
1479   std::vector<const arg_t *> v_fmt_amo = {&x0, &v_address, &vs2, &vd, opt, &vm};
1480   for (size_t elt = 0; elt <= 3; ++elt) {
1481     const custom_fmt_t template_insn[] = {
1482       {match_vamoaddei8_v | mask_wd,   mask_vamoaddei8_v | mask_wd,
1483          "%sei%d.v", v_fmt_amo_wd},
1484       {match_vamoaddei8_v,   mask_vamoaddei8_v | mask_wd,
1485          "%sei%d.v", v_fmt_amo},
1486     };
1487     std::pair<const char*, reg_t> amo_map[] = {
1488         {"vamoswap", 0x01ul << 27},
1489         {"vamoadd",  0x00ul << 27},
1490         {"vamoxor",  0x04ul << 27},
1491         {"vamoand",  0x0cul << 27},
1492         {"vamoor",   0x08ul << 27},
1493         {"vamomin",  0x10ul << 27},
1494         {"vamomax",  0x14ul << 27},
1495         {"vamominu", 0x18ul << 27},
1496         {"vamomaxu", 0x1cul << 27}};
1497     const reg_t elt_map[] = {0x0ul << 12,  0x5ul << 12,
1498                              0x6ul <<12, 0x7ul << 12};
1499 
1500     for (size_t idx = 0; idx < sizeof(amo_map) / sizeof(amo_map[0]); ++idx) {
1501       for (auto item : template_insn) {
1502         char buf[128];
1503         sprintf(buf, item.fmt, amo_map[idx].first, 8 << elt);
1504         add_insn(new disasm_insn_t(buf,
1505                   item.match | amo_map[idx].second | elt_map[elt],
1506                   item.mask,
1507                   item.arg));
1508       }
1509     }
1510   }
1511 
1512 #define DEFINE_PI3TYPE(code) add_pitype3_insn(this, #code, match_##code, mask_##code);
1513 #define DEFINE_PI4TYPE(code) add_pitype4_insn(this, #code, match_##code, mask_##code);
1514 #define DEFINE_PI5TYPE(code) add_pitype5_insn(this, #code, match_##code, mask_##code);
1515 #define DEFINE_PI6TYPE(code) add_pitype6_insn(this, #code, match_##code, mask_##code);
1516 
1517 #define DISASM_8_AND_16_RINSN(code) \
1518   DEFINE_RTYPE(code##8); \
1519   DEFINE_RTYPE(code##16);
1520 
1521 #define DISASM_8_AND_16_RINSN_ROUND(code) \
1522   DEFINE_RTYPE(code##8_u); \
1523   DEFINE_RTYPE(code##16_u);
1524 
1525 #define DISASM_8_AND_16_PIINSN(code) \
1526   DEFINE_PI3TYPE(code##8); \
1527   DEFINE_PI4TYPE(code##16);
1528 
1529 #define DISASM_8_AND_16_PIINSN_ROUND(code) \
1530   DEFINE_PI3TYPE(code##8_u); \
1531   DEFINE_PI4TYPE(code##16_u);
1532 
1533 #define DISASM_RINSN_AND_ROUND(code) \
1534   DEFINE_RTYPE(code); \
1535   DEFINE_RTYPE(code##_u); \
1536 
1537   DISASM_8_AND_16_RINSN(add);
1538   DISASM_8_AND_16_RINSN(radd);
1539   DISASM_8_AND_16_RINSN(uradd);
1540   DISASM_8_AND_16_RINSN(kadd);
1541   DISASM_8_AND_16_RINSN(ukadd);
1542   DISASM_8_AND_16_RINSN(sub);
1543   DISASM_8_AND_16_RINSN(rsub);
1544   DISASM_8_AND_16_RINSN(ursub);
1545   DISASM_8_AND_16_RINSN(ksub);
1546   DISASM_8_AND_16_RINSN(uksub);
1547   DEFINE_RTYPE(cras16);
1548   DEFINE_RTYPE(rcras16);
1549   DEFINE_RTYPE(urcras16);
1550   DEFINE_RTYPE(kcras16);
1551   DEFINE_RTYPE(ukcras16);
1552   DEFINE_RTYPE(crsa16);
1553   DEFINE_RTYPE(rcrsa16);
1554   DEFINE_RTYPE(urcrsa16);
1555   DEFINE_RTYPE(kcrsa16);
1556   DEFINE_RTYPE(ukcrsa16);
1557   DEFINE_RTYPE(stas16);
1558   DEFINE_RTYPE(rstas16);
1559   DEFINE_RTYPE(urstas16);
1560   DEFINE_RTYPE(kstas16);
1561   DEFINE_RTYPE(ukstas16);
1562   DEFINE_RTYPE(stsa16);
1563   DEFINE_RTYPE(rstsa16);
1564   DEFINE_RTYPE(urstsa16);
1565   DEFINE_RTYPE(kstsa16);
1566   DEFINE_RTYPE(ukstsa16);
1567 
1568   DISASM_8_AND_16_RINSN(sra);
1569   DISASM_8_AND_16_RINSN(srl);
1570   DISASM_8_AND_16_RINSN(sll);
1571   DISASM_8_AND_16_RINSN(ksll);
1572   DISASM_8_AND_16_RINSN(kslra);
1573   DISASM_8_AND_16_PIINSN(srai);
1574   DISASM_8_AND_16_PIINSN(srli);
1575   DISASM_8_AND_16_PIINSN(slli);
1576   DISASM_8_AND_16_PIINSN(kslli);
1577   DISASM_8_AND_16_RINSN_ROUND(sra);
1578   DISASM_8_AND_16_RINSN_ROUND(srl);
1579   DISASM_8_AND_16_RINSN_ROUND(kslra);
1580   DISASM_8_AND_16_PIINSN_ROUND(srai);
1581   DISASM_8_AND_16_PIINSN_ROUND(srli);
1582 
1583   DISASM_8_AND_16_RINSN(cmpeq);
1584   DISASM_8_AND_16_RINSN(scmplt);
1585   DISASM_8_AND_16_RINSN(scmple);
1586   DISASM_8_AND_16_RINSN(ucmplt);
1587   DISASM_8_AND_16_RINSN(ucmple);
1588 
1589   DISASM_8_AND_16_RINSN(smul);
1590   DISASM_8_AND_16_RINSN(smulx);
1591   DISASM_8_AND_16_RINSN(umul);
1592   DISASM_8_AND_16_RINSN(umulx);
1593   DISASM_8_AND_16_RINSN(khm);
1594   DISASM_8_AND_16_RINSN(khmx);
1595 
1596   DISASM_8_AND_16_RINSN(smin);
1597   DISASM_8_AND_16_RINSN(umin);
1598   DISASM_8_AND_16_RINSN(smax);
1599   DISASM_8_AND_16_RINSN(umax);
1600   DISASM_8_AND_16_PIINSN(sclip);
1601   DISASM_8_AND_16_PIINSN(uclip);
1602   DEFINE_R1TYPE(kabs16);
1603   DEFINE_R1TYPE(clrs16);
1604   DEFINE_R1TYPE(clz16);
1605   DEFINE_R1TYPE(kabs8);
1606   DEFINE_R1TYPE(clrs8);
1607   DEFINE_R1TYPE(clz8);
1608 
1609   DEFINE_R1TYPE(sunpkd810);
1610   DEFINE_R1TYPE(sunpkd820);
1611   DEFINE_R1TYPE(sunpkd830);
1612   DEFINE_R1TYPE(sunpkd831);
1613   DEFINE_R1TYPE(sunpkd832);
1614   DEFINE_R1TYPE(zunpkd810);
1615   DEFINE_R1TYPE(zunpkd820);
1616   DEFINE_R1TYPE(zunpkd830);
1617   DEFINE_R1TYPE(zunpkd831);
1618   DEFINE_R1TYPE(zunpkd832);
1619 
1620   DEFINE_RTYPE(pkbb16);
1621   DEFINE_RTYPE(pkbt16);
1622   DEFINE_RTYPE(pktb16);
1623   DEFINE_RTYPE(pktt16);
1624   DISASM_RINSN_AND_ROUND(smmul);
1625   DISASM_RINSN_AND_ROUND(kmmac);
1626   DISASM_RINSN_AND_ROUND(kmmsb);
1627   DISASM_RINSN_AND_ROUND(kwmmul);
1628   DISASM_RINSN_AND_ROUND(smmwb);
1629   DISASM_RINSN_AND_ROUND(smmwt);
1630   DISASM_RINSN_AND_ROUND(kmmawb);
1631   DISASM_RINSN_AND_ROUND(kmmawt);
1632   DISASM_RINSN_AND_ROUND(kmmwb2);
1633   DISASM_RINSN_AND_ROUND(kmmwt2);
1634   DISASM_RINSN_AND_ROUND(kmmawb2);
1635   DISASM_RINSN_AND_ROUND(kmmawt2);
1636   DEFINE_RTYPE(smbb16)
1637   DEFINE_RTYPE(smbt16)
1638   DEFINE_RTYPE(smtt16)
1639   DEFINE_RTYPE(kmda)
1640   DEFINE_RTYPE(kmxda)
1641   DEFINE_RTYPE(smds)
1642   DEFINE_RTYPE(smdrs)
1643   DEFINE_RTYPE(smxds)
1644   DEFINE_RTYPE(kmabb)
1645   DEFINE_RTYPE(kmabt)
1646   DEFINE_RTYPE(kmatt)
1647   DEFINE_RTYPE(kmada)
1648   DEFINE_RTYPE(kmaxda)
1649   DEFINE_RTYPE(kmads)
1650   DEFINE_RTYPE(kmadrs)
1651   DEFINE_RTYPE(kmaxds)
1652   DEFINE_RTYPE(kmsda)
1653   DEFINE_RTYPE(kmsxda)
1654   DEFINE_RTYPE(smal)
1655   DEFINE_RTYPE(sclip32)
1656   DEFINE_RTYPE(uclip32)
1657   DEFINE_R1TYPE(clrs32);
1658   DEFINE_R1TYPE(clz32);
1659   DEFINE_RTYPE(pbsad);
1660   DEFINE_RTYPE(pbsada);
1661   DEFINE_RTYPE(smaqa);
1662   DEFINE_RTYPE(umaqa);
1663   DEFINE_RTYPE(smaqa_su);
1664 
1665   DEFINE_RTYPE(radd64);
1666   DEFINE_RTYPE(uradd64);
1667   DEFINE_RTYPE(kadd64);
1668   DEFINE_RTYPE(ukadd64);
1669   DEFINE_RTYPE(rsub64);
1670   DEFINE_RTYPE(ursub64);
1671   DEFINE_RTYPE(ksub64);
1672   DEFINE_RTYPE(uksub64);
1673   DEFINE_RTYPE(smar64);
1674   DEFINE_RTYPE(smsr64);
1675   DEFINE_RTYPE(umar64);
1676   DEFINE_RTYPE(umsr64);
1677   DEFINE_RTYPE(kmar64);
1678   DEFINE_RTYPE(kmsr64);
1679   DEFINE_RTYPE(ukmar64);
1680   DEFINE_RTYPE(ukmsr64);
1681   DEFINE_RTYPE(smalbb);
1682   DEFINE_RTYPE(smalbt);
1683   DEFINE_RTYPE(smaltt);
1684   DEFINE_RTYPE(smalda);
1685   DEFINE_RTYPE(smalxda);
1686   DEFINE_RTYPE(smalds);
1687   DEFINE_RTYPE(smaldrs);
1688   DEFINE_RTYPE(smalxds);
1689   DEFINE_RTYPE(smslda);
1690   DEFINE_RTYPE(smslxda);
1691 
1692   DEFINE_RTYPE(kaddh);
1693   DEFINE_RTYPE(ksubh);
1694   DEFINE_RTYPE(khmbb);
1695   DEFINE_RTYPE(khmbt);
1696   DEFINE_RTYPE(khmtt);
1697   DEFINE_RTYPE(ukaddh);
1698   DEFINE_RTYPE(uksubh);
1699   DEFINE_RTYPE(kaddw);
1700   DEFINE_RTYPE(ukaddw);
1701   DEFINE_RTYPE(ksubw);
1702   DEFINE_RTYPE(uksubw);
1703   DEFINE_RTYPE(kdmbb);
1704   DEFINE_RTYPE(kdmbt);
1705   DEFINE_RTYPE(kdmtt);
1706   DEFINE_RTYPE(kslraw);
1707   DEFINE_RTYPE(kslraw_u);
1708   DEFINE_RTYPE(ksllw);
1709   DEFINE_PI5TYPE(kslliw);
1710   DEFINE_RTYPE(kdmabb);
1711   DEFINE_RTYPE(kdmabt);
1712   DEFINE_RTYPE(kdmatt);
1713   DEFINE_RTYPE(kabsw);
1714   DEFINE_RTYPE(raddw);
1715   DEFINE_RTYPE(uraddw);
1716   DEFINE_RTYPE(rsubw);
1717   DEFINE_RTYPE(ursubw);
1718   DEFINE_RTYPE(max);
1719   DEFINE_RTYPE(min);
1720   DEFINE_RTYPE(mulr64);
1721   DEFINE_RTYPE(mulsr64);
1722   DEFINE_RTYPE(msubr32);
1723   DEFINE_RTYPE(ave);
1724   DEFINE_RTYPE(sra_u);
1725   DEFINE_PI5TYPE(srai_u);
1726   DEFINE_PI3TYPE(insb);
1727   DEFINE_RTYPE(maddr32)
1728 
1729   if (xlen == 32) {
1730     DISASM_INSN("c.flw", c_flw, 0, {&rvc_fp_rs2s, &rvc_lw_address});
1731     DISASM_INSN("c.flwsp", c_flwsp, 0, {&frd, &rvc_lwsp_address});
1732     DISASM_INSN("c.fsw", c_fsw, 0, {&rvc_fp_rs2s, &rvc_lw_address});
1733     DISASM_INSN("c.fswsp", c_fswsp, 0, {&rvc_fp_rs2, &rvc_swsp_address});
1734     DISASM_INSN("c.jal", c_jal, 0, {&rvc_jump_target});
1735 
1736     DEFINE_RTYPE(add64);
1737     DEFINE_RTYPE(sub64);
1738   } else {
1739     DISASM_INSN("c.ld", c_ld, 0, {&rvc_rs2s, &rvc_ld_address});
1740     DISASM_INSN("c.ldsp", c_ldsp, 0, {&xrd, &rvc_ldsp_address});
1741     DISASM_INSN("c.sd", c_sd, 0, {&rvc_rs2s, &rvc_ld_address});
1742     DISASM_INSN("c.sdsp", c_sdsp, 0, {&rvc_rs2, &rvc_sdsp_address});
1743     DISASM_INSN("c.addiw", c_addiw, 0, {&xrd, &rvc_imm});
1744 
1745     DEFINE_RTYPE(add32);
1746     DEFINE_RTYPE(radd32);
1747     DEFINE_RTYPE(uradd32);
1748     DEFINE_RTYPE(kadd32);
1749     DEFINE_RTYPE(ukadd32);
1750     DEFINE_RTYPE(sub32);
1751     DEFINE_RTYPE(rsub32);
1752     DEFINE_RTYPE(ursub32);
1753     DEFINE_RTYPE(ksub32);
1754     DEFINE_RTYPE(uksub32);
1755     DEFINE_RTYPE(cras32);
1756     DEFINE_RTYPE(rcras32);
1757     DEFINE_RTYPE(urcras32);
1758     DEFINE_RTYPE(kcras32);
1759     DEFINE_RTYPE(ukcras32);
1760     DEFINE_RTYPE(crsa32);
1761     DEFINE_RTYPE(rcrsa32);
1762     DEFINE_RTYPE(urcrsa32);
1763     DEFINE_RTYPE(kcrsa32);
1764     DEFINE_RTYPE(ukcrsa32);
1765     DEFINE_RTYPE(stas32);
1766     DEFINE_RTYPE(rstas32);
1767     DEFINE_RTYPE(urstas32);
1768     DEFINE_RTYPE(kstas32);
1769     DEFINE_RTYPE(ukstas32);
1770     DEFINE_RTYPE(stsa32);
1771     DEFINE_RTYPE(rstsa32);
1772     DEFINE_RTYPE(urstsa32);
1773     DEFINE_RTYPE(kstsa32);
1774     DEFINE_RTYPE(ukstsa32);
1775     DEFINE_RTYPE(sra32);
1776     DEFINE_PI5TYPE(srai32);
1777     DEFINE_RTYPE(sra32_u);
1778     DEFINE_PI5TYPE(srai32_u);
1779     DEFINE_RTYPE(srl32);
1780     DEFINE_PI5TYPE(srli32);
1781     DEFINE_RTYPE(srl32_u);
1782     DEFINE_PI5TYPE(srli32_u);
1783     DEFINE_RTYPE(sll32);
1784     DEFINE_PI5TYPE(slli32);
1785     DEFINE_RTYPE(ksll32);
1786     DEFINE_PI5TYPE(kslli32);
1787     DEFINE_RTYPE(kslra32);
1788     DEFINE_RTYPE(kslra32_u);
1789     DEFINE_RTYPE(smin32);
1790     DEFINE_RTYPE(umin32);
1791     DEFINE_RTYPE(smax32);
1792     DEFINE_RTYPE(umax32);
1793     DEFINE_R1TYPE(kabs32);
1794     DEFINE_RTYPE(khmbb16);
1795     DEFINE_RTYPE(khmbt16);
1796     DEFINE_RTYPE(khmtt16);
1797     DEFINE_RTYPE(kdmbb16);
1798     DEFINE_RTYPE(kdmbt16);
1799     DEFINE_RTYPE(kdmtt16);
1800     DEFINE_RTYPE(kdmabb16);
1801     DEFINE_RTYPE(kdmabt16);
1802     DEFINE_RTYPE(kdmatt16);
1803     DEFINE_RTYPE(smbt32);
1804     DEFINE_RTYPE(smtt32);
1805     DEFINE_RTYPE(kmabb32);
1806     DEFINE_RTYPE(kmabt32);
1807     DEFINE_RTYPE(kmatt32);
1808     DEFINE_RTYPE(kmda32);
1809     DEFINE_RTYPE(kmxda32);
1810     DEFINE_RTYPE(kmaxda32);
1811     DEFINE_RTYPE(kmads32);
1812     DEFINE_RTYPE(kmadrs32);
1813     DEFINE_RTYPE(kmaxds32);
1814     DEFINE_RTYPE(kmsda32);
1815     DEFINE_RTYPE(kmsxda32);
1816     DEFINE_RTYPE(smds32);
1817     DEFINE_RTYPE(smdrs32);
1818     DEFINE_RTYPE(smxds32);
1819     DEFINE_PI5TYPE(sraiw_u);
1820     DEFINE_RTYPE(pkbb32);
1821     DEFINE_RTYPE(pkbt32);
1822     DEFINE_RTYPE(pktb32);
1823     DEFINE_RTYPE(pktt32);
1824   }
1825 
1826   add_unknown_insns(this);
1827 }
1828 
lookup(insn_t insn) const1829 const disasm_insn_t* disassembler_t::lookup(insn_t insn) const
1830 {
1831   size_t idx = insn.bits() % HASH_SIZE;
1832   for (size_t j = 0; j < chain[idx].size(); j++)
1833     if(*chain[idx][j] == insn)
1834       return chain[idx][j];
1835 
1836   idx = HASH_SIZE;
1837   for (size_t j = 0; j < chain[idx].size(); j++)
1838     if(*chain[idx][j] == insn)
1839       return chain[idx][j];
1840 
1841   return NULL;
1842 }
1843 
add_insn(disasm_insn_t * insn)1844 void NOINLINE disassembler_t::add_insn(disasm_insn_t* insn)
1845 {
1846   size_t idx = HASH_SIZE;
1847   if (insn->get_mask() % HASH_SIZE == HASH_SIZE - 1)
1848     idx = insn->get_match() % HASH_SIZE;
1849   chain[idx].push_back(insn);
1850 }
1851 
~disassembler_t()1852 disassembler_t::~disassembler_t()
1853 {
1854   for (size_t i = 0; i < HASH_SIZE+1; i++)
1855     for (size_t j = 0; j < chain[i].size(); j++)
1856       delete chain[i][j];
1857 }
1858