1 // See LICENSE for license details.
13 virtual std::string
to_string(insn_t val
) const = 0;
17 static const char* xpr_to_string
[] = {
18 "zero", "ra", "v0", "v1", "a0", "a1", "a2", "a3",
19 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
20 "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3",
21 "s4", "s5", "s6", "s7", "s8", "s9", "sp", "tp"
24 static const char* fpr_to_string
[] = {
25 "ft0", "ft1", "fv0", "fv1", "fa0", "fa1", "fa2", "fa3",
26 "fa4", "fa5", "fa6", "fa7", "ft2", "ft3", "ft4", "ft5",
27 "ft6", "ft7", "ft8", "ft9", "fs0", "fs1", "fs2", "fs3",
28 "fs4", "fs5", "fs6", "fs7", "fs8", "fs9", "ft10", "ft11"
31 static const char* vxpr_to_string
[] = {
32 "vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7",
33 "vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15",
34 "vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23",
35 "vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31"
38 static const char* vfpr_to_string
[] = {
39 "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7",
40 "vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15",
41 "vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23",
42 "vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31"
45 class load_address_t
: public arg_t
49 virtual std::string
to_string(insn_t insn
) const
52 s
<< insn
.itype
.imm12
<< '(' << xpr_to_string
[insn
.itype
.rs1
] << ')';
57 class store_address_t
: public arg_t
61 virtual std::string
to_string(insn_t insn
) const
64 int32_t imm
= (int32_t)insn
.btype
.immlo
;
65 imm
|= insn
.btype
.immhi
<< IMMLO_BITS
;
66 s
<< imm
<< '(' << xpr_to_string
[insn
.itype
.rs1
] << ')';
71 class amo_address_t
: public arg_t
75 virtual std::string
to_string(insn_t insn
) const
78 s
<< "0(" << xpr_to_string
[insn
.itype
.rs1
] << ')';
83 class xrd_reg_t
: public arg_t
87 virtual std::string
to_string(insn_t insn
) const
89 return xpr_to_string
[insn
.itype
.rd
];
93 class xrs1_reg_t
: public arg_t
97 virtual std::string
to_string(insn_t insn
) const
99 return xpr_to_string
[insn
.itype
.rs1
];
103 class xrs2_reg_t
: public arg_t
107 virtual std::string
to_string(insn_t insn
) const
109 return xpr_to_string
[insn
.rtype
.rs2
];
113 class frd_reg_t
: public arg_t
117 virtual std::string
to_string(insn_t insn
) const
119 return fpr_to_string
[insn
.ftype
.rd
];
123 class frs1_reg_t
: public arg_t
127 virtual std::string
to_string(insn_t insn
) const
129 return fpr_to_string
[insn
.ftype
.rs1
];
133 class frs2_reg_t
: public arg_t
137 virtual std::string
to_string(insn_t insn
) const
139 return fpr_to_string
[insn
.ftype
.rs2
];
143 class frs3_reg_t
: public arg_t
147 virtual std::string
to_string(insn_t insn
) const
149 return fpr_to_string
[insn
.ftype
.rs3
];
153 class vxrd_reg_t
: public arg_t
157 virtual std::string
to_string(insn_t insn
) const
159 return vxpr_to_string
[insn
.itype
.rd
];
163 class vxrs1_reg_t
: public arg_t
167 virtual std::string
to_string(insn_t insn
) const
169 return vxpr_to_string
[insn
.itype
.rs1
];
173 class vfrd_reg_t
: public arg_t
177 virtual std::string
to_string(insn_t insn
) const
179 return vfpr_to_string
[insn
.itype
.rd
];
183 class vfrs1_reg_t
: public arg_t
187 virtual std::string
to_string(insn_t insn
) const
189 return vfpr_to_string
[insn
.itype
.rs1
];
193 class nxregs_reg_t
: public arg_t
197 virtual std::string
to_string(insn_t insn
) const
200 s
<< (insn
.itype
.imm12
& 0x3f);
205 class nfregs_reg_t
: public arg_t
209 virtual std::string
to_string(insn_t insn
) const
212 s
<< ((insn
.itype
.imm12
>> 6) & 0x3f);
217 class pcr_reg_t
: public arg_t
221 virtual std::string
to_string(insn_t insn
) const
224 s
<< "pcr" << insn
.rtype
.rs1
;
229 class imm_t
: public arg_t
233 virtual std::string
to_string(insn_t insn
) const
236 s
<< insn
.itype
.imm12
;
241 class bigimm_t
: public arg_t
245 virtual std::string
to_string(insn_t insn
) const
248 s
<< std::hex
<< "0x" << insn
.ltype
.bigimm
;
253 class branch_target_t
: public arg_t
257 virtual std::string
to_string(insn_t insn
) const
260 int32_t target
= (int32_t)insn
.btype
.immlo
;
261 target
|= insn
.btype
.immhi
<< IMMLO_BITS
;
262 target
<<= BRANCH_ALIGN_BITS
;
263 char sign
= target
>= 0 ? '+' : '-';
264 s
<< "pc " << sign
<< std::hex
<< " 0x" << abs(target
);
269 class jump_target_t
: public arg_t
273 virtual std::string
to_string(insn_t insn
) const
276 int32_t target
= (int32_t)insn
.jtype
.target
;
277 target
<<= JUMP_ALIGN_BITS
;
278 char sign
= target
>= 0 ? '+' : '-';
279 s
<< "pc " << sign
<< std::hex
<< " 0x" << abs(target
);
284 // workaround for lack of initializer_list in gcc-4.1
288 disasm_insn_t(const char* name
, uint32_t match
, uint32_t mask
)
290 init(name
, match
, mask
, 0);
292 disasm_insn_t(const char* name
, uint32_t match
, uint32_t mask
,
295 init(name
, match
, mask
, 1, a0
);
297 disasm_insn_t(const char* name
, uint32_t match
, uint32_t mask
,
298 const arg_t
* a0
, const arg_t
* a1
)
300 init(name
, match
, mask
, 2, a0
, a1
);
302 disasm_insn_t(const char* name
, uint32_t match
, uint32_t mask
,
303 const arg_t
* a0
, const arg_t
* a1
, const arg_t
* a2
)
305 init(name
, match
, mask
, 3, a0
, a1
, a2
);
307 disasm_insn_t(const char* name
, uint32_t match
, uint32_t mask
,
308 const arg_t
* a0
, const arg_t
* a1
, const arg_t
* a2
,
311 init(name
, match
, mask
, 4, a0
, a1
, a2
, a3
);
313 disasm_insn_t(const char* name
, uint32_t match
, uint32_t mask
,
314 const arg_t
* a0
, const arg_t
* a1
, const arg_t
* a2
,
315 const arg_t
* a3
, const arg_t
* a4
)
317 init(name
, match
, mask
, 5, a0
, a1
, a2
, a3
, a4
);
320 bool operator == (insn_t insn
) const
322 return (insn
.bits
& mask
) == match
;
325 std::string
to_string(insn_t insn
) const
329 for (len
= 0; name
[len
]; len
++)
330 s
<< (name
[len
] == '_' ? '.' : name
[len
]);
334 s
<< std::string(std::max(1, 8 - len
), ' ');
335 for (size_t i
= 0; i
< args
.size()-1; i
++)
336 s
<< args
[i
]->to_string(insn
) << ", ";
337 s
<< args
[args
.size()-1]->to_string(insn
);
342 uint32_t get_match() const { return match
; }
343 uint32_t get_mask() const { return mask
; }
348 std::vector
<const arg_t
*> args
;
351 void init(const char* name
, uint32_t match
, uint32_t mask
, int n
, ...)
355 for (int i
= 0; i
< n
; i
++)
356 args
.push_back(va_arg(vl
, const arg_t
*));
364 std::string
disassembler::disassemble(insn_t insn
)
366 const disasm_insn_t
* disasm_insn
= lookup(insn
);
367 return disasm_insn
? disasm_insn
->to_string(insn
) : "unknown";
370 disassembler::disassembler()
372 static const xrd_reg_t _xrd_reg
, *xrd_reg
= &_xrd_reg
;
373 static const xrs1_reg_t _xrs1_reg
, *xrs1_reg
= &_xrs1_reg
;
374 static const load_address_t _load_address
, *load_address
= &_load_address
;
375 static const store_address_t _store_address
, *store_address
= &_store_address
;
376 static const amo_address_t _amo_address
, *amo_address
= &_amo_address
;
377 static const xrs2_reg_t _xrs2_reg
, *xrs2_reg
= &_xrs2_reg
;
378 static const frd_reg_t _frd_reg
, *frd_reg
= &_frd_reg
;
379 static const frs1_reg_t _frs1_reg
, *frs1_reg
= &_frs1_reg
;
380 static const frs2_reg_t _frs2_reg
, *frs2_reg
= &_frs2_reg
;
381 static const frs3_reg_t _frs3_reg
, *frs3_reg
= &_frs3_reg
;
382 static const pcr_reg_t _pcr_reg
, *pcr_reg
= &_pcr_reg
;
383 static const imm_t _imm
, *imm
= &_imm
;
384 static const bigimm_t _bigimm
, *bigimm
= &_bigimm
;
385 static const branch_target_t _branch_target
, *branch_target
= &_branch_target
;
386 static const jump_target_t _jump_target
, *jump_target
= &_jump_target
;
387 static const vxrd_reg_t _vxrd_reg
, *vxrd_reg
= &_vxrd_reg
;
388 static const vxrs1_reg_t _vxrs1_reg
, *vxrs1_reg
= &_vxrs1_reg
;
389 static const vfrd_reg_t _vfrd_reg
, *vfrd_reg
= &_vfrd_reg
;
390 static const vfrs1_reg_t _vfrs1_reg
, *vfrs1_reg
= &_vfrs1_reg
;
391 static const nxregs_reg_t _nxregs_reg
, *nxregs_reg
= &_nxregs_reg
;
392 static const nfregs_reg_t _nfregs_reg
, *nfregs_reg
= &_nfregs_reg
;
395 dummy
.bits
= -1, dummy
.rtype
.rs1
= 0;
396 uint32_t mask_rs1
= ~dummy
.bits
;
397 dummy
.bits
= -1, dummy
.rtype
.rs2
= 0;
398 uint32_t mask_rs2
= ~dummy
.bits
;
399 dummy
.bits
= -1, dummy
.rtype
.rd
= 0;
400 uint32_t mask_rd
= ~dummy
.bits
;
401 dummy
.bits
= -1, dummy
.itype
.imm12
= 0;
402 uint32_t mask_imm
= ~dummy
.bits
;
403 dummy
.bits
= 0, dummy
.itype
.rd
= 1;
404 uint32_t match_rd_ra
= dummy
.bits
;
405 dummy
.bits
= 0, dummy
.itype
.rs1
= 1;
406 uint32_t match_rs1_ra
= dummy
.bits
;
408 #define DECLARE_INSN(code, match, mask) \
409 const uint32_t __attribute__((unused)) match_##code = match; \
410 const uint32_t __attribute__((unused)) mask_##code = mask;
414 // explicit per-instruction disassembly
415 #define DISASM_INSN(name, code, extra, ...) \
416 add_insn(new disasm_insn_t(name, match_##code, mask_##code | (extra), __VA_ARGS__));
417 #define DEFINE_NOARG(code) \
418 add_insn(new disasm_insn_t(#code, match_##code, mask_##code));
419 #define DEFINE_DTYPE(code) DISASM_INSN(#code, code, 0, xrd_reg)
420 #define DEFINE_RTYPE(code) DISASM_INSN(#code, code, 0, xrd_reg, xrs1_reg, xrs2_reg)
421 #define DEFINE_ITYPE(code) DISASM_INSN(#code, code, 0, xrd_reg, xrs1_reg, imm)
422 #define DEFINE_I0TYPE(name, code) DISASM_INSN(name, code, mask_rs1, xrd_reg, imm)
423 #define DEFINE_I1TYPE(name, code) DISASM_INSN(name, code, mask_imm, xrd_reg, xrs1_reg)
424 #define DEFINE_I2TYPE(name, code) DISASM_INSN(name, code, mask_rd | mask_imm, xrs1_reg)
425 #define DEFINE_LTYPE(code) DISASM_INSN(#code, code, 0, xrd_reg, bigimm)
426 #define DEFINE_BTYPE(code) DISASM_INSN(#code, code, 0, xrs1_reg, xrs2_reg, branch_target)
427 #define DEFINE_B0TYPE(name, code) DISASM_INSN(name, code, mask_rs1 | mask_rs2, branch_target)
428 #define DEFINE_B1TYPE(name, code) DISASM_INSN(name, code, mask_rs2, xrs1_reg, branch_target)
429 #define DEFINE_JTYPE(code) DISASM_INSN(#code, code, 0, jump_target)
430 #define DEFINE_XLOAD(code) DISASM_INSN(#code, code, 0, xrd_reg, load_address)
431 #define DEFINE_XSTORE(code) DISASM_INSN(#code, code, 0, xrs2_reg, store_address)
432 #define DEFINE_XAMO(code) DISASM_INSN(#code, code, 0, xrd_reg, xrs2_reg, amo_address)
433 #define DEFINE_FLOAD(code) DISASM_INSN(#code, code, 0, frd_reg, load_address)
434 #define DEFINE_FSTORE(code) DISASM_INSN(#code, code, 0, frs2_reg, store_address)
435 #define DEFINE_FRTYPE(code) DISASM_INSN(#code, code, 0, frd_reg, frs1_reg, frs2_reg)
436 #define DEFINE_FR1TYPE(code) DISASM_INSN(#code, code, 0, frd_reg, frs1_reg)
437 #define DEFINE_FR3TYPE(code) DISASM_INSN(#code, code, 0, frd_reg, frs1_reg, frs2_reg, frs3_reg)
438 #define DEFINE_FXTYPE(code) DISASM_INSN(#code, code, 0, xrd_reg, frs1_reg)
439 #define DEFINE_XFTYPE(code) DISASM_INSN(#code, code, 0, frd_reg, xrs1_reg)
441 #define DEFINE_RS1(code) DISASM_INSN(#code, code, 0, xrs1_reg)
442 #define DEFINE_RS1_RS2(code) DISASM_INSN(#code, code, 0, xrs1_reg, xrs2_reg)
443 #define DEFINE_VEC_XMEM(code) DISASM_INSN(#code, code, 0, vxrd_reg, xrs1_reg)
444 #define DEFINE_VEC_XMEMST(code) DISASM_INSN(#code, code, 0, vxrd_reg, xrs1_reg, xrs2_reg)
445 #define DEFINE_VEC_FMEM(code) DISASM_INSN(#code, code, 0, vfrd_reg, xrs1_reg)
446 #define DEFINE_VEC_FMEMST(code) DISASM_INSN(#code, code, 0, vfrd_reg, xrs1_reg, xrs2_reg)
461 DEFINE_XAMO(amoadd_w
)
462 DEFINE_XAMO(amoswap_w
)
463 DEFINE_XAMO(amoand_w
)
465 DEFINE_XAMO(amomin_w
)
466 DEFINE_XAMO(amomax_w
)
467 DEFINE_XAMO(amominu_w
)
468 DEFINE_XAMO(amomaxu_w
)
469 DEFINE_XAMO(amoadd_d
)
470 DEFINE_XAMO(amoswap_d
)
471 DEFINE_XAMO(amoand_d
)
473 DEFINE_XAMO(amomin_d
)
474 DEFINE_XAMO(amomax_d
)
475 DEFINE_XAMO(amominu_d
)
476 DEFINE_XAMO(amomaxu_d
)
487 DEFINE_B0TYPE("b", beq
);
488 DEFINE_B1TYPE("beqz", beq
);
489 DEFINE_B1TYPE("bnez", bne
);
490 DEFINE_B1TYPE("bltz", blt
);
491 DEFINE_B1TYPE("bgez", bge
);
501 DEFINE_I2TYPE("jr", jalr_j
);
502 add_insn(new disasm_insn_t("jalr", match_jalr_c
| match_rd_ra
, mask_jalr_c
| mask_rd
| mask_imm
, xrs1_reg
));
503 add_insn(new disasm_insn_t("ret", match_jalr_r
| match_rs1_ra
, mask_jalr_r
| mask_rd
| mask_rs1
| mask_imm
));
505 DEFINE_ITYPE(jalr_c
);
506 DEFINE_ITYPE(jalr_r
);
507 DEFINE_ITYPE(jalr_j
);
509 add_insn(new disasm_insn_t("nop", match_addi
, mask_addi
| mask_rd
| mask_rs1
| mask_imm
));
510 DEFINE_I0TYPE("li", addi
);
511 DEFINE_I1TYPE("move", addi
);
539 DEFINE_RTYPE(mulhsu
);
555 DEFINE_NOARG(syscall
);
558 DEFINE_NOARG(fence_i
);
560 DEFINE_DTYPE(rdcycle
);
561 DEFINE_DTYPE(rdtime
);
562 DEFINE_DTYPE(rdinstret
);
564 add_insn(new disasm_insn_t("mtpcr", match_mtpcr
, mask_mtpcr
| mask_rd
, xrs2_reg
, pcr_reg
));
565 add_insn(new disasm_insn_t("mtpcr", match_mtpcr
, mask_mtpcr
, xrd_reg
, xrs2_reg
, pcr_reg
));
566 add_insn(new disasm_insn_t("mfpcr", match_mfpcr
, mask_mfpcr
, xrd_reg
, pcr_reg
));
567 add_insn(new disasm_insn_t("setpcr", match_setpcr
, mask_setpcr
, xrd_reg
, pcr_reg
, imm
));
568 add_insn(new disasm_insn_t("clearpcr", match_clearpcr
, mask_clearpcr
, xrd_reg
, pcr_reg
, imm
));
572 DEFINE_RS1(vxcptsave
);
573 DEFINE_RS1(vxcptrestore
);
574 DEFINE_NOARG(vxcptkill
);
576 DEFINE_RS1(vxcptevac
);
577 DEFINE_NOARG(vxcpthold
);
578 DEFINE_RS1_RS2(venqcmd
);
579 DEFINE_RS1_RS2(venqimm1
);
580 DEFINE_RS1_RS2(venqimm2
);
581 DEFINE_RS1_RS2(venqcnt
);
583 DEFINE_FRTYPE(fadd_s
);
584 DEFINE_FRTYPE(fsub_s
);
585 DEFINE_FRTYPE(fmul_s
);
586 DEFINE_FRTYPE(fdiv_s
);
587 DEFINE_FR1TYPE(fsqrt_s
);
588 DEFINE_FRTYPE(fmin_s
);
589 DEFINE_FRTYPE(fmax_s
);
590 DEFINE_FR3TYPE(fmadd_s
);
591 DEFINE_FR3TYPE(fmsub_s
);
592 DEFINE_FR3TYPE(fnmadd_s
);
593 DEFINE_FR3TYPE(fnmsub_s
);
594 DEFINE_FRTYPE(fsgnj_s
);
595 DEFINE_FRTYPE(fsgnjn_s
);
596 DEFINE_FRTYPE(fsgnjx_s
);
597 DEFINE_FR1TYPE(fcvt_s_d
);
598 DEFINE_XFTYPE(fcvt_s_l
);
599 DEFINE_XFTYPE(fcvt_s_lu
);
600 DEFINE_XFTYPE(fcvt_s_w
);
601 DEFINE_XFTYPE(fcvt_s_wu
);
602 DEFINE_XFTYPE(fcvt_s_wu
);
603 DEFINE_XFTYPE(mxtf_s
);
604 DEFINE_FXTYPE(fcvt_l_s
);
605 DEFINE_FXTYPE(fcvt_lu_s
);
606 DEFINE_FXTYPE(fcvt_w_s
);
607 DEFINE_FXTYPE(fcvt_wu_s
);
608 DEFINE_FXTYPE(mftx_s
);
609 DEFINE_FXTYPE(feq_s
);
610 DEFINE_FXTYPE(flt_s
);
611 DEFINE_FXTYPE(fle_s
);
613 DEFINE_FRTYPE(fadd_d
);
614 DEFINE_FRTYPE(fsub_d
);
615 DEFINE_FRTYPE(fmul_d
);
616 DEFINE_FRTYPE(fdiv_d
);
617 DEFINE_FR1TYPE(fsqrt_d
);
618 DEFINE_FRTYPE(fmin_d
);
619 DEFINE_FRTYPE(fmax_d
);
620 DEFINE_FR3TYPE(fmadd_d
);
621 DEFINE_FR3TYPE(fmsub_d
);
622 DEFINE_FR3TYPE(fnmadd_d
);
623 DEFINE_FR3TYPE(fnmsub_d
);
624 DEFINE_FRTYPE(fsgnj_d
);
625 DEFINE_FRTYPE(fsgnjn_d
);
626 DEFINE_FRTYPE(fsgnjx_d
);
627 DEFINE_FR1TYPE(fcvt_d_s
);
628 DEFINE_XFTYPE(fcvt_d_l
);
629 DEFINE_XFTYPE(fcvt_d_lu
);
630 DEFINE_XFTYPE(fcvt_d_w
);
631 DEFINE_XFTYPE(fcvt_d_wu
);
632 DEFINE_XFTYPE(fcvt_d_wu
);
633 DEFINE_XFTYPE(mxtf_d
);
634 DEFINE_FXTYPE(fcvt_l_d
);
635 DEFINE_FXTYPE(fcvt_lu_d
);
636 DEFINE_FXTYPE(fcvt_w_d
);
637 DEFINE_FXTYPE(fcvt_wu_d
);
638 DEFINE_FXTYPE(mftx_d
);
639 DEFINE_FXTYPE(feq_d
);
640 DEFINE_FXTYPE(flt_d
);
641 DEFINE_FXTYPE(fle_d
);
643 add_insn(new disasm_insn_t("mtfsr", match_mtfsr
, mask_mtfsr
| mask_rd
, xrs1_reg
));
644 add_insn(new disasm_insn_t("mtfsr", match_mtfsr
, mask_mtfsr
, xrd_reg
, xrs1_reg
));
647 DEFINE_VEC_XMEM(vld
);
648 DEFINE_VEC_XMEM(vlw
);
649 DEFINE_VEC_XMEM(vlwu
);
650 DEFINE_VEC_XMEM(vlh
);
651 DEFINE_VEC_XMEM(vlhu
);
652 DEFINE_VEC_XMEM(vlb
);
653 DEFINE_VEC_XMEM(vlbu
);
654 DEFINE_VEC_FMEM(vfld
);
655 DEFINE_VEC_FMEM(vflw
);
656 DEFINE_VEC_XMEMST(vlstd
);
657 DEFINE_VEC_XMEMST(vlstw
);
658 DEFINE_VEC_XMEMST(vlstwu
);
659 DEFINE_VEC_XMEMST(vlsth
);
660 DEFINE_VEC_XMEMST(vlsthu
);
661 DEFINE_VEC_XMEMST(vlstb
);
662 DEFINE_VEC_XMEMST(vlstbu
);
663 DEFINE_VEC_FMEMST(vflstd
);
664 DEFINE_VEC_FMEMST(vflstw
);
666 DEFINE_VEC_XMEM(vsd
);
667 DEFINE_VEC_XMEM(vsw
);
668 DEFINE_VEC_XMEM(vsh
);
669 DEFINE_VEC_XMEM(vsb
);
670 DEFINE_VEC_FMEM(vfsd
);
671 DEFINE_VEC_FMEM(vfsw
);
672 DEFINE_VEC_XMEMST(vsstd
);
673 DEFINE_VEC_XMEMST(vsstw
);
674 DEFINE_VEC_XMEMST(vssth
);
675 DEFINE_VEC_XMEMST(vsstb
);
676 DEFINE_VEC_FMEMST(vfsstd
);
677 DEFINE_VEC_FMEMST(vfsstw
);
679 DISASM_INSN("vmvv", vmvv
, 0, vxrd_reg
, vxrs1_reg
);
680 DISASM_INSN("vmsv", vmsv
, 0, vxrd_reg
, xrs1_reg
);
681 DISASM_INSN("vmst", vmst
, 0, vxrd_reg
, xrs1_reg
, xrs2_reg
);
682 DISASM_INSN("vmts", vmts
, 0, xrd_reg
, vxrs1_reg
, xrs2_reg
);
683 DISASM_INSN("vfmvv", vfmvv
, 0, vfrd_reg
, vfrs1_reg
);
684 DISASM_INSN("vfmsv", vfmsv
, 0, vfrd_reg
, frs1_reg
);
685 DISASM_INSN("vfmst", vfmst
, 0, vfrd_reg
, frs1_reg
, frs2_reg
);
686 DISASM_INSN("vfmts", vfmts
, 0, frd_reg
, vfrs1_reg
, frs2_reg
);
688 DEFINE_RS1_RS2(vvcfg
);
689 DEFINE_RS1_RS2(vtcfg
);
691 DISASM_INSN("vvcfgivl", vvcfgivl
, 0, xrd_reg
, xrs1_reg
, nxregs_reg
, nfregs_reg
);
692 DISASM_INSN("vtcfgivl", vtcfgivl
, 0, xrd_reg
, xrs1_reg
, nxregs_reg
, nfregs_reg
);
693 DISASM_INSN("vsetvl", vsetvl
, 0, xrd_reg
, xrs1_reg
);
694 DISASM_INSN("vf", vf
, 0, xrs1_reg
, imm
);
696 DEFINE_NOARG(fence_v_l
);
697 DEFINE_NOARG(fence_v_g
);
699 // provide a default disassembly for all instructions as a fallback
700 #define DECLARE_INSN(code, match, mask) \
701 add_insn(new disasm_insn_t(#code " (args unknown)", match, mask));
706 const disasm_insn_t
* disassembler::lookup(insn_t insn
)
708 size_t idx
= insn
.bits
% HASH_SIZE
;
709 for (size_t j
= 0; j
< chain
[idx
].size(); j
++)
710 if(*chain
[idx
][j
] == insn
)
711 return chain
[idx
][j
];
714 for (size_t j
= 0; j
< chain
[idx
].size(); j
++)
715 if(*chain
[idx
][j
] == insn
)
716 return chain
[idx
][j
];
721 void disassembler::add_insn(disasm_insn_t
* insn
)
723 size_t idx
= HASH_SIZE
;
724 if (insn
->get_mask() % HASH_SIZE
== HASH_SIZE
- 1)
725 idx
= insn
->get_match() % HASH_SIZE
;
726 chain
[idx
].push_back(insn
);
729 disassembler::~disassembler()
731 for (size_t i
= 0; i
< HASH_SIZE
+1; i
++)
732 for (size_t j
= 0; j
< chain
[i
].size(); j
++)