2 * QEMU RISC-V Disassembler
4 * Copyright (c) 2016-2017 Michael Clark <michaeljclark@mac.com>
5 * Copyright (c) 2017-2018 SiFive, Inc.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2 or later, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "disas/dis-asm.h"
26 typedef uint64_t rv_inst
;
27 typedef uint16_t rv_opcode
;
246 rv_op_amoswap_w
= 84,
253 rv_op_amominu_w
= 91,
254 rv_op_amomaxu_w
= 92,
257 rv_op_amoswap_d
= 95,
262 rv_op_amomin_d
= 100,
263 rv_op_amomax_d
= 101,
264 rv_op_amominu_d
= 102,
265 rv_op_amomaxu_d
= 103,
268 rv_op_amoswap_q
= 106,
269 rv_op_amoadd_q
= 107,
270 rv_op_amoxor_q
= 108,
272 rv_op_amoand_q
= 110,
273 rv_op_amomin_q
= 111,
274 rv_op_amomax_q
= 112,
275 rv_op_amominu_q
= 113,
276 rv_op_amomaxu_q
= 114,
284 rv_op_sfence_vm
= 122,
285 rv_op_sfence_vma
= 123,
297 rv_op_fnmsub_s
= 135,
298 rv_op_fnmadd_s
= 136,
304 rv_op_fsgnjn_s
= 142,
305 rv_op_fsgnjx_s
= 143,
312 rv_op_fcvt_w_s
= 150,
313 rv_op_fcvt_wu_s
= 151,
314 rv_op_fcvt_s_w
= 152,
315 rv_op_fcvt_s_wu
= 153,
317 rv_op_fclass_s
= 155,
319 rv_op_fcvt_l_s
= 157,
320 rv_op_fcvt_lu_s
= 158,
321 rv_op_fcvt_s_l
= 159,
322 rv_op_fcvt_s_lu
= 160,
327 rv_op_fnmsub_d
= 165,
328 rv_op_fnmadd_d
= 166,
334 rv_op_fsgnjn_d
= 172,
335 rv_op_fsgnjx_d
= 173,
338 rv_op_fcvt_s_d
= 176,
339 rv_op_fcvt_d_s
= 177,
344 rv_op_fcvt_w_d
= 182,
345 rv_op_fcvt_wu_d
= 183,
346 rv_op_fcvt_d_w
= 184,
347 rv_op_fcvt_d_wu
= 185,
348 rv_op_fclass_d
= 186,
349 rv_op_fcvt_l_d
= 187,
350 rv_op_fcvt_lu_d
= 188,
352 rv_op_fcvt_d_l
= 190,
353 rv_op_fcvt_d_lu
= 191,
359 rv_op_fnmsub_q
= 197,
360 rv_op_fnmadd_q
= 198,
366 rv_op_fsgnjn_q
= 204,
367 rv_op_fsgnjx_q
= 205,
370 rv_op_fcvt_s_q
= 208,
371 rv_op_fcvt_q_s
= 209,
372 rv_op_fcvt_d_q
= 210,
373 rv_op_fcvt_q_d
= 211,
378 rv_op_fcvt_w_q
= 216,
379 rv_op_fcvt_wu_q
= 217,
380 rv_op_fcvt_q_w
= 218,
381 rv_op_fcvt_q_wu
= 219,
382 rv_op_fclass_q
= 220,
383 rv_op_fcvt_l_q
= 221,
384 rv_op_fcvt_lu_q
= 222,
385 rv_op_fcvt_q_l
= 223,
386 rv_op_fcvt_q_lu
= 224,
389 rv_op_c_addi4spn
= 227,
400 rv_op_c_addi16sp
= 238,
420 rv_op_c_ebreak
= 258,
469 rv_op_rdinstret
= 307,
470 rv_op_rdcycleh
= 308,
472 rv_op_rdinstreth
= 310,
480 rv_op_fsflagsi
= 318,
499 rv_op_sh1add_uw
= 337,
500 rv_op_sh2add_uw
= 338,
501 rv_op_sh3add_uw
= 339,
547 const rvc_constraint
*constraints
;
555 const char * const name
;
556 const rv_codec codec
;
557 const char * const format
;
558 const rv_comp_data
*pseudo
;
559 const short decomp_rv32
;
560 const short decomp_rv64
;
561 const short decomp_rv128
;
562 const short decomp_data
;
567 static const char rv_ireg_name_sym
[32][5] = {
568 "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
569 "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
570 "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
571 "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6",
574 static const char rv_freg_name_sym
[32][5] = {
575 "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
576 "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
577 "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
578 "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11",
581 /* instruction formats */
583 #define rv_fmt_none "O\t"
584 #define rv_fmt_rs1 "O\t1"
585 #define rv_fmt_offset "O\to"
586 #define rv_fmt_pred_succ "O\tp,s"
587 #define rv_fmt_rs1_rs2 "O\t1,2"
588 #define rv_fmt_rd_imm "O\t0,i"
589 #define rv_fmt_rd_offset "O\t0,o"
590 #define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
591 #define rv_fmt_frd_rs1 "O\t3,1"
592 #define rv_fmt_rd_frs1 "O\t0,4"
593 #define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
594 #define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
595 #define rv_fmt_rm_frd_frs1 "O\tr,3,4"
596 #define rv_fmt_rm_frd_rs1 "O\tr,3,1"
597 #define rv_fmt_rm_rd_frs1 "O\tr,0,4"
598 #define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5"
599 #define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6"
600 #define rv_fmt_rd_rs1_imm "O\t0,1,i"
601 #define rv_fmt_rd_rs1_offset "O\t0,1,i"
602 #define rv_fmt_rd_offset_rs1 "O\t0,i(1)"
603 #define rv_fmt_frd_offset_rs1 "O\t3,i(1)"
604 #define rv_fmt_rd_csr_rs1 "O\t0,c,1"
605 #define rv_fmt_rd_csr_zimm "O\t0,c,7"
606 #define rv_fmt_rs2_offset_rs1 "O\t2,i(1)"
607 #define rv_fmt_frs2_offset_rs1 "O\t5,i(1)"
608 #define rv_fmt_rs1_rs2_offset "O\t1,2,o"
609 #define rv_fmt_rs2_rs1_offset "O\t2,1,o"
610 #define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)"
611 #define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)"
612 #define rv_fmt_rd "O\t0"
613 #define rv_fmt_rd_zimm "O\t0,7"
614 #define rv_fmt_rd_rs1 "O\t0,1"
615 #define rv_fmt_rd_rs2 "O\t0,2"
616 #define rv_fmt_rs1_offset "O\t1,o"
617 #define rv_fmt_rs2_offset "O\t2,o"
619 /* pseudo-instruction constraints */
621 static const rvc_constraint rvcc_jal
[] = { rvc_rd_eq_ra
, rvc_end
};
622 static const rvc_constraint rvcc_jalr
[] = { rvc_rd_eq_ra
, rvc_imm_eq_zero
, rvc_end
};
623 static const rvc_constraint rvcc_nop
[] = { rvc_rd_eq_x0
, rvc_rs1_eq_x0
, rvc_imm_eq_zero
, rvc_end
};
624 static const rvc_constraint rvcc_mv
[] = { rvc_imm_eq_zero
, rvc_end
};
625 static const rvc_constraint rvcc_not
[] = { rvc_imm_eq_n1
, rvc_end
};
626 static const rvc_constraint rvcc_neg
[] = { rvc_rs1_eq_x0
, rvc_end
};
627 static const rvc_constraint rvcc_negw
[] = { rvc_rs1_eq_x0
, rvc_end
};
628 static const rvc_constraint rvcc_sext_w
[] = { rvc_imm_eq_zero
, rvc_end
};
629 static const rvc_constraint rvcc_seqz
[] = { rvc_imm_eq_p1
, rvc_end
};
630 static const rvc_constraint rvcc_snez
[] = { rvc_rs1_eq_x0
, rvc_end
};
631 static const rvc_constraint rvcc_sltz
[] = { rvc_rs2_eq_x0
, rvc_end
};
632 static const rvc_constraint rvcc_sgtz
[] = { rvc_rs1_eq_x0
, rvc_end
};
633 static const rvc_constraint rvcc_fmv_s
[] = { rvc_rs2_eq_rs1
, rvc_end
};
634 static const rvc_constraint rvcc_fabs_s
[] = { rvc_rs2_eq_rs1
, rvc_end
};
635 static const rvc_constraint rvcc_fneg_s
[] = { rvc_rs2_eq_rs1
, rvc_end
};
636 static const rvc_constraint rvcc_fmv_d
[] = { rvc_rs2_eq_rs1
, rvc_end
};
637 static const rvc_constraint rvcc_fabs_d
[] = { rvc_rs2_eq_rs1
, rvc_end
};
638 static const rvc_constraint rvcc_fneg_d
[] = { rvc_rs2_eq_rs1
, rvc_end
};
639 static const rvc_constraint rvcc_fmv_q
[] = { rvc_rs2_eq_rs1
, rvc_end
};
640 static const rvc_constraint rvcc_fabs_q
[] = { rvc_rs2_eq_rs1
, rvc_end
};
641 static const rvc_constraint rvcc_fneg_q
[] = { rvc_rs2_eq_rs1
, rvc_end
};
642 static const rvc_constraint rvcc_beqz
[] = { rvc_rs2_eq_x0
, rvc_end
};
643 static const rvc_constraint rvcc_bnez
[] = { rvc_rs2_eq_x0
, rvc_end
};
644 static const rvc_constraint rvcc_blez
[] = { rvc_rs1_eq_x0
, rvc_end
};
645 static const rvc_constraint rvcc_bgez
[] = { rvc_rs2_eq_x0
, rvc_end
};
646 static const rvc_constraint rvcc_bltz
[] = { rvc_rs2_eq_x0
, rvc_end
};
647 static const rvc_constraint rvcc_bgtz
[] = { rvc_rs1_eq_x0
, rvc_end
};
648 static const rvc_constraint rvcc_ble
[] = { rvc_end
};
649 static const rvc_constraint rvcc_bleu
[] = { rvc_end
};
650 static const rvc_constraint rvcc_bgt
[] = { rvc_end
};
651 static const rvc_constraint rvcc_bgtu
[] = { rvc_end
};
652 static const rvc_constraint rvcc_j
[] = { rvc_rd_eq_x0
, rvc_end
};
653 static const rvc_constraint rvcc_ret
[] = { rvc_rd_eq_x0
, rvc_rs1_eq_ra
, rvc_end
};
654 static const rvc_constraint rvcc_jr
[] = { rvc_rd_eq_x0
, rvc_imm_eq_zero
, rvc_end
};
655 static const rvc_constraint rvcc_rdcycle
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0xc00
, rvc_end
};
656 static const rvc_constraint rvcc_rdtime
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0xc01
, rvc_end
};
657 static const rvc_constraint rvcc_rdinstret
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0xc02
, rvc_end
};
658 static const rvc_constraint rvcc_rdcycleh
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0xc80
, rvc_end
};
659 static const rvc_constraint rvcc_rdtimeh
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0xc81
, rvc_end
};
660 static const rvc_constraint rvcc_rdinstreth
[] = { rvc_rs1_eq_x0
,
661 rvc_csr_eq_0xc82
, rvc_end
};
662 static const rvc_constraint rvcc_frcsr
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0x003
, rvc_end
};
663 static const rvc_constraint rvcc_frrm
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0x002
, rvc_end
};
664 static const rvc_constraint rvcc_frflags
[] = { rvc_rs1_eq_x0
, rvc_csr_eq_0x001
, rvc_end
};
665 static const rvc_constraint rvcc_fscsr
[] = { rvc_csr_eq_0x003
, rvc_end
};
666 static const rvc_constraint rvcc_fsrm
[] = { rvc_csr_eq_0x002
, rvc_end
};
667 static const rvc_constraint rvcc_fsflags
[] = { rvc_csr_eq_0x001
, rvc_end
};
668 static const rvc_constraint rvcc_fsrmi
[] = { rvc_csr_eq_0x002
, rvc_end
};
669 static const rvc_constraint rvcc_fsflagsi
[] = { rvc_csr_eq_0x001
, rvc_end
};
671 /* pseudo-instruction metadata */
673 static const rv_comp_data rvcp_jal
[] = {
675 { rv_op_jal
, rvcc_jal
},
676 { rv_op_illegal
, NULL
}
679 static const rv_comp_data rvcp_jalr
[] = {
680 { rv_op_ret
, rvcc_ret
},
681 { rv_op_jr
, rvcc_jr
},
682 { rv_op_jalr
, rvcc_jalr
},
683 { rv_op_illegal
, NULL
}
686 static const rv_comp_data rvcp_beq
[] = {
687 { rv_op_beqz
, rvcc_beqz
},
688 { rv_op_illegal
, NULL
}
691 static const rv_comp_data rvcp_bne
[] = {
692 { rv_op_bnez
, rvcc_bnez
},
693 { rv_op_illegal
, NULL
}
696 static const rv_comp_data rvcp_blt
[] = {
697 { rv_op_bltz
, rvcc_bltz
},
698 { rv_op_bgtz
, rvcc_bgtz
},
699 { rv_op_bgt
, rvcc_bgt
},
700 { rv_op_illegal
, NULL
}
703 static const rv_comp_data rvcp_bge
[] = {
704 { rv_op_blez
, rvcc_blez
},
705 { rv_op_bgez
, rvcc_bgez
},
706 { rv_op_ble
, rvcc_ble
},
707 { rv_op_illegal
, NULL
}
710 static const rv_comp_data rvcp_bltu
[] = {
711 { rv_op_bgtu
, rvcc_bgtu
},
712 { rv_op_illegal
, NULL
}
715 static const rv_comp_data rvcp_bgeu
[] = {
716 { rv_op_bleu
, rvcc_bleu
},
717 { rv_op_illegal
, NULL
}
720 static const rv_comp_data rvcp_addi
[] = {
721 { rv_op_nop
, rvcc_nop
},
722 { rv_op_mv
, rvcc_mv
},
723 { rv_op_illegal
, NULL
}
726 static const rv_comp_data rvcp_sltiu
[] = {
727 { rv_op_seqz
, rvcc_seqz
},
728 { rv_op_illegal
, NULL
}
731 static const rv_comp_data rvcp_xori
[] = {
732 { rv_op_not
, rvcc_not
},
733 { rv_op_illegal
, NULL
}
736 static const rv_comp_data rvcp_sub
[] = {
737 { rv_op_neg
, rvcc_neg
},
738 { rv_op_illegal
, NULL
}
741 static const rv_comp_data rvcp_slt
[] = {
742 { rv_op_sltz
, rvcc_sltz
},
743 { rv_op_sgtz
, rvcc_sgtz
},
744 { rv_op_illegal
, NULL
}
747 static const rv_comp_data rvcp_sltu
[] = {
748 { rv_op_snez
, rvcc_snez
},
749 { rv_op_illegal
, NULL
}
752 static const rv_comp_data rvcp_addiw
[] = {
753 { rv_op_sext_w
, rvcc_sext_w
},
754 { rv_op_illegal
, NULL
}
757 static const rv_comp_data rvcp_subw
[] = {
758 { rv_op_negw
, rvcc_negw
},
759 { rv_op_illegal
, NULL
}
762 static const rv_comp_data rvcp_csrrw
[] = {
763 { rv_op_fscsr
, rvcc_fscsr
},
764 { rv_op_fsrm
, rvcc_fsrm
},
765 { rv_op_fsflags
, rvcc_fsflags
},
766 { rv_op_illegal
, NULL
}
769 static const rv_comp_data rvcp_csrrs
[] = {
770 { rv_op_rdcycle
, rvcc_rdcycle
},
771 { rv_op_rdtime
, rvcc_rdtime
},
772 { rv_op_rdinstret
, rvcc_rdinstret
},
773 { rv_op_rdcycleh
, rvcc_rdcycleh
},
774 { rv_op_rdtimeh
, rvcc_rdtimeh
},
775 { rv_op_rdinstreth
, rvcc_rdinstreth
},
776 { rv_op_frcsr
, rvcc_frcsr
},
777 { rv_op_frrm
, rvcc_frrm
},
778 { rv_op_frflags
, rvcc_frflags
},
779 { rv_op_illegal
, NULL
}
782 static const rv_comp_data rvcp_csrrwi
[] = {
783 { rv_op_fsrmi
, rvcc_fsrmi
},
784 { rv_op_fsflagsi
, rvcc_fsflagsi
},
785 { rv_op_illegal
, NULL
}
788 static const rv_comp_data rvcp_fsgnj_s
[] = {
789 { rv_op_fmv_s
, rvcc_fmv_s
},
790 { rv_op_illegal
, NULL
}
793 static const rv_comp_data rvcp_fsgnjn_s
[] = {
794 { rv_op_fneg_s
, rvcc_fneg_s
},
795 { rv_op_illegal
, NULL
}
798 static const rv_comp_data rvcp_fsgnjx_s
[] = {
799 { rv_op_fabs_s
, rvcc_fabs_s
},
800 { rv_op_illegal
, NULL
}
803 static const rv_comp_data rvcp_fsgnj_d
[] = {
804 { rv_op_fmv_d
, rvcc_fmv_d
},
805 { rv_op_illegal
, NULL
}
808 static const rv_comp_data rvcp_fsgnjn_d
[] = {
809 { rv_op_fneg_d
, rvcc_fneg_d
},
810 { rv_op_illegal
, NULL
}
813 static const rv_comp_data rvcp_fsgnjx_d
[] = {
814 { rv_op_fabs_d
, rvcc_fabs_d
},
815 { rv_op_illegal
, NULL
}
818 static const rv_comp_data rvcp_fsgnj_q
[] = {
819 { rv_op_fmv_q
, rvcc_fmv_q
},
820 { rv_op_illegal
, NULL
}
823 static const rv_comp_data rvcp_fsgnjn_q
[] = {
824 { rv_op_fneg_q
, rvcc_fneg_q
},
825 { rv_op_illegal
, NULL
}
828 static const rv_comp_data rvcp_fsgnjx_q
[] = {
829 { rv_op_fabs_q
, rvcc_fabs_q
},
830 { rv_op_illegal
, NULL
}
833 /* instruction metadata */
835 const rv_opcode_data opcode_data
[] = {
836 { "illegal", rv_codec_illegal
, rv_fmt_none
, NULL
, 0, 0, 0 },
837 { "lui", rv_codec_u
, rv_fmt_rd_imm
, NULL
, 0, 0, 0 },
838 { "auipc", rv_codec_u
, rv_fmt_rd_offset
, NULL
, 0, 0, 0 },
839 { "jal", rv_codec_uj
, rv_fmt_rd_offset
, rvcp_jal
, 0, 0, 0 },
840 { "jalr", rv_codec_i
, rv_fmt_rd_rs1_offset
, rvcp_jalr
, 0, 0, 0 },
841 { "beq", rv_codec_sb
, rv_fmt_rs1_rs2_offset
, rvcp_beq
, 0, 0, 0 },
842 { "bne", rv_codec_sb
, rv_fmt_rs1_rs2_offset
, rvcp_bne
, 0, 0, 0 },
843 { "blt", rv_codec_sb
, rv_fmt_rs1_rs2_offset
, rvcp_blt
, 0, 0, 0 },
844 { "bge", rv_codec_sb
, rv_fmt_rs1_rs2_offset
, rvcp_bge
, 0, 0, 0 },
845 { "bltu", rv_codec_sb
, rv_fmt_rs1_rs2_offset
, rvcp_bltu
, 0, 0, 0 },
846 { "bgeu", rv_codec_sb
, rv_fmt_rs1_rs2_offset
, rvcp_bgeu
, 0, 0, 0 },
847 { "lb", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
848 { "lh", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
849 { "lw", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
850 { "lbu", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
851 { "lhu", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
852 { "sb", rv_codec_s
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, 0 },
853 { "sh", rv_codec_s
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, 0 },
854 { "sw", rv_codec_s
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, 0 },
855 { "addi", rv_codec_i
, rv_fmt_rd_rs1_imm
, rvcp_addi
, 0, 0, 0 },
856 { "slti", rv_codec_i
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
857 { "sltiu", rv_codec_i
, rv_fmt_rd_rs1_imm
, rvcp_sltiu
, 0, 0, 0 },
858 { "xori", rv_codec_i
, rv_fmt_rd_rs1_imm
, rvcp_xori
, 0, 0, 0 },
859 { "ori", rv_codec_i
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
860 { "andi", rv_codec_i
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
861 { "slli", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
862 { "srli", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
863 { "srai", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
864 { "add", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
865 { "sub", rv_codec_r
, rv_fmt_rd_rs1_rs2
, rvcp_sub
, 0, 0, 0 },
866 { "sll", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
867 { "slt", rv_codec_r
, rv_fmt_rd_rs1_rs2
, rvcp_slt
, 0, 0, 0 },
868 { "sltu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, rvcp_sltu
, 0, 0, 0 },
869 { "xor", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
870 { "srl", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
871 { "sra", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
872 { "or", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
873 { "and", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
874 { "fence", rv_codec_r_f
, rv_fmt_pred_succ
, NULL
, 0, 0, 0 },
875 { "fence.i", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
876 { "lwu", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
877 { "ld", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
878 { "sd", rv_codec_s
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, 0 },
879 { "addiw", rv_codec_i
, rv_fmt_rd_rs1_imm
, rvcp_addiw
, 0, 0, 0 },
880 { "slliw", rv_codec_i_sh5
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
881 { "srliw", rv_codec_i_sh5
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
882 { "sraiw", rv_codec_i_sh5
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
883 { "addw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
884 { "subw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, rvcp_subw
, 0, 0, 0 },
885 { "sllw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
886 { "srlw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
887 { "sraw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
888 { "ldu", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
889 { "lq", rv_codec_i
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, 0 },
890 { "sq", rv_codec_s
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, 0 },
891 { "addid", rv_codec_i
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
892 { "sllid", rv_codec_i_sh6
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
893 { "srlid", rv_codec_i_sh6
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
894 { "sraid", rv_codec_i_sh6
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
895 { "addd", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
896 { "subd", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
897 { "slld", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
898 { "srld", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
899 { "srad", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
900 { "mul", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
901 { "mulh", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
902 { "mulhsu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
903 { "mulhu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
904 { "div", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
905 { "divu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
906 { "rem", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
907 { "remu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
908 { "mulw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
909 { "divw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
910 { "divuw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
911 { "remw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
912 { "remuw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
913 { "muld", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
914 { "divd", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
915 { "divud", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
916 { "remd", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
917 { "remud", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
918 { "lr.w", rv_codec_r_l
, rv_fmt_aqrl_rd_rs1
, NULL
, 0, 0, 0 },
919 { "sc.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
920 { "amoswap.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
921 { "amoadd.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
922 { "amoxor.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
923 { "amoor.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
924 { "amoand.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
925 { "amomin.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
926 { "amomax.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
927 { "amominu.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
928 { "amomaxu.w", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
929 { "lr.d", rv_codec_r_l
, rv_fmt_aqrl_rd_rs1
, NULL
, 0, 0, 0 },
930 { "sc.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
931 { "amoswap.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
932 { "amoadd.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
933 { "amoxor.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
934 { "amoor.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
935 { "amoand.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
936 { "amomin.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
937 { "amomax.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
938 { "amominu.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
939 { "amomaxu.d", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
940 { "lr.q", rv_codec_r_l
, rv_fmt_aqrl_rd_rs1
, NULL
, 0, 0, 0 },
941 { "sc.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
942 { "amoswap.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
943 { "amoadd.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
944 { "amoxor.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
945 { "amoor.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
946 { "amoand.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
947 { "amomin.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
948 { "amomax.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
949 { "amominu.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
950 { "amomaxu.q", rv_codec_r_a
, rv_fmt_aqrl_rd_rs2_rs1
, NULL
, 0, 0, 0 },
951 { "ecall", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
952 { "ebreak", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
953 { "uret", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
954 { "sret", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
955 { "hret", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
956 { "mret", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
957 { "dret", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
958 { "sfence.vm", rv_codec_r
, rv_fmt_rs1
, NULL
, 0, 0, 0 },
959 { "sfence.vma", rv_codec_r
, rv_fmt_rs1_rs2
, NULL
, 0, 0, 0 },
960 { "wfi", rv_codec_none
, rv_fmt_none
, NULL
, 0, 0, 0 },
961 { "csrrw", rv_codec_i_csr
, rv_fmt_rd_csr_rs1
, rvcp_csrrw
, 0, 0, 0 },
962 { "csrrs", rv_codec_i_csr
, rv_fmt_rd_csr_rs1
, rvcp_csrrs
, 0, 0, 0 },
963 { "csrrc", rv_codec_i_csr
, rv_fmt_rd_csr_rs1
, NULL
, 0, 0, 0 },
964 { "csrrwi", rv_codec_i_csr
, rv_fmt_rd_csr_zimm
, rvcp_csrrwi
, 0, 0, 0 },
965 { "csrrsi", rv_codec_i_csr
, rv_fmt_rd_csr_zimm
, NULL
, 0, 0, 0 },
966 { "csrrci", rv_codec_i_csr
, rv_fmt_rd_csr_zimm
, NULL
, 0, 0, 0 },
967 { "flw", rv_codec_i
, rv_fmt_frd_offset_rs1
, NULL
, 0, 0, 0 },
968 { "fsw", rv_codec_s
, rv_fmt_frs2_offset_rs1
, NULL
, 0, 0, 0 },
969 { "fmadd.s", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
970 { "fmsub.s", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
971 { "fnmsub.s", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
972 { "fnmadd.s", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
973 { "fadd.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
974 { "fsub.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
975 { "fmul.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
976 { "fdiv.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
977 { "fsgnj.s", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnj_s
, 0, 0, 0 },
978 { "fsgnjn.s", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnjn_s
, 0, 0, 0 },
979 { "fsgnjx.s", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnjx_s
, 0, 0, 0 },
980 { "fmin.s", rv_codec_r
, rv_fmt_frd_frs1_frs2
, NULL
, 0, 0, 0 },
981 { "fmax.s", rv_codec_r
, rv_fmt_frd_frs1_frs2
, NULL
, 0, 0, 0 },
982 { "fsqrt.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
983 { "fle.s", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
984 { "flt.s", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
985 { "feq.s", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
986 { "fcvt.w.s", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
987 { "fcvt.wu.s", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
988 { "fcvt.s.w", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
989 { "fcvt.s.wu", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
990 { "fmv.x.s", rv_codec_r
, rv_fmt_rd_frs1
, NULL
, 0, 0, 0 },
991 { "fclass.s", rv_codec_r
, rv_fmt_rd_frs1
, NULL
, 0, 0, 0 },
992 { "fmv.s.x", rv_codec_r
, rv_fmt_frd_rs1
, NULL
, 0, 0, 0 },
993 { "fcvt.l.s", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
994 { "fcvt.lu.s", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
995 { "fcvt.s.l", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
996 { "fcvt.s.lu", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
997 { "fld", rv_codec_i
, rv_fmt_frd_offset_rs1
, NULL
, 0, 0, 0 },
998 { "fsd", rv_codec_s
, rv_fmt_frs2_offset_rs1
, NULL
, 0, 0, 0 },
999 { "fmadd.d", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1000 { "fmsub.d", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1001 { "fnmsub.d", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1002 { "fnmadd.d", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1003 { "fadd.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1004 { "fsub.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1005 { "fmul.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1006 { "fdiv.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1007 { "fsgnj.d", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnj_d
, 0, 0, 0 },
1008 { "fsgnjn.d", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnjn_d
, 0, 0, 0 },
1009 { "fsgnjx.d", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnjx_d
, 0, 0, 0 },
1010 { "fmin.d", rv_codec_r
, rv_fmt_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1011 { "fmax.d", rv_codec_r
, rv_fmt_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1012 { "fcvt.s.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1013 { "fcvt.d.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1014 { "fsqrt.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1015 { "fle.d", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
1016 { "flt.d", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
1017 { "feq.d", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
1018 { "fcvt.w.d", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1019 { "fcvt.wu.d", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1020 { "fcvt.d.w", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1021 { "fcvt.d.wu", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1022 { "fclass.d", rv_codec_r
, rv_fmt_rd_frs1
, NULL
, 0, 0, 0 },
1023 { "fcvt.l.d", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1024 { "fcvt.lu.d", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1025 { "fmv.x.d", rv_codec_r
, rv_fmt_rd_frs1
, NULL
, 0, 0, 0 },
1026 { "fcvt.d.l", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1027 { "fcvt.d.lu", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1028 { "fmv.d.x", rv_codec_r
, rv_fmt_frd_rs1
, NULL
, 0, 0, 0 },
1029 { "flq", rv_codec_i
, rv_fmt_frd_offset_rs1
, NULL
, 0, 0, 0 },
1030 { "fsq", rv_codec_s
, rv_fmt_frs2_offset_rs1
, NULL
, 0, 0, 0 },
1031 { "fmadd.q", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1032 { "fmsub.q", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1033 { "fnmsub.q", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1034 { "fnmadd.q", rv_codec_r4_m
, rv_fmt_rm_frd_frs1_frs2_frs3
, NULL
, 0, 0, 0 },
1035 { "fadd.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1036 { "fsub.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1037 { "fmul.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1038 { "fdiv.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1039 { "fsgnj.q", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnj_q
, 0, 0, 0 },
1040 { "fsgnjn.q", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnjn_q
, 0, 0, 0 },
1041 { "fsgnjx.q", rv_codec_r
, rv_fmt_frd_frs1_frs2
, rvcp_fsgnjx_q
, 0, 0, 0 },
1042 { "fmin.q", rv_codec_r
, rv_fmt_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1043 { "fmax.q", rv_codec_r
, rv_fmt_frd_frs1_frs2
, NULL
, 0, 0, 0 },
1044 { "fcvt.s.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1045 { "fcvt.q.s", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1046 { "fcvt.d.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1047 { "fcvt.q.d", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1048 { "fsqrt.q", rv_codec_r_m
, rv_fmt_rm_frd_frs1
, NULL
, 0, 0, 0 },
1049 { "fle.q", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
1050 { "flt.q", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
1051 { "feq.q", rv_codec_r
, rv_fmt_rd_frs1_frs2
, NULL
, 0, 0, 0 },
1052 { "fcvt.w.q", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1053 { "fcvt.wu.q", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1054 { "fcvt.q.w", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1055 { "fcvt.q.wu", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1056 { "fclass.q", rv_codec_r
, rv_fmt_rd_frs1
, NULL
, 0, 0, 0 },
1057 { "fcvt.l.q", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1058 { "fcvt.lu.q", rv_codec_r_m
, rv_fmt_rm_rd_frs1
, NULL
, 0, 0, 0 },
1059 { "fcvt.q.l", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1060 { "fcvt.q.lu", rv_codec_r_m
, rv_fmt_rm_frd_rs1
, NULL
, 0, 0, 0 },
1061 { "fmv.x.q", rv_codec_r
, rv_fmt_rd_frs1
, NULL
, 0, 0, 0 },
1062 { "fmv.q.x", rv_codec_r
, rv_fmt_frd_rs1
, NULL
, 0, 0, 0 },
1063 { "c.addi4spn", rv_codec_ciw_4spn
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_addi
,
1064 rv_op_addi
, rv_op_addi
, rvcd_imm_nz
},
1065 { "c.fld", rv_codec_cl_ld
, rv_fmt_frd_offset_rs1
, NULL
, rv_op_fld
, rv_op_fld
, 0 },
1066 { "c.lw", rv_codec_cl_lw
, rv_fmt_rd_offset_rs1
, NULL
, rv_op_lw
, rv_op_lw
, rv_op_lw
},
1067 { "c.flw", rv_codec_cl_lw
, rv_fmt_frd_offset_rs1
, NULL
, rv_op_flw
, 0, 0 },
1068 { "c.fsd", rv_codec_cs_sd
, rv_fmt_frs2_offset_rs1
, NULL
, rv_op_fsd
, rv_op_fsd
, 0 },
1069 { "c.sw", rv_codec_cs_sw
, rv_fmt_rs2_offset_rs1
, NULL
, rv_op_sw
, rv_op_sw
, rv_op_sw
},
1070 { "c.fsw", rv_codec_cs_sw
, rv_fmt_frs2_offset_rs1
, NULL
, rv_op_fsw
, 0, 0 },
1071 { "c.nop", rv_codec_ci_none
, rv_fmt_none
, NULL
, rv_op_addi
, rv_op_addi
, rv_op_addi
},
1072 { "c.addi", rv_codec_ci
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_addi
, rv_op_addi
,
1073 rv_op_addi
, rvcd_imm_nz
},
1074 { "c.jal", rv_codec_cj_jal
, rv_fmt_rd_offset
, NULL
, rv_op_jal
, 0, 0 },
1075 { "c.li", rv_codec_ci_li
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_addi
, rv_op_addi
, rv_op_addi
},
1076 { "c.addi16sp", rv_codec_ci_16sp
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_addi
,
1077 rv_op_addi
, rv_op_addi
, rvcd_imm_nz
},
1078 { "c.lui", rv_codec_ci_lui
, rv_fmt_rd_imm
, NULL
, rv_op_lui
, rv_op_lui
,
1079 rv_op_lui
, rvcd_imm_nz
},
1080 { "c.srli", rv_codec_cb_sh6
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_srli
,
1081 rv_op_srli
, rv_op_srli
, rvcd_imm_nz
},
1082 { "c.srai", rv_codec_cb_sh6
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_srai
,
1083 rv_op_srai
, rv_op_srai
, rvcd_imm_nz
},
1084 { "c.andi", rv_codec_cb_imm
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_andi
,
1085 rv_op_andi
, rv_op_andi
},
1086 { "c.sub", rv_codec_cs
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_sub
, rv_op_sub
, rv_op_sub
},
1087 { "c.xor", rv_codec_cs
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_xor
, rv_op_xor
, rv_op_xor
},
1088 { "c.or", rv_codec_cs
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_or
, rv_op_or
, rv_op_or
},
1089 { "c.and", rv_codec_cs
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_and
, rv_op_and
, rv_op_and
},
1090 { "c.subw", rv_codec_cs
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_subw
, rv_op_subw
, rv_op_subw
},
1091 { "c.addw", rv_codec_cs
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_addw
, rv_op_addw
, rv_op_addw
},
1092 { "c.j", rv_codec_cj
, rv_fmt_rd_offset
, NULL
, rv_op_jal
, rv_op_jal
, rv_op_jal
},
1093 { "c.beqz", rv_codec_cb
, rv_fmt_rs1_rs2_offset
, NULL
, rv_op_beq
, rv_op_beq
, rv_op_beq
},
1094 { "c.bnez", rv_codec_cb
, rv_fmt_rs1_rs2_offset
, NULL
, rv_op_bne
, rv_op_bne
, rv_op_bne
},
1095 { "c.slli", rv_codec_ci_sh6
, rv_fmt_rd_rs1_imm
, NULL
, rv_op_slli
,
1096 rv_op_slli
, rv_op_slli
, rvcd_imm_nz
},
1097 { "c.fldsp", rv_codec_ci_ldsp
, rv_fmt_frd_offset_rs1
, NULL
, rv_op_fld
, rv_op_fld
, rv_op_fld
},
1098 { "c.lwsp", rv_codec_ci_lwsp
, rv_fmt_rd_offset_rs1
, NULL
, rv_op_lw
, rv_op_lw
, rv_op_lw
},
1099 { "c.flwsp", rv_codec_ci_lwsp
, rv_fmt_frd_offset_rs1
, NULL
, rv_op_flw
, 0, 0 },
1100 { "c.jr", rv_codec_cr_jr
, rv_fmt_rd_rs1_offset
, NULL
, rv_op_jalr
, rv_op_jalr
, rv_op_jalr
},
1101 { "c.mv", rv_codec_cr_mv
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_addi
, rv_op_addi
, rv_op_addi
},
1102 { "c.ebreak", rv_codec_ci_none
, rv_fmt_none
, NULL
, rv_op_ebreak
, rv_op_ebreak
, rv_op_ebreak
},
1103 { "c.jalr", rv_codec_cr_jalr
, rv_fmt_rd_rs1_offset
, NULL
, rv_op_jalr
, rv_op_jalr
, rv_op_jalr
},
1104 { "c.add", rv_codec_cr
, rv_fmt_rd_rs1_rs2
, NULL
, rv_op_add
, rv_op_add
, rv_op_add
},
1105 { "c.fsdsp", rv_codec_css_sdsp
, rv_fmt_frs2_offset_rs1
, NULL
, rv_op_fsd
, rv_op_fsd
, rv_op_fsd
},
1106 { "c.swsp", rv_codec_css_swsp
, rv_fmt_rs2_offset_rs1
, NULL
, rv_op_sw
, rv_op_sw
, rv_op_sw
},
1107 { "c.fswsp", rv_codec_css_swsp
, rv_fmt_frs2_offset_rs1
, NULL
, rv_op_fsw
, 0, 0 },
1108 { "c.ld", rv_codec_cl_ld
, rv_fmt_rd_offset_rs1
, NULL
, 0, rv_op_ld
, rv_op_ld
},
1109 { "c.sd", rv_codec_cs_sd
, rv_fmt_rs2_offset_rs1
, NULL
, 0, rv_op_sd
, rv_op_sd
},
1110 { "c.addiw", rv_codec_ci
, rv_fmt_rd_rs1_imm
, NULL
, 0, rv_op_addiw
, rv_op_addiw
},
1111 { "c.ldsp", rv_codec_ci_ldsp
, rv_fmt_rd_offset_rs1
, NULL
, 0, rv_op_ld
, rv_op_ld
},
1112 { "c.sdsp", rv_codec_css_sdsp
, rv_fmt_rs2_offset_rs1
, NULL
, 0, rv_op_sd
, rv_op_sd
},
1113 { "c.lq", rv_codec_cl_lq
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, rv_op_lq
},
1114 { "c.sq", rv_codec_cs_sq
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, rv_op_sq
},
1115 { "c.lqsp", rv_codec_ci_lqsp
, rv_fmt_rd_offset_rs1
, NULL
, 0, 0, rv_op_lq
},
1116 { "c.sqsp", rv_codec_css_sqsp
, rv_fmt_rs2_offset_rs1
, NULL
, 0, 0, rv_op_sq
},
1117 { "nop", rv_codec_i
, rv_fmt_none
, NULL
, 0, 0, 0 },
1118 { "mv", rv_codec_i
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1119 { "not", rv_codec_i
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1120 { "neg", rv_codec_r
, rv_fmt_rd_rs2
, NULL
, 0, 0, 0 },
1121 { "negw", rv_codec_r
, rv_fmt_rd_rs2
, NULL
, 0, 0, 0 },
1122 { "sext.w", rv_codec_i
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1123 { "seqz", rv_codec_i
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1124 { "snez", rv_codec_r
, rv_fmt_rd_rs2
, NULL
, 0, 0, 0 },
1125 { "sltz", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1126 { "sgtz", rv_codec_r
, rv_fmt_rd_rs2
, NULL
, 0, 0, 0 },
1127 { "fmv.s", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1128 { "fabs.s", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1129 { "fneg.s", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1130 { "fmv.d", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1131 { "fabs.d", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1132 { "fneg.d", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1133 { "fmv.q", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1134 { "fabs.q", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1135 { "fneg.q", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1136 { "beqz", rv_codec_sb
, rv_fmt_rs1_offset
, NULL
, 0, 0, 0 },
1137 { "bnez", rv_codec_sb
, rv_fmt_rs1_offset
, NULL
, 0, 0, 0 },
1138 { "blez", rv_codec_sb
, rv_fmt_rs2_offset
, NULL
, 0, 0, 0 },
1139 { "bgez", rv_codec_sb
, rv_fmt_rs1_offset
, NULL
, 0, 0, 0 },
1140 { "bltz", rv_codec_sb
, rv_fmt_rs1_offset
, NULL
, 0, 0, 0 },
1141 { "bgtz", rv_codec_sb
, rv_fmt_rs2_offset
, NULL
, 0, 0, 0 },
1142 { "ble", rv_codec_sb
, rv_fmt_rs2_rs1_offset
, NULL
, 0, 0, 0 },
1143 { "bleu", rv_codec_sb
, rv_fmt_rs2_rs1_offset
, NULL
, 0, 0, 0 },
1144 { "bgt", rv_codec_sb
, rv_fmt_rs2_rs1_offset
, NULL
, 0, 0, 0 },
1145 { "bgtu", rv_codec_sb
, rv_fmt_rs2_rs1_offset
, NULL
, 0, 0, 0 },
1146 { "j", rv_codec_uj
, rv_fmt_offset
, NULL
, 0, 0, 0 },
1147 { "ret", rv_codec_i
, rv_fmt_none
, NULL
, 0, 0, 0 },
1148 { "jr", rv_codec_i
, rv_fmt_rs1
, NULL
, 0, 0, 0 },
1149 { "rdcycle", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1150 { "rdtime", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1151 { "rdinstret", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1152 { "rdcycleh", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1153 { "rdtimeh", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1154 { "rdinstreth", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1155 { "frcsr", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1156 { "frrm", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1157 { "frflags", rv_codec_i_csr
, rv_fmt_rd
, NULL
, 0, 0, 0 },
1158 { "fscsr", rv_codec_i_csr
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1159 { "fsrm", rv_codec_i_csr
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1160 { "fsflags", rv_codec_i_csr
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1161 { "fsrmi", rv_codec_i_csr
, rv_fmt_rd_zimm
, NULL
, 0, 0, 0 },
1162 { "fsflagsi", rv_codec_i_csr
, rv_fmt_rd_zimm
, NULL
, 0, 0, 0 },
1163 { "bseti", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
1164 { "bclri", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
1165 { "binvi", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
1166 { "bexti", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
1167 { "rori", rv_codec_i_sh7
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
1168 { "clz", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1169 { "ctz", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1170 { "cpop", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1171 { "sext.h", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1172 { "sext.b", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1173 { "xnor", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1174 { "orn", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1175 { "andn", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1176 { "rol", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1177 { "ror", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1178 { "sh1add", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1179 { "sh2add", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1180 { "sh3add", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1181 { "sh1add.uw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1182 { "sh2add.uw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1183 { "sh3add.uw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1184 { "clmul", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1185 { "clmulr", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1186 { "clmulh", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1187 { "min", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1188 { "minu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1189 { "max", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1190 { "maxu", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1191 { "clzw", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1192 { "clzw", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1193 { "cpopw", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1194 { "slli.uw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1195 { "add.uw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1196 { "rolw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1197 { "rorw", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1198 { "rev8", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1199 { "zext.h", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1200 { "roriw", rv_codec_i_sh5
, rv_fmt_rd_rs1_imm
, NULL
, 0, 0, 0 },
1201 { "orc.b", rv_codec_r
, rv_fmt_rd_rs1
, NULL
, 0, 0, 0 },
1202 { "bset", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1203 { "bclr", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1204 { "binv", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1205 { "bext", rv_codec_r
, rv_fmt_rd_rs1_rs2
, NULL
, 0, 0, 0 },
1210 static const char *csr_name(int csrno
)
1213 case 0x0000: return "ustatus";
1214 case 0x0001: return "fflags";
1215 case 0x0002: return "frm";
1216 case 0x0003: return "fcsr";
1217 case 0x0004: return "uie";
1218 case 0x0005: return "utvec";
1219 case 0x0040: return "uscratch";
1220 case 0x0041: return "uepc";
1221 case 0x0042: return "ucause";
1222 case 0x0043: return "utval";
1223 case 0x0044: return "uip";
1224 case 0x0100: return "sstatus";
1225 case 0x0102: return "sedeleg";
1226 case 0x0103: return "sideleg";
1227 case 0x0104: return "sie";
1228 case 0x0105: return "stvec";
1229 case 0x0106: return "scounteren";
1230 case 0x0140: return "sscratch";
1231 case 0x0141: return "sepc";
1232 case 0x0142: return "scause";
1233 case 0x0143: return "stval";
1234 case 0x0144: return "sip";
1235 case 0x0180: return "satp";
1236 case 0x0200: return "hstatus";
1237 case 0x0202: return "hedeleg";
1238 case 0x0203: return "hideleg";
1239 case 0x0204: return "hie";
1240 case 0x0205: return "htvec";
1241 case 0x0240: return "hscratch";
1242 case 0x0241: return "hepc";
1243 case 0x0242: return "hcause";
1244 case 0x0243: return "hbadaddr";
1245 case 0x0244: return "hip";
1246 case 0x0300: return "mstatus";
1247 case 0x0301: return "misa";
1248 case 0x0302: return "medeleg";
1249 case 0x0303: return "mideleg";
1250 case 0x0304: return "mie";
1251 case 0x0305: return "mtvec";
1252 case 0x0306: return "mcounteren";
1253 case 0x0320: return "mucounteren";
1254 case 0x0321: return "mscounteren";
1255 case 0x0322: return "mhcounteren";
1256 case 0x0323: return "mhpmevent3";
1257 case 0x0324: return "mhpmevent4";
1258 case 0x0325: return "mhpmevent5";
1259 case 0x0326: return "mhpmevent6";
1260 case 0x0327: return "mhpmevent7";
1261 case 0x0328: return "mhpmevent8";
1262 case 0x0329: return "mhpmevent9";
1263 case 0x032a: return "mhpmevent10";
1264 case 0x032b: return "mhpmevent11";
1265 case 0x032c: return "mhpmevent12";
1266 case 0x032d: return "mhpmevent13";
1267 case 0x032e: return "mhpmevent14";
1268 case 0x032f: return "mhpmevent15";
1269 case 0x0330: return "mhpmevent16";
1270 case 0x0331: return "mhpmevent17";
1271 case 0x0332: return "mhpmevent18";
1272 case 0x0333: return "mhpmevent19";
1273 case 0x0334: return "mhpmevent20";
1274 case 0x0335: return "mhpmevent21";
1275 case 0x0336: return "mhpmevent22";
1276 case 0x0337: return "mhpmevent23";
1277 case 0x0338: return "mhpmevent24";
1278 case 0x0339: return "mhpmevent25";
1279 case 0x033a: return "mhpmevent26";
1280 case 0x033b: return "mhpmevent27";
1281 case 0x033c: return "mhpmevent28";
1282 case 0x033d: return "mhpmevent29";
1283 case 0x033e: return "mhpmevent30";
1284 case 0x033f: return "mhpmevent31";
1285 case 0x0340: return "mscratch";
1286 case 0x0341: return "mepc";
1287 case 0x0342: return "mcause";
1288 case 0x0343: return "mtval";
1289 case 0x0344: return "mip";
1290 case 0x0380: return "mbase";
1291 case 0x0381: return "mbound";
1292 case 0x0382: return "mibase";
1293 case 0x0383: return "mibound";
1294 case 0x0384: return "mdbase";
1295 case 0x0385: return "mdbound";
1296 case 0x03a0: return "pmpcfg3";
1297 case 0x03b0: return "pmpaddr0";
1298 case 0x03b1: return "pmpaddr1";
1299 case 0x03b2: return "pmpaddr2";
1300 case 0x03b3: return "pmpaddr3";
1301 case 0x03b4: return "pmpaddr4";
1302 case 0x03b5: return "pmpaddr5";
1303 case 0x03b6: return "pmpaddr6";
1304 case 0x03b7: return "pmpaddr7";
1305 case 0x03b8: return "pmpaddr8";
1306 case 0x03b9: return "pmpaddr9";
1307 case 0x03ba: return "pmpaddr10";
1308 case 0x03bb: return "pmpaddr11";
1309 case 0x03bc: return "pmpaddr12";
1310 case 0x03bd: return "pmpaddr14";
1311 case 0x03be: return "pmpaddr13";
1312 case 0x03bf: return "pmpaddr15";
1313 case 0x0780: return "mtohost";
1314 case 0x0781: return "mfromhost";
1315 case 0x0782: return "mreset";
1316 case 0x0783: return "mipi";
1317 case 0x0784: return "miobase";
1318 case 0x07a0: return "tselect";
1319 case 0x07a1: return "tdata1";
1320 case 0x07a2: return "tdata2";
1321 case 0x07a3: return "tdata3";
1322 case 0x07b0: return "dcsr";
1323 case 0x07b1: return "dpc";
1324 case 0x07b2: return "dscratch";
1325 case 0x0b00: return "mcycle";
1326 case 0x0b01: return "mtime";
1327 case 0x0b02: return "minstret";
1328 case 0x0b03: return "mhpmcounter3";
1329 case 0x0b04: return "mhpmcounter4";
1330 case 0x0b05: return "mhpmcounter5";
1331 case 0x0b06: return "mhpmcounter6";
1332 case 0x0b07: return "mhpmcounter7";
1333 case 0x0b08: return "mhpmcounter8";
1334 case 0x0b09: return "mhpmcounter9";
1335 case 0x0b0a: return "mhpmcounter10";
1336 case 0x0b0b: return "mhpmcounter11";
1337 case 0x0b0c: return "mhpmcounter12";
1338 case 0x0b0d: return "mhpmcounter13";
1339 case 0x0b0e: return "mhpmcounter14";
1340 case 0x0b0f: return "mhpmcounter15";
1341 case 0x0b10: return "mhpmcounter16";
1342 case 0x0b11: return "mhpmcounter17";
1343 case 0x0b12: return "mhpmcounter18";
1344 case 0x0b13: return "mhpmcounter19";
1345 case 0x0b14: return "mhpmcounter20";
1346 case 0x0b15: return "mhpmcounter21";
1347 case 0x0b16: return "mhpmcounter22";
1348 case 0x0b17: return "mhpmcounter23";
1349 case 0x0b18: return "mhpmcounter24";
1350 case 0x0b19: return "mhpmcounter25";
1351 case 0x0b1a: return "mhpmcounter26";
1352 case 0x0b1b: return "mhpmcounter27";
1353 case 0x0b1c: return "mhpmcounter28";
1354 case 0x0b1d: return "mhpmcounter29";
1355 case 0x0b1e: return "mhpmcounter30";
1356 case 0x0b1f: return "mhpmcounter31";
1357 case 0x0b80: return "mcycleh";
1358 case 0x0b81: return "mtimeh";
1359 case 0x0b82: return "minstreth";
1360 case 0x0b83: return "mhpmcounter3h";
1361 case 0x0b84: return "mhpmcounter4h";
1362 case 0x0b85: return "mhpmcounter5h";
1363 case 0x0b86: return "mhpmcounter6h";
1364 case 0x0b87: return "mhpmcounter7h";
1365 case 0x0b88: return "mhpmcounter8h";
1366 case 0x0b89: return "mhpmcounter9h";
1367 case 0x0b8a: return "mhpmcounter10h";
1368 case 0x0b8b: return "mhpmcounter11h";
1369 case 0x0b8c: return "mhpmcounter12h";
1370 case 0x0b8d: return "mhpmcounter13h";
1371 case 0x0b8e: return "mhpmcounter14h";
1372 case 0x0b8f: return "mhpmcounter15h";
1373 case 0x0b90: return "mhpmcounter16h";
1374 case 0x0b91: return "mhpmcounter17h";
1375 case 0x0b92: return "mhpmcounter18h";
1376 case 0x0b93: return "mhpmcounter19h";
1377 case 0x0b94: return "mhpmcounter20h";
1378 case 0x0b95: return "mhpmcounter21h";
1379 case 0x0b96: return "mhpmcounter22h";
1380 case 0x0b97: return "mhpmcounter23h";
1381 case 0x0b98: return "mhpmcounter24h";
1382 case 0x0b99: return "mhpmcounter25h";
1383 case 0x0b9a: return "mhpmcounter26h";
1384 case 0x0b9b: return "mhpmcounter27h";
1385 case 0x0b9c: return "mhpmcounter28h";
1386 case 0x0b9d: return "mhpmcounter29h";
1387 case 0x0b9e: return "mhpmcounter30h";
1388 case 0x0b9f: return "mhpmcounter31h";
1389 case 0x0c00: return "cycle";
1390 case 0x0c01: return "time";
1391 case 0x0c02: return "instret";
1392 case 0x0c80: return "cycleh";
1393 case 0x0c81: return "timeh";
1394 case 0x0c82: return "instreth";
1395 case 0x0d00: return "scycle";
1396 case 0x0d01: return "stime";
1397 case 0x0d02: return "sinstret";
1398 case 0x0d80: return "scycleh";
1399 case 0x0d81: return "stimeh";
1400 case 0x0d82: return "sinstreth";
1401 case 0x0e00: return "hcycle";
1402 case 0x0e01: return "htime";
1403 case 0x0e02: return "hinstret";
1404 case 0x0e80: return "hcycleh";
1405 case 0x0e81: return "htimeh";
1406 case 0x0e82: return "hinstreth";
1407 case 0x0f11: return "mvendorid";
1408 case 0x0f12: return "marchid";
1409 case 0x0f13: return "mimpid";
1410 case 0x0f14: return "mhartid";
1411 default: return NULL
;
1417 static void decode_inst_opcode(rv_decode
*dec
, rv_isa isa
)
1419 rv_inst inst
= dec
->inst
;
1420 rv_opcode op
= rv_op_illegal
;
1421 switch (((inst
>> 0) & 0b11)) {
1423 switch (((inst
>> 13) & 0b111)) {
1424 case 0: op
= rv_op_c_addi4spn
; break;
1432 case 2: op
= rv_op_c_lw
; break;
1447 case 6: op
= rv_op_c_sw
; break;
1458 switch (((inst
>> 13) & 0b111)) {
1460 switch (((inst
>> 2) & 0b11111111111)) {
1461 case 0: op
= rv_op_c_nop
; break;
1462 default: op
= rv_op_c_addi
; break;
1472 case 2: op
= rv_op_c_li
; break;
1474 switch (((inst
>> 7) & 0b11111)) {
1475 case 2: op
= rv_op_c_addi16sp
; break;
1476 default: op
= rv_op_c_lui
; break;
1480 switch (((inst
>> 10) & 0b11)) {
1487 case 2: op
= rv_op_c_andi
; break;
1489 switch (((inst
>> 10) & 0b100) | ((inst
>> 5) & 0b011)) {
1490 case 0: op
= rv_op_c_sub
; break;
1491 case 1: op
= rv_op_c_xor
; break;
1492 case 2: op
= rv_op_c_or
; break;
1493 case 3: op
= rv_op_c_and
; break;
1494 case 4: op
= rv_op_c_subw
; break;
1495 case 5: op
= rv_op_c_addw
; break;
1500 case 5: op
= rv_op_c_j
; break;
1501 case 6: op
= rv_op_c_beqz
; break;
1502 case 7: op
= rv_op_c_bnez
; break;
1506 switch (((inst
>> 13) & 0b111)) {
1517 case 2: op
= rv_op_c_lwsp
; break;
1526 switch (((inst
>> 12) & 0b1)) {
1528 switch (((inst
>> 2) & 0b11111)) {
1529 case 0: op
= rv_op_c_jr
; break;
1530 default: op
= rv_op_c_mv
; break;
1534 switch (((inst
>> 2) & 0b11111)) {
1536 switch (((inst
>> 7) & 0b11111)) {
1537 case 0: op
= rv_op_c_ebreak
; break;
1538 default: op
= rv_op_c_jalr
; break;
1541 default: op
= rv_op_c_add
; break;
1553 case 6: op
= rv_op_c_swsp
; break;
1564 switch (((inst
>> 2) & 0b11111)) {
1566 switch (((inst
>> 12) & 0b111)) {
1567 case 0: op
= rv_op_lb
; break;
1568 case 1: op
= rv_op_lh
; break;
1569 case 2: op
= rv_op_lw
; break;
1570 case 3: op
= rv_op_ld
; break;
1571 case 4: op
= rv_op_lbu
; break;
1572 case 5: op
= rv_op_lhu
; break;
1573 case 6: op
= rv_op_lwu
; break;
1574 case 7: op
= rv_op_ldu
; break;
1578 switch (((inst
>> 12) & 0b111)) {
1579 case 2: op
= rv_op_flw
; break;
1580 case 3: op
= rv_op_fld
; break;
1581 case 4: op
= rv_op_flq
; break;
1585 switch (((inst
>> 12) & 0b111)) {
1586 case 0: op
= rv_op_fence
; break;
1587 case 1: op
= rv_op_fence_i
; break;
1588 case 2: op
= rv_op_lq
; break;
1592 switch (((inst
>> 12) & 0b111)) {
1593 case 0: op
= rv_op_addi
; break;
1595 switch (((inst
>> 27) & 0b11111)) {
1596 case 0b00000: op
= rv_op_slli
; break;
1597 case 0b00101: op
= rv_op_bseti
; break;
1598 case 0b01001: op
= rv_op_bclri
; break;
1599 case 0b01101: op
= rv_op_binvi
; break;
1601 switch (((inst
>> 20) & 0b1111111)) {
1602 case 0b0000000: op
= rv_op_clz
; break;
1603 case 0b0000001: op
= rv_op_ctz
; break;
1604 case 0b0000010: op
= rv_op_cpop
; break;
1606 case 0b0000100: op
= rv_op_sext_b
; break;
1607 case 0b0000101: op
= rv_op_sext_h
; break;
1612 case 2: op
= rv_op_slti
; break;
1613 case 3: op
= rv_op_sltiu
; break;
1614 case 4: op
= rv_op_xori
; break;
1616 switch (((inst
>> 27) & 0b11111)) {
1617 case 0b00000: op
= rv_op_srli
; break;
1618 case 0b00101: op
= rv_op_orc_b
; break;
1619 case 0b01000: op
= rv_op_srai
; break;
1620 case 0b01001: op
= rv_op_bexti
; break;
1621 case 0b01100: op
= rv_op_rori
; break;
1623 switch ((inst
>> 20) & 0b1111111) {
1624 case 0b0111000: op
= rv_op_rev8
; break;
1629 case 6: op
= rv_op_ori
; break;
1630 case 7: op
= rv_op_andi
; break;
1633 case 5: op
= rv_op_auipc
; break;
1635 switch (((inst
>> 12) & 0b111)) {
1636 case 0: op
= rv_op_addiw
; break;
1638 switch (((inst
>> 25) & 0b1111111)) {
1639 case 0: op
= rv_op_slliw
; break;
1640 case 4: op
= rv_op_slli_uw
; break;
1642 switch ((inst
>> 20) & 0b11111) {
1643 case 0b00000: op
= rv_op_clzw
; break;
1644 case 0b00001: op
= rv_op_ctzw
; break;
1645 case 0b00010: op
= rv_op_cpopw
; break;
1651 switch (((inst
>> 25) & 0b1111111)) {
1652 case 0: op
= rv_op_srliw
; break;
1653 case 32: op
= rv_op_sraiw
; break;
1654 case 48: op
= rv_op_roriw
; break;
1660 switch (((inst
>> 12) & 0b111)) {
1661 case 0: op
= rv_op_sb
; break;
1662 case 1: op
= rv_op_sh
; break;
1663 case 2: op
= rv_op_sw
; break;
1664 case 3: op
= rv_op_sd
; break;
1665 case 4: op
= rv_op_sq
; break;
1669 switch (((inst
>> 12) & 0b111)) {
1670 case 2: op
= rv_op_fsw
; break;
1671 case 3: op
= rv_op_fsd
; break;
1672 case 4: op
= rv_op_fsq
; break;
1676 switch (((inst
>> 24) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
1677 case 2: op
= rv_op_amoadd_w
; break;
1678 case 3: op
= rv_op_amoadd_d
; break;
1679 case 4: op
= rv_op_amoadd_q
; break;
1680 case 10: op
= rv_op_amoswap_w
; break;
1681 case 11: op
= rv_op_amoswap_d
; break;
1682 case 12: op
= rv_op_amoswap_q
; break;
1684 switch (((inst
>> 20) & 0b11111)) {
1685 case 0: op
= rv_op_lr_w
; break;
1689 switch (((inst
>> 20) & 0b11111)) {
1690 case 0: op
= rv_op_lr_d
; break;
1694 switch (((inst
>> 20) & 0b11111)) {
1695 case 0: op
= rv_op_lr_q
; break;
1698 case 26: op
= rv_op_sc_w
; break;
1699 case 27: op
= rv_op_sc_d
; break;
1700 case 28: op
= rv_op_sc_q
; break;
1701 case 34: op
= rv_op_amoxor_w
; break;
1702 case 35: op
= rv_op_amoxor_d
; break;
1703 case 36: op
= rv_op_amoxor_q
; break;
1704 case 66: op
= rv_op_amoor_w
; break;
1705 case 67: op
= rv_op_amoor_d
; break;
1706 case 68: op
= rv_op_amoor_q
; break;
1707 case 98: op
= rv_op_amoand_w
; break;
1708 case 99: op
= rv_op_amoand_d
; break;
1709 case 100: op
= rv_op_amoand_q
; break;
1710 case 130: op
= rv_op_amomin_w
; break;
1711 case 131: op
= rv_op_amomin_d
; break;
1712 case 132: op
= rv_op_amomin_q
; break;
1713 case 162: op
= rv_op_amomax_w
; break;
1714 case 163: op
= rv_op_amomax_d
; break;
1715 case 164: op
= rv_op_amomax_q
; break;
1716 case 194: op
= rv_op_amominu_w
; break;
1717 case 195: op
= rv_op_amominu_d
; break;
1718 case 196: op
= rv_op_amominu_q
; break;
1719 case 226: op
= rv_op_amomaxu_w
; break;
1720 case 227: op
= rv_op_amomaxu_d
; break;
1721 case 228: op
= rv_op_amomaxu_q
; break;
1725 switch (((inst
>> 22) & 0b1111111000) | ((inst
>> 12) & 0b0000000111)) {
1726 case 0: op
= rv_op_add
; break;
1727 case 1: op
= rv_op_sll
; break;
1728 case 2: op
= rv_op_slt
; break;
1729 case 3: op
= rv_op_sltu
; break;
1730 case 4: op
= rv_op_xor
; break;
1731 case 5: op
= rv_op_srl
; break;
1732 case 6: op
= rv_op_or
; break;
1733 case 7: op
= rv_op_and
; break;
1734 case 8: op
= rv_op_mul
; break;
1735 case 9: op
= rv_op_mulh
; break;
1736 case 10: op
= rv_op_mulhsu
; break;
1737 case 11: op
= rv_op_mulhu
; break;
1738 case 12: op
= rv_op_div
; break;
1739 case 13: op
= rv_op_divu
; break;
1740 case 14: op
= rv_op_rem
; break;
1741 case 15: op
= rv_op_remu
; break;
1743 switch ((inst
>> 20) & 0b11111) {
1744 case 0: op
= rv_op_zext_h
; break;
1747 case 41: op
= rv_op_clmul
; break;
1748 case 42: op
= rv_op_clmulr
; break;
1749 case 43: op
= rv_op_clmulh
; break;
1750 case 44: op
= rv_op_min
; break;
1751 case 45: op
= rv_op_minu
; break;
1752 case 46: op
= rv_op_max
; break;
1753 case 47: op
= rv_op_maxu
; break;
1754 case 130: op
= rv_op_sh1add
; break;
1755 case 132: op
= rv_op_sh2add
; break;
1756 case 134: op
= rv_op_sh3add
; break;
1757 case 161: op
= rv_op_bset
; break;
1758 case 256: op
= rv_op_sub
; break;
1759 case 260: op
= rv_op_xnor
; break;
1760 case 261: op
= rv_op_sra
; break;
1761 case 262: op
= rv_op_orn
; break;
1762 case 263: op
= rv_op_andn
; break;
1763 case 289: op
= rv_op_bclr
; break;
1764 case 293: op
= rv_op_bext
; break;
1765 case 385: op
= rv_op_rol
; break;
1766 case 386: op
= rv_op_ror
; break;
1767 case 417: op
= rv_op_binv
; break;
1770 case 13: op
= rv_op_lui
; break;
1772 switch (((inst
>> 22) & 0b1111111000) | ((inst
>> 12) & 0b0000000111)) {
1773 case 0: op
= rv_op_addw
; break;
1774 case 1: op
= rv_op_sllw
; break;
1775 case 5: op
= rv_op_srlw
; break;
1776 case 8: op
= rv_op_mulw
; break;
1777 case 12: op
= rv_op_divw
; break;
1778 case 13: op
= rv_op_divuw
; break;
1779 case 14: op
= rv_op_remw
; break;
1780 case 15: op
= rv_op_remuw
; break;
1781 case 32: op
= rv_op_add_uw
; break;
1783 switch ((inst
>> 20) & 0b11111) {
1784 case 0: op
= rv_op_zext_h
; break;
1787 case 130: op
= rv_op_sh1add_uw
; break;
1788 case 132: op
= rv_op_sh2add_uw
; break;
1789 case 134: op
= rv_op_sh3add_uw
; break;
1790 case 256: op
= rv_op_subw
; break;
1791 case 261: op
= rv_op_sraw
; break;
1792 case 385: op
= rv_op_rolw
; break;
1793 case 389: op
= rv_op_rorw
; break;
1797 switch (((inst
>> 25) & 0b11)) {
1798 case 0: op
= rv_op_fmadd_s
; break;
1799 case 1: op
= rv_op_fmadd_d
; break;
1800 case 3: op
= rv_op_fmadd_q
; break;
1804 switch (((inst
>> 25) & 0b11)) {
1805 case 0: op
= rv_op_fmsub_s
; break;
1806 case 1: op
= rv_op_fmsub_d
; break;
1807 case 3: op
= rv_op_fmsub_q
; break;
1811 switch (((inst
>> 25) & 0b11)) {
1812 case 0: op
= rv_op_fnmsub_s
; break;
1813 case 1: op
= rv_op_fnmsub_d
; break;
1814 case 3: op
= rv_op_fnmsub_q
; break;
1818 switch (((inst
>> 25) & 0b11)) {
1819 case 0: op
= rv_op_fnmadd_s
; break;
1820 case 1: op
= rv_op_fnmadd_d
; break;
1821 case 3: op
= rv_op_fnmadd_q
; break;
1825 switch (((inst
>> 25) & 0b1111111)) {
1826 case 0: op
= rv_op_fadd_s
; break;
1827 case 1: op
= rv_op_fadd_d
; break;
1828 case 3: op
= rv_op_fadd_q
; break;
1829 case 4: op
= rv_op_fsub_s
; break;
1830 case 5: op
= rv_op_fsub_d
; break;
1831 case 7: op
= rv_op_fsub_q
; break;
1832 case 8: op
= rv_op_fmul_s
; break;
1833 case 9: op
= rv_op_fmul_d
; break;
1834 case 11: op
= rv_op_fmul_q
; break;
1835 case 12: op
= rv_op_fdiv_s
; break;
1836 case 13: op
= rv_op_fdiv_d
; break;
1837 case 15: op
= rv_op_fdiv_q
; break;
1839 switch (((inst
>> 12) & 0b111)) {
1840 case 0: op
= rv_op_fsgnj_s
; break;
1841 case 1: op
= rv_op_fsgnjn_s
; break;
1842 case 2: op
= rv_op_fsgnjx_s
; break;
1846 switch (((inst
>> 12) & 0b111)) {
1847 case 0: op
= rv_op_fsgnj_d
; break;
1848 case 1: op
= rv_op_fsgnjn_d
; break;
1849 case 2: op
= rv_op_fsgnjx_d
; break;
1853 switch (((inst
>> 12) & 0b111)) {
1854 case 0: op
= rv_op_fsgnj_q
; break;
1855 case 1: op
= rv_op_fsgnjn_q
; break;
1856 case 2: op
= rv_op_fsgnjx_q
; break;
1860 switch (((inst
>> 12) & 0b111)) {
1861 case 0: op
= rv_op_fmin_s
; break;
1862 case 1: op
= rv_op_fmax_s
; break;
1866 switch (((inst
>> 12) & 0b111)) {
1867 case 0: op
= rv_op_fmin_d
; break;
1868 case 1: op
= rv_op_fmax_d
; break;
1872 switch (((inst
>> 12) & 0b111)) {
1873 case 0: op
= rv_op_fmin_q
; break;
1874 case 1: op
= rv_op_fmax_q
; break;
1878 switch (((inst
>> 20) & 0b11111)) {
1879 case 1: op
= rv_op_fcvt_s_d
; break;
1880 case 3: op
= rv_op_fcvt_s_q
; break;
1884 switch (((inst
>> 20) & 0b11111)) {
1885 case 0: op
= rv_op_fcvt_d_s
; break;
1886 case 3: op
= rv_op_fcvt_d_q
; break;
1890 switch (((inst
>> 20) & 0b11111)) {
1891 case 0: op
= rv_op_fcvt_q_s
; break;
1892 case 1: op
= rv_op_fcvt_q_d
; break;
1896 switch (((inst
>> 20) & 0b11111)) {
1897 case 0: op
= rv_op_fsqrt_s
; break;
1901 switch (((inst
>> 20) & 0b11111)) {
1902 case 0: op
= rv_op_fsqrt_d
; break;
1906 switch (((inst
>> 20) & 0b11111)) {
1907 case 0: op
= rv_op_fsqrt_q
; break;
1911 switch (((inst
>> 12) & 0b111)) {
1912 case 0: op
= rv_op_fle_s
; break;
1913 case 1: op
= rv_op_flt_s
; break;
1914 case 2: op
= rv_op_feq_s
; break;
1918 switch (((inst
>> 12) & 0b111)) {
1919 case 0: op
= rv_op_fle_d
; break;
1920 case 1: op
= rv_op_flt_d
; break;
1921 case 2: op
= rv_op_feq_d
; break;
1925 switch (((inst
>> 12) & 0b111)) {
1926 case 0: op
= rv_op_fle_q
; break;
1927 case 1: op
= rv_op_flt_q
; break;
1928 case 2: op
= rv_op_feq_q
; break;
1932 switch (((inst
>> 20) & 0b11111)) {
1933 case 0: op
= rv_op_fcvt_w_s
; break;
1934 case 1: op
= rv_op_fcvt_wu_s
; break;
1935 case 2: op
= rv_op_fcvt_l_s
; break;
1936 case 3: op
= rv_op_fcvt_lu_s
; break;
1940 switch (((inst
>> 20) & 0b11111)) {
1941 case 0: op
= rv_op_fcvt_w_d
; break;
1942 case 1: op
= rv_op_fcvt_wu_d
; break;
1943 case 2: op
= rv_op_fcvt_l_d
; break;
1944 case 3: op
= rv_op_fcvt_lu_d
; break;
1948 switch (((inst
>> 20) & 0b11111)) {
1949 case 0: op
= rv_op_fcvt_w_q
; break;
1950 case 1: op
= rv_op_fcvt_wu_q
; break;
1951 case 2: op
= rv_op_fcvt_l_q
; break;
1952 case 3: op
= rv_op_fcvt_lu_q
; break;
1956 switch (((inst
>> 20) & 0b11111)) {
1957 case 0: op
= rv_op_fcvt_s_w
; break;
1958 case 1: op
= rv_op_fcvt_s_wu
; break;
1959 case 2: op
= rv_op_fcvt_s_l
; break;
1960 case 3: op
= rv_op_fcvt_s_lu
; break;
1964 switch (((inst
>> 20) & 0b11111)) {
1965 case 0: op
= rv_op_fcvt_d_w
; break;
1966 case 1: op
= rv_op_fcvt_d_wu
; break;
1967 case 2: op
= rv_op_fcvt_d_l
; break;
1968 case 3: op
= rv_op_fcvt_d_lu
; break;
1972 switch (((inst
>> 20) & 0b11111)) {
1973 case 0: op
= rv_op_fcvt_q_w
; break;
1974 case 1: op
= rv_op_fcvt_q_wu
; break;
1975 case 2: op
= rv_op_fcvt_q_l
; break;
1976 case 3: op
= rv_op_fcvt_q_lu
; break;
1980 switch (((inst
>> 17) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
1981 case 0: op
= rv_op_fmv_x_s
; break;
1982 case 1: op
= rv_op_fclass_s
; break;
1986 switch (((inst
>> 17) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
1987 case 0: op
= rv_op_fmv_x_d
; break;
1988 case 1: op
= rv_op_fclass_d
; break;
1992 switch (((inst
>> 17) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
1993 case 0: op
= rv_op_fmv_x_q
; break;
1994 case 1: op
= rv_op_fclass_q
; break;
1998 switch (((inst
>> 17) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
1999 case 0: op
= rv_op_fmv_s_x
; break;
2003 switch (((inst
>> 17) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
2004 case 0: op
= rv_op_fmv_d_x
; break;
2008 switch (((inst
>> 17) & 0b11111000) | ((inst
>> 12) & 0b00000111)) {
2009 case 0: op
= rv_op_fmv_q_x
; break;
2015 switch (((inst
>> 12) & 0b111)) {
2016 case 0: op
= rv_op_addid
; break;
2018 switch (((inst
>> 26) & 0b111111)) {
2019 case 0: op
= rv_op_sllid
; break;
2023 switch (((inst
>> 26) & 0b111111)) {
2024 case 0: op
= rv_op_srlid
; break;
2025 case 16: op
= rv_op_sraid
; break;
2031 switch (((inst
>> 12) & 0b111)) {
2032 case 0: op
= rv_op_beq
; break;
2033 case 1: op
= rv_op_bne
; break;
2034 case 4: op
= rv_op_blt
; break;
2035 case 5: op
= rv_op_bge
; break;
2036 case 6: op
= rv_op_bltu
; break;
2037 case 7: op
= rv_op_bgeu
; break;
2041 switch (((inst
>> 12) & 0b111)) {
2042 case 0: op
= rv_op_jalr
; break;
2045 case 27: op
= rv_op_jal
; break;
2047 switch (((inst
>> 12) & 0b111)) {
2049 switch (((inst
>> 20) & 0b111111100000) | ((inst
>> 7) & 0b000000011111)) {
2051 switch (((inst
>> 15) & 0b1111111111)) {
2052 case 0: op
= rv_op_ecall
; break;
2053 case 32: op
= rv_op_ebreak
; break;
2054 case 64: op
= rv_op_uret
; break;
2058 switch (((inst
>> 20) & 0b11111)) {
2060 switch (((inst
>> 15) & 0b11111)) {
2061 case 0: op
= rv_op_sret
; break;
2064 case 4: op
= rv_op_sfence_vm
; break;
2066 switch (((inst
>> 15) & 0b11111)) {
2067 case 0: op
= rv_op_wfi
; break;
2072 case 288: op
= rv_op_sfence_vma
; break;
2074 switch (((inst
>> 15) & 0b1111111111)) {
2075 case 64: op
= rv_op_hret
; break;
2079 switch (((inst
>> 15) & 0b1111111111)) {
2080 case 64: op
= rv_op_mret
; break;
2084 switch (((inst
>> 15) & 0b1111111111)) {
2085 case 576: op
= rv_op_dret
; break;
2090 case 1: op
= rv_op_csrrw
; break;
2091 case 2: op
= rv_op_csrrs
; break;
2092 case 3: op
= rv_op_csrrc
; break;
2093 case 5: op
= rv_op_csrrwi
; break;
2094 case 6: op
= rv_op_csrrsi
; break;
2095 case 7: op
= rv_op_csrrci
; break;
2099 switch (((inst
>> 22) & 0b1111111000) | ((inst
>> 12) & 0b0000000111)) {
2100 case 0: op
= rv_op_addd
; break;
2101 case 1: op
= rv_op_slld
; break;
2102 case 5: op
= rv_op_srld
; break;
2103 case 8: op
= rv_op_muld
; break;
2104 case 12: op
= rv_op_divd
; break;
2105 case 13: op
= rv_op_divud
; break;
2106 case 14: op
= rv_op_remd
; break;
2107 case 15: op
= rv_op_remud
; break;
2108 case 256: op
= rv_op_subd
; break;
2109 case 261: op
= rv_op_srad
; break;
2118 /* operand extractors */
2120 static uint32_t operand_rd(rv_inst inst
)
2122 return (inst
<< 52) >> 59;
2125 static uint32_t operand_rs1(rv_inst inst
)
2127 return (inst
<< 44) >> 59;
2130 static uint32_t operand_rs2(rv_inst inst
)
2132 return (inst
<< 39) >> 59;
2135 static uint32_t operand_rs3(rv_inst inst
)
2137 return (inst
<< 32) >> 59;
2140 static uint32_t operand_aq(rv_inst inst
)
2142 return (inst
<< 37) >> 63;
2145 static uint32_t operand_rl(rv_inst inst
)
2147 return (inst
<< 38) >> 63;
2150 static uint32_t operand_pred(rv_inst inst
)
2152 return (inst
<< 36) >> 60;
2155 static uint32_t operand_succ(rv_inst inst
)
2157 return (inst
<< 40) >> 60;
2160 static uint32_t operand_rm(rv_inst inst
)
2162 return (inst
<< 49) >> 61;
2165 static uint32_t operand_shamt5(rv_inst inst
)
2167 return (inst
<< 39) >> 59;
2170 static uint32_t operand_shamt6(rv_inst inst
)
2172 return (inst
<< 38) >> 58;
2175 static uint32_t operand_shamt7(rv_inst inst
)
2177 return (inst
<< 37) >> 57;
2180 static uint32_t operand_crdq(rv_inst inst
)
2182 return (inst
<< 59) >> 61;
2185 static uint32_t operand_crs1q(rv_inst inst
)
2187 return (inst
<< 54) >> 61;
2190 static uint32_t operand_crs1rdq(rv_inst inst
)
2192 return (inst
<< 54) >> 61;
2195 static uint32_t operand_crs2q(rv_inst inst
)
2197 return (inst
<< 59) >> 61;
2200 static uint32_t operand_crd(rv_inst inst
)
2202 return (inst
<< 52) >> 59;
2205 static uint32_t operand_crs1(rv_inst inst
)
2207 return (inst
<< 52) >> 59;
2210 static uint32_t operand_crs1rd(rv_inst inst
)
2212 return (inst
<< 52) >> 59;
2215 static uint32_t operand_crs2(rv_inst inst
)
2217 return (inst
<< 57) >> 59;
2220 static uint32_t operand_cimmsh5(rv_inst inst
)
2222 return (inst
<< 57) >> 59;
2225 static uint32_t operand_csr12(rv_inst inst
)
2227 return (inst
<< 32) >> 52;
2230 static int32_t operand_imm12(rv_inst inst
)
2232 return ((int64_t)inst
<< 32) >> 52;
2235 static int32_t operand_imm20(rv_inst inst
)
2237 return (((int64_t)inst
<< 32) >> 44) << 12;
2240 static int32_t operand_jimm20(rv_inst inst
)
2242 return (((int64_t)inst
<< 32) >> 63) << 20 |
2243 ((inst
<< 33) >> 54) << 1 |
2244 ((inst
<< 43) >> 63) << 11 |
2245 ((inst
<< 44) >> 56) << 12;
2248 static int32_t operand_simm12(rv_inst inst
)
2250 return (((int64_t)inst
<< 32) >> 57) << 5 |
2254 static int32_t operand_sbimm12(rv_inst inst
)
2256 return (((int64_t)inst
<< 32) >> 63) << 12 |
2257 ((inst
<< 33) >> 58) << 5 |
2258 ((inst
<< 52) >> 60) << 1 |
2259 ((inst
<< 56) >> 63) << 11;
2262 static uint32_t operand_cimmsh6(rv_inst inst
)
2264 return ((inst
<< 51) >> 63) << 5 |
2268 static int32_t operand_cimmi(rv_inst inst
)
2270 return (((int64_t)inst
<< 51) >> 63) << 5 |
2274 static int32_t operand_cimmui(rv_inst inst
)
2276 return (((int64_t)inst
<< 51) >> 63) << 17 |
2277 ((inst
<< 57) >> 59) << 12;
2280 static uint32_t operand_cimmlwsp(rv_inst inst
)
2282 return ((inst
<< 51) >> 63) << 5 |
2283 ((inst
<< 57) >> 61) << 2 |
2284 ((inst
<< 60) >> 62) << 6;
2287 static uint32_t operand_cimmldsp(rv_inst inst
)
2289 return ((inst
<< 51) >> 63) << 5 |
2290 ((inst
<< 57) >> 62) << 3 |
2291 ((inst
<< 59) >> 61) << 6;
2294 static uint32_t operand_cimmlqsp(rv_inst inst
)
2296 return ((inst
<< 51) >> 63) << 5 |
2297 ((inst
<< 57) >> 63) << 4 |
2298 ((inst
<< 58) >> 60) << 6;
2301 static int32_t operand_cimm16sp(rv_inst inst
)
2303 return (((int64_t)inst
<< 51) >> 63) << 9 |
2304 ((inst
<< 57) >> 63) << 4 |
2305 ((inst
<< 58) >> 63) << 6 |
2306 ((inst
<< 59) >> 62) << 7 |
2307 ((inst
<< 61) >> 63) << 5;
2310 static int32_t operand_cimmj(rv_inst inst
)
2312 return (((int64_t)inst
<< 51) >> 63) << 11 |
2313 ((inst
<< 52) >> 63) << 4 |
2314 ((inst
<< 53) >> 62) << 8 |
2315 ((inst
<< 55) >> 63) << 10 |
2316 ((inst
<< 56) >> 63) << 6 |
2317 ((inst
<< 57) >> 63) << 7 |
2318 ((inst
<< 58) >> 61) << 1 |
2319 ((inst
<< 61) >> 63) << 5;
2322 static int32_t operand_cimmb(rv_inst inst
)
2324 return (((int64_t)inst
<< 51) >> 63) << 8 |
2325 ((inst
<< 52) >> 62) << 3 |
2326 ((inst
<< 57) >> 62) << 6 |
2327 ((inst
<< 59) >> 62) << 1 |
2328 ((inst
<< 61) >> 63) << 5;
2331 static uint32_t operand_cimmswsp(rv_inst inst
)
2333 return ((inst
<< 51) >> 60) << 2 |
2334 ((inst
<< 55) >> 62) << 6;
2337 static uint32_t operand_cimmsdsp(rv_inst inst
)
2339 return ((inst
<< 51) >> 61) << 3 |
2340 ((inst
<< 54) >> 61) << 6;
2343 static uint32_t operand_cimmsqsp(rv_inst inst
)
2345 return ((inst
<< 51) >> 62) << 4 |
2346 ((inst
<< 53) >> 60) << 6;
2349 static uint32_t operand_cimm4spn(rv_inst inst
)
2351 return ((inst
<< 51) >> 62) << 4 |
2352 ((inst
<< 53) >> 60) << 6 |
2353 ((inst
<< 57) >> 63) << 2 |
2354 ((inst
<< 58) >> 63) << 3;
2357 static uint32_t operand_cimmw(rv_inst inst
)
2359 return ((inst
<< 51) >> 61) << 3 |
2360 ((inst
<< 57) >> 63) << 2 |
2361 ((inst
<< 58) >> 63) << 6;
2364 static uint32_t operand_cimmd(rv_inst inst
)
2366 return ((inst
<< 51) >> 61) << 3 |
2367 ((inst
<< 57) >> 62) << 6;
2370 static uint32_t operand_cimmq(rv_inst inst
)
2372 return ((inst
<< 51) >> 62) << 4 |
2373 ((inst
<< 53) >> 63) << 8 |
2374 ((inst
<< 57) >> 62) << 6;
2377 /* decode operands */
2379 static void decode_inst_operands(rv_decode
*dec
)
2381 rv_inst inst
= dec
->inst
;
2382 dec
->codec
= opcode_data
[dec
->op
].codec
;
2383 switch (dec
->codec
) {
2385 dec
->rd
= dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2389 dec
->rd
= operand_rd(inst
);
2390 dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2391 dec
->imm
= operand_imm20(inst
);
2394 dec
->rd
= operand_rd(inst
);
2395 dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2396 dec
->imm
= operand_jimm20(inst
);
2399 dec
->rd
= operand_rd(inst
);
2400 dec
->rs1
= operand_rs1(inst
);
2401 dec
->rs2
= rv_ireg_zero
;
2402 dec
->imm
= operand_imm12(inst
);
2404 case rv_codec_i_sh5
:
2405 dec
->rd
= operand_rd(inst
);
2406 dec
->rs1
= operand_rs1(inst
);
2407 dec
->rs2
= rv_ireg_zero
;
2408 dec
->imm
= operand_shamt5(inst
);
2410 case rv_codec_i_sh6
:
2411 dec
->rd
= operand_rd(inst
);
2412 dec
->rs1
= operand_rs1(inst
);
2413 dec
->rs2
= rv_ireg_zero
;
2414 dec
->imm
= operand_shamt6(inst
);
2416 case rv_codec_i_sh7
:
2417 dec
->rd
= operand_rd(inst
);
2418 dec
->rs1
= operand_rs1(inst
);
2419 dec
->rs2
= rv_ireg_zero
;
2420 dec
->imm
= operand_shamt7(inst
);
2422 case rv_codec_i_csr
:
2423 dec
->rd
= operand_rd(inst
);
2424 dec
->rs1
= operand_rs1(inst
);
2425 dec
->rs2
= rv_ireg_zero
;
2426 dec
->imm
= operand_csr12(inst
);
2429 dec
->rd
= rv_ireg_zero
;
2430 dec
->rs1
= operand_rs1(inst
);
2431 dec
->rs2
= operand_rs2(inst
);
2432 dec
->imm
= operand_simm12(inst
);
2435 dec
->rd
= rv_ireg_zero
;
2436 dec
->rs1
= operand_rs1(inst
);
2437 dec
->rs2
= operand_rs2(inst
);
2438 dec
->imm
= operand_sbimm12(inst
);
2441 dec
->rd
= operand_rd(inst
);
2442 dec
->rs1
= operand_rs1(inst
);
2443 dec
->rs2
= operand_rs2(inst
);
2447 dec
->rd
= operand_rd(inst
);
2448 dec
->rs1
= operand_rs1(inst
);
2449 dec
->rs2
= operand_rs2(inst
);
2451 dec
->rm
= operand_rm(inst
);
2454 dec
->rd
= operand_rd(inst
);
2455 dec
->rs1
= operand_rs1(inst
);
2456 dec
->rs2
= operand_rs2(inst
);
2457 dec
->rs3
= operand_rs3(inst
);
2459 dec
->rm
= operand_rm(inst
);
2462 dec
->rd
= operand_rd(inst
);
2463 dec
->rs1
= operand_rs1(inst
);
2464 dec
->rs2
= operand_rs2(inst
);
2466 dec
->aq
= operand_aq(inst
);
2467 dec
->rl
= operand_rl(inst
);
2470 dec
->rd
= operand_rd(inst
);
2471 dec
->rs1
= operand_rs1(inst
);
2472 dec
->rs2
= rv_ireg_zero
;
2474 dec
->aq
= operand_aq(inst
);
2475 dec
->rl
= operand_rl(inst
);
2478 dec
->rd
= dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2479 dec
->pred
= operand_pred(inst
);
2480 dec
->succ
= operand_succ(inst
);
2484 dec
->rd
= rv_ireg_zero
;
2485 dec
->rs1
= operand_crs1q(inst
) + 8;
2486 dec
->rs2
= rv_ireg_zero
;
2487 dec
->imm
= operand_cimmb(inst
);
2489 case rv_codec_cb_imm
:
2490 dec
->rd
= dec
->rs1
= operand_crs1rdq(inst
) + 8;
2491 dec
->rs2
= rv_ireg_zero
;
2492 dec
->imm
= operand_cimmi(inst
);
2494 case rv_codec_cb_sh5
:
2495 dec
->rd
= dec
->rs1
= operand_crs1rdq(inst
) + 8;
2496 dec
->rs2
= rv_ireg_zero
;
2497 dec
->imm
= operand_cimmsh5(inst
);
2499 case rv_codec_cb_sh6
:
2500 dec
->rd
= dec
->rs1
= operand_crs1rdq(inst
) + 8;
2501 dec
->rs2
= rv_ireg_zero
;
2502 dec
->imm
= operand_cimmsh6(inst
);
2505 dec
->rd
= dec
->rs1
= operand_crs1rd(inst
);
2506 dec
->rs2
= rv_ireg_zero
;
2507 dec
->imm
= operand_cimmi(inst
);
2509 case rv_codec_ci_sh5
:
2510 dec
->rd
= dec
->rs1
= operand_crs1rd(inst
);
2511 dec
->rs2
= rv_ireg_zero
;
2512 dec
->imm
= operand_cimmsh5(inst
);
2514 case rv_codec_ci_sh6
:
2515 dec
->rd
= dec
->rs1
= operand_crs1rd(inst
);
2516 dec
->rs2
= rv_ireg_zero
;
2517 dec
->imm
= operand_cimmsh6(inst
);
2519 case rv_codec_ci_16sp
:
2520 dec
->rd
= rv_ireg_sp
;
2521 dec
->rs1
= rv_ireg_sp
;
2522 dec
->rs2
= rv_ireg_zero
;
2523 dec
->imm
= operand_cimm16sp(inst
);
2525 case rv_codec_ci_lwsp
:
2526 dec
->rd
= operand_crd(inst
);
2527 dec
->rs1
= rv_ireg_sp
;
2528 dec
->rs2
= rv_ireg_zero
;
2529 dec
->imm
= operand_cimmlwsp(inst
);
2531 case rv_codec_ci_ldsp
:
2532 dec
->rd
= operand_crd(inst
);
2533 dec
->rs1
= rv_ireg_sp
;
2534 dec
->rs2
= rv_ireg_zero
;
2535 dec
->imm
= operand_cimmldsp(inst
);
2537 case rv_codec_ci_lqsp
:
2538 dec
->rd
= operand_crd(inst
);
2539 dec
->rs1
= rv_ireg_sp
;
2540 dec
->rs2
= rv_ireg_zero
;
2541 dec
->imm
= operand_cimmlqsp(inst
);
2543 case rv_codec_ci_li
:
2544 dec
->rd
= operand_crd(inst
);
2545 dec
->rs1
= rv_ireg_zero
;
2546 dec
->rs2
= rv_ireg_zero
;
2547 dec
->imm
= operand_cimmi(inst
);
2549 case rv_codec_ci_lui
:
2550 dec
->rd
= operand_crd(inst
);
2551 dec
->rs1
= rv_ireg_zero
;
2552 dec
->rs2
= rv_ireg_zero
;
2553 dec
->imm
= operand_cimmui(inst
);
2555 case rv_codec_ci_none
:
2556 dec
->rd
= dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2559 case rv_codec_ciw_4spn
:
2560 dec
->rd
= operand_crdq(inst
) + 8;
2561 dec
->rs1
= rv_ireg_sp
;
2562 dec
->rs2
= rv_ireg_zero
;
2563 dec
->imm
= operand_cimm4spn(inst
);
2566 dec
->rd
= dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2567 dec
->imm
= operand_cimmj(inst
);
2569 case rv_codec_cj_jal
:
2570 dec
->rd
= rv_ireg_ra
;
2571 dec
->rs1
= dec
->rs2
= rv_ireg_zero
;
2572 dec
->imm
= operand_cimmj(inst
);
2574 case rv_codec_cl_lw
:
2575 dec
->rd
= operand_crdq(inst
) + 8;
2576 dec
->rs1
= operand_crs1q(inst
) + 8;
2577 dec
->rs2
= rv_ireg_zero
;
2578 dec
->imm
= operand_cimmw(inst
);
2580 case rv_codec_cl_ld
:
2581 dec
->rd
= operand_crdq(inst
) + 8;
2582 dec
->rs1
= operand_crs1q(inst
) + 8;
2583 dec
->rs2
= rv_ireg_zero
;
2584 dec
->imm
= operand_cimmd(inst
);
2586 case rv_codec_cl_lq
:
2587 dec
->rd
= operand_crdq(inst
) + 8;
2588 dec
->rs1
= operand_crs1q(inst
) + 8;
2589 dec
->rs2
= rv_ireg_zero
;
2590 dec
->imm
= operand_cimmq(inst
);
2593 dec
->rd
= dec
->rs1
= operand_crs1rd(inst
);
2594 dec
->rs2
= operand_crs2(inst
);
2597 case rv_codec_cr_mv
:
2598 dec
->rd
= operand_crd(inst
);
2599 dec
->rs1
= operand_crs2(inst
);
2600 dec
->rs2
= rv_ireg_zero
;
2603 case rv_codec_cr_jalr
:
2604 dec
->rd
= rv_ireg_ra
;
2605 dec
->rs1
= operand_crs1(inst
);
2606 dec
->rs2
= rv_ireg_zero
;
2609 case rv_codec_cr_jr
:
2610 dec
->rd
= rv_ireg_zero
;
2611 dec
->rs1
= operand_crs1(inst
);
2612 dec
->rs2
= rv_ireg_zero
;
2616 dec
->rd
= dec
->rs1
= operand_crs1rdq(inst
) + 8;
2617 dec
->rs2
= operand_crs2q(inst
) + 8;
2620 case rv_codec_cs_sw
:
2621 dec
->rd
= rv_ireg_zero
;
2622 dec
->rs1
= operand_crs1q(inst
) + 8;
2623 dec
->rs2
= operand_crs2q(inst
) + 8;
2624 dec
->imm
= operand_cimmw(inst
);
2626 case rv_codec_cs_sd
:
2627 dec
->rd
= rv_ireg_zero
;
2628 dec
->rs1
= operand_crs1q(inst
) + 8;
2629 dec
->rs2
= operand_crs2q(inst
) + 8;
2630 dec
->imm
= operand_cimmd(inst
);
2632 case rv_codec_cs_sq
:
2633 dec
->rd
= rv_ireg_zero
;
2634 dec
->rs1
= operand_crs1q(inst
) + 8;
2635 dec
->rs2
= operand_crs2q(inst
) + 8;
2636 dec
->imm
= operand_cimmq(inst
);
2638 case rv_codec_css_swsp
:
2639 dec
->rd
= rv_ireg_zero
;
2640 dec
->rs1
= rv_ireg_sp
;
2641 dec
->rs2
= operand_crs2(inst
);
2642 dec
->imm
= operand_cimmswsp(inst
);
2644 case rv_codec_css_sdsp
:
2645 dec
->rd
= rv_ireg_zero
;
2646 dec
->rs1
= rv_ireg_sp
;
2647 dec
->rs2
= operand_crs2(inst
);
2648 dec
->imm
= operand_cimmsdsp(inst
);
2650 case rv_codec_css_sqsp
:
2651 dec
->rd
= rv_ireg_zero
;
2652 dec
->rs1
= rv_ireg_sp
;
2653 dec
->rs2
= operand_crs2(inst
);
2654 dec
->imm
= operand_cimmsqsp(inst
);
2659 /* check constraint */
2661 static bool check_constraints(rv_decode
*dec
, const rvc_constraint
*c
)
2663 int32_t imm
= dec
->imm
;
2664 uint8_t rd
= dec
->rd
, rs1
= dec
->rs1
, rs2
= dec
->rs2
;
2665 while (*c
!= rvc_end
) {
2687 case rvc_rs2_eq_rs1
:
2688 if (!(rs2
== rs1
)) {
2697 case rvc_imm_eq_zero
:
2712 case rvc_csr_eq_0x001
:
2713 if (!(imm
== 0x001)) {
2717 case rvc_csr_eq_0x002
:
2718 if (!(imm
== 0x002)) {
2722 case rvc_csr_eq_0x003
:
2723 if (!(imm
== 0x003)) {
2727 case rvc_csr_eq_0xc00
:
2728 if (!(imm
== 0xc00)) {
2732 case rvc_csr_eq_0xc01
:
2733 if (!(imm
== 0xc01)) {
2737 case rvc_csr_eq_0xc02
:
2738 if (!(imm
== 0xc02)) {
2742 case rvc_csr_eq_0xc80
:
2743 if (!(imm
== 0xc80)) {
2747 case rvc_csr_eq_0xc81
:
2748 if (!(imm
== 0xc81)) {
2752 case rvc_csr_eq_0xc82
:
2753 if (!(imm
== 0xc82)) {
2764 /* instruction length */
2766 static size_t inst_length(rv_inst inst
)
2768 /* NOTE: supports maximum instruction size of 64-bits */
2770 /* instruction length coding
2772 * aa - 16 bit aa != 11
2773 * bbb11 - 32 bit bbb != 111
2778 return (inst
& 0b11) != 0b11 ? 2
2779 : (inst
& 0b11100) != 0b11100 ? 4
2780 : (inst
& 0b111111) == 0b011111 ? 6
2781 : (inst
& 0b1111111) == 0b0111111 ? 8
2785 /* format instruction */
2787 static void append(char *s1
, const char *s2
, size_t n
)
2789 size_t l1
= strlen(s1
);
2790 if (n
- l1
- 1 > 0) {
2791 strncat(s1
, s2
, n
- l1
);
2795 static void format_inst(char *buf
, size_t buflen
, size_t tab
, rv_decode
*dec
)
2800 fmt
= opcode_data
[dec
->op
].format
;
2804 append(buf
, opcode_data
[dec
->op
].name
, buflen
);
2807 append(buf
, "(", buflen
);
2810 append(buf
, ",", buflen
);
2813 append(buf
, ")", buflen
);
2816 append(buf
, rv_ireg_name_sym
[dec
->rd
], buflen
);
2819 append(buf
, rv_ireg_name_sym
[dec
->rs1
], buflen
);
2822 append(buf
, rv_ireg_name_sym
[dec
->rs2
], buflen
);
2825 append(buf
, rv_freg_name_sym
[dec
->rd
], buflen
);
2828 append(buf
, rv_freg_name_sym
[dec
->rs1
], buflen
);
2831 append(buf
, rv_freg_name_sym
[dec
->rs2
], buflen
);
2834 append(buf
, rv_freg_name_sym
[dec
->rs3
], buflen
);
2837 snprintf(tmp
, sizeof(tmp
), "%d", dec
->rs1
);
2838 append(buf
, tmp
, buflen
);
2841 snprintf(tmp
, sizeof(tmp
), "%d", dec
->imm
);
2842 append(buf
, tmp
, buflen
);
2845 snprintf(tmp
, sizeof(tmp
), "%d", dec
->imm
);
2846 append(buf
, tmp
, buflen
);
2847 while (strlen(buf
) < tab
* 2) {
2848 append(buf
, " ", buflen
);
2850 snprintf(tmp
, sizeof(tmp
), "# 0x%" PRIx64
,
2851 dec
->pc
+ dec
->imm
);
2852 append(buf
, tmp
, buflen
);
2855 const char *name
= csr_name(dec
->imm
& 0xfff);
2857 append(buf
, name
, buflen
);
2859 snprintf(tmp
, sizeof(tmp
), "0x%03x", dec
->imm
& 0xfff);
2860 append(buf
, tmp
, buflen
);
2867 append(buf
, "rne", buflen
);
2870 append(buf
, "rtz", buflen
);
2873 append(buf
, "rdn", buflen
);
2876 append(buf
, "rup", buflen
);
2879 append(buf
, "rmm", buflen
);
2882 append(buf
, "dyn", buflen
);
2885 append(buf
, "inv", buflen
);
2890 if (dec
->pred
& rv_fence_i
) {
2891 append(buf
, "i", buflen
);
2893 if (dec
->pred
& rv_fence_o
) {
2894 append(buf
, "o", buflen
);
2896 if (dec
->pred
& rv_fence_r
) {
2897 append(buf
, "r", buflen
);
2899 if (dec
->pred
& rv_fence_w
) {
2900 append(buf
, "w", buflen
);
2904 if (dec
->succ
& rv_fence_i
) {
2905 append(buf
, "i", buflen
);
2907 if (dec
->succ
& rv_fence_o
) {
2908 append(buf
, "o", buflen
);
2910 if (dec
->succ
& rv_fence_r
) {
2911 append(buf
, "r", buflen
);
2913 if (dec
->succ
& rv_fence_w
) {
2914 append(buf
, "w", buflen
);
2918 while (strlen(buf
) < tab
) {
2919 append(buf
, " ", buflen
);
2924 append(buf
, ".aq", buflen
);
2929 append(buf
, ".rl", buflen
);
2939 /* lift instruction to pseudo-instruction */
2941 static void decode_inst_lift_pseudo(rv_decode
*dec
)
2943 const rv_comp_data
*comp_data
= opcode_data
[dec
->op
].pseudo
;
2947 while (comp_data
->constraints
) {
2948 if (check_constraints(dec
, comp_data
->constraints
)) {
2949 dec
->op
= comp_data
->op
;
2950 dec
->codec
= opcode_data
[dec
->op
].codec
;
2957 /* decompress instruction */
2959 static void decode_inst_decompress_rv32(rv_decode
*dec
)
2961 int decomp_op
= opcode_data
[dec
->op
].decomp_rv32
;
2962 if (decomp_op
!= rv_op_illegal
) {
2963 if ((opcode_data
[dec
->op
].decomp_data
& rvcd_imm_nz
)
2965 dec
->op
= rv_op_illegal
;
2967 dec
->op
= decomp_op
;
2968 dec
->codec
= opcode_data
[decomp_op
].codec
;
2973 static void decode_inst_decompress_rv64(rv_decode
*dec
)
2975 int decomp_op
= opcode_data
[dec
->op
].decomp_rv64
;
2976 if (decomp_op
!= rv_op_illegal
) {
2977 if ((opcode_data
[dec
->op
].decomp_data
& rvcd_imm_nz
)
2979 dec
->op
= rv_op_illegal
;
2981 dec
->op
= decomp_op
;
2982 dec
->codec
= opcode_data
[decomp_op
].codec
;
2987 static void decode_inst_decompress_rv128(rv_decode
*dec
)
2989 int decomp_op
= opcode_data
[dec
->op
].decomp_rv128
;
2990 if (decomp_op
!= rv_op_illegal
) {
2991 if ((opcode_data
[dec
->op
].decomp_data
& rvcd_imm_nz
)
2993 dec
->op
= rv_op_illegal
;
2995 dec
->op
= decomp_op
;
2996 dec
->codec
= opcode_data
[decomp_op
].codec
;
3001 static void decode_inst_decompress(rv_decode
*dec
, rv_isa isa
)
3005 decode_inst_decompress_rv32(dec
);
3008 decode_inst_decompress_rv64(dec
);
3011 decode_inst_decompress_rv128(dec
);
3016 /* disassemble instruction */
3019 disasm_inst(char *buf
, size_t buflen
, rv_isa isa
, uint64_t pc
, rv_inst inst
)
3021 rv_decode dec
= { 0 };
3024 decode_inst_opcode(&dec
, isa
);
3025 decode_inst_operands(&dec
);
3026 decode_inst_decompress(&dec
, isa
);
3027 decode_inst_lift_pseudo(&dec
);
3028 format_inst(buf
, buflen
, 16, &dec
);
3031 #define INST_FMT_2 "%04" PRIx64 " "
3032 #define INST_FMT_4 "%08" PRIx64 " "
3033 #define INST_FMT_6 "%012" PRIx64 " "
3034 #define INST_FMT_8 "%016" PRIx64 " "
3037 print_insn_riscv(bfd_vma memaddr
, struct disassemble_info
*info
, rv_isa isa
)
3039 char buf
[128] = { 0 };
3046 /* Instructions are made of 2-byte packets in little-endian order */
3047 for (n
= 0; n
< len
; n
+= 2) {
3048 status
= (*info
->read_memory_func
)(memaddr
+ n
, packet
, 2, info
);
3050 /* Don't fail just because we fell off the end. */
3054 (*info
->memory_error_func
)(status
, memaddr
, info
);
3057 inst
|= ((rv_inst
) bfd_getl16(packet
)) << (8 * n
);
3059 len
= inst_length(inst
);
3065 (*info
->fprintf_func
)(info
->stream
, INST_FMT_2
, inst
);
3068 (*info
->fprintf_func
)(info
->stream
, INST_FMT_4
, inst
);
3071 (*info
->fprintf_func
)(info
->stream
, INST_FMT_6
, inst
);
3074 (*info
->fprintf_func
)(info
->stream
, INST_FMT_8
, inst
);
3078 disasm_inst(buf
, sizeof(buf
), isa
, memaddr
, inst
);
3079 (*info
->fprintf_func
)(info
->stream
, "%s", buf
);
3084 int print_insn_riscv32(bfd_vma memaddr
, struct disassemble_info
*info
)
3086 return print_insn_riscv(memaddr
, info
, rv32
);
3089 int print_insn_riscv64(bfd_vma memaddr
, struct disassemble_info
*info
)
3091 return print_insn_riscv(memaddr
, info
, rv64
);
3094 int print_insn_riscv128(bfd_vma memaddr
, struct disassemble_info
*info
)
3096 return print_insn_riscv(memaddr
, info
, rv128
);