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