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;
248 rv_op_amoswap_w = 84,
255 rv_op_amominu_w = 91,
256 rv_op_amomaxu_w = 92,
259 rv_op_amoswap_d = 95,
264 rv_op_amomin_d = 100,
265 rv_op_amomax_d = 101,
266 rv_op_amominu_d = 102,
267 rv_op_amomaxu_d = 103,
270 rv_op_amoswap_q = 106,
271 rv_op_amoadd_q = 107,
272 rv_op_amoxor_q = 108,
274 rv_op_amoand_q = 110,
275 rv_op_amomin_q = 111,
276 rv_op_amomax_q = 112,
277 rv_op_amominu_q = 113,
278 rv_op_amomaxu_q = 114,
286 rv_op_sfence_vm = 122,
287 rv_op_sfence_vma = 123,
299 rv_op_fnmsub_s = 135,
300 rv_op_fnmadd_s = 136,
306 rv_op_fsgnjn_s = 142,
307 rv_op_fsgnjx_s = 143,
314 rv_op_fcvt_w_s = 150,
315 rv_op_fcvt_wu_s = 151,
316 rv_op_fcvt_s_w = 152,
317 rv_op_fcvt_s_wu = 153,
319 rv_op_fclass_s = 155,
321 rv_op_fcvt_l_s = 157,
322 rv_op_fcvt_lu_s = 158,
323 rv_op_fcvt_s_l = 159,
324 rv_op_fcvt_s_lu = 160,
329 rv_op_fnmsub_d = 165,
330 rv_op_fnmadd_d = 166,
336 rv_op_fsgnjn_d = 172,
337 rv_op_fsgnjx_d = 173,
340 rv_op_fcvt_s_d = 176,
341 rv_op_fcvt_d_s = 177,
346 rv_op_fcvt_w_d = 182,
347 rv_op_fcvt_wu_d = 183,
348 rv_op_fcvt_d_w = 184,
349 rv_op_fcvt_d_wu = 185,
350 rv_op_fclass_d = 186,
351 rv_op_fcvt_l_d = 187,
352 rv_op_fcvt_lu_d = 188,
354 rv_op_fcvt_d_l = 190,
355 rv_op_fcvt_d_lu = 191,
361 rv_op_fnmsub_q = 197,
362 rv_op_fnmadd_q = 198,
368 rv_op_fsgnjn_q = 204,
369 rv_op_fsgnjx_q = 205,
372 rv_op_fcvt_s_q = 208,
373 rv_op_fcvt_q_s = 209,
374 rv_op_fcvt_d_q = 210,
375 rv_op_fcvt_q_d = 211,
380 rv_op_fcvt_w_q = 216,
381 rv_op_fcvt_wu_q = 217,
382 rv_op_fcvt_q_w = 218,
383 rv_op_fcvt_q_wu = 219,
384 rv_op_fclass_q = 220,
385 rv_op_fcvt_l_q = 221,
386 rv_op_fcvt_lu_q = 222,
387 rv_op_fcvt_q_l = 223,
388 rv_op_fcvt_q_lu = 224,
391 rv_op_c_addi4spn = 227,
402 rv_op_c_addi16sp = 238,
422 rv_op_c_ebreak = 258,
471 rv_op_rdinstret = 307,
472 rv_op_rdcycleh = 308,
474 rv_op_rdinstreth = 310,
482 rv_op_fsflagsi = 318,
501 rv_op_sh1add_uw = 337,
502 rv_op_sh2add_uw = 338,
503 rv_op_sh3add_uw = 339,
526 rv_op_aes32esmi = 362,
527 rv_op_aes32esi = 363,
528 rv_op_aes32dsmi = 364,
529 rv_op_aes32dsi = 365,
530 rv_op_aes64ks1i = 366,
531 rv_op_aes64ks2 = 367,
533 rv_op_aes64esm = 369,
535 rv_op_aes64dsm = 371,
537 rv_op_sha256sig0 = 373,
538 rv_op_sha256sig1 = 374,
539 rv_op_sha256sum0 = 375,
540 rv_op_sha256sum1 = 376,
541 rv_op_sha512sig0 = 377,
542 rv_op_sha512sig1 = 378,
543 rv_op_sha512sum0 = 379,
544 rv_op_sha512sum1 = 380,
545 rv_op_sha512sum0r = 381,
546 rv_op_sha512sum1r = 382,
547 rv_op_sha512sig0l = 383,
548 rv_op_sha512sig0h = 384,
549 rv_op_sha512sig1l = 385,
550 rv_op_sha512sig1h = 386,
588 const rvc_constraint *constraints;
596 const char * const name;
597 const rv_codec codec;
598 const char * const format;
599 const rv_comp_data *pseudo;
600 const short decomp_rv32;
601 const short decomp_rv64;
602 const short decomp_rv128;
603 const short decomp_data;
608 static const char rv_ireg_name_sym[32][5] = {
609 "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
610 "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
611 "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
612 "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6",
615 static const char rv_freg_name_sym[32][5] = {
616 "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
617 "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
618 "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
619 "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11",
622 /* instruction formats */
624 #define rv_fmt_none "O\t"
625 #define rv_fmt_rs1 "O\t1"
626 #define rv_fmt_offset "O\to"
627 #define rv_fmt_pred_succ "O\tp,s"
628 #define rv_fmt_rs1_rs2 "O\t1,2"
629 #define rv_fmt_rd_imm "O\t0,i"
630 #define rv_fmt_rd_offset "O\t0,o"
631 #define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
632 #define rv_fmt_frd_rs1 "O\t3,1"
633 #define rv_fmt_rd_frs1 "O\t0,4"
634 #define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
635 #define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
636 #define rv_fmt_rm_frd_frs1 "O\tr,3,4"
637 #define rv_fmt_rm_frd_rs1 "O\tr,3,1"
638 #define rv_fmt_rm_rd_frs1 "O\tr,0,4"
639 #define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5"
640 #define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6"
641 #define rv_fmt_rd_rs1_imm "O\t0,1,i"
642 #define rv_fmt_rd_rs1_offset "O\t0,1,i"
643 #define rv_fmt_rd_offset_rs1 "O\t0,i(1)"
644 #define rv_fmt_frd_offset_rs1 "O\t3,i(1)"
645 #define rv_fmt_rd_csr_rs1 "O\t0,c,1"
646 #define rv_fmt_rd_csr_zimm "O\t0,c,7"
647 #define rv_fmt_rs2_offset_rs1 "O\t2,i(1)"
648 #define rv_fmt_frs2_offset_rs1 "O\t5,i(1)"
649 #define rv_fmt_rs1_rs2_offset "O\t1,2,o"
650 #define rv_fmt_rs2_rs1_offset "O\t2,1,o"
651 #define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)"
652 #define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)"
653 #define rv_fmt_rd "O\t0"
654 #define rv_fmt_rd_zimm "O\t0,7"
655 #define rv_fmt_rd_rs1 "O\t0,1"
656 #define rv_fmt_rd_rs2 "O\t0,2"
657 #define rv_fmt_rs1_offset "O\t1,o"
658 #define rv_fmt_rs2_offset "O\t2,o"
659 #define rv_fmt_rs1_rs2_bs "O\t1,2,b"
660 #define rv_fmt_rd_rs1_rnum "O\t0,1,n"
662 /* pseudo-instruction constraints */
664 static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
665 static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, rvc_end };
666 static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, rvc_imm_eq_zero, rvc_end };
667 static const rvc_constraint rvcc_mv[] = { rvc_imm_eq_zero, rvc_end };
668 static const rvc_constraint rvcc_not[] = { rvc_imm_eq_n1, rvc_end };
669 static const rvc_constraint rvcc_neg[] = { rvc_rs1_eq_x0, rvc_end };
670 static const rvc_constraint rvcc_negw[] = { rvc_rs1_eq_x0, rvc_end };
671 static const rvc_constraint rvcc_sext_w[] = { rvc_imm_eq_zero, rvc_end };
672 static const rvc_constraint rvcc_seqz[] = { rvc_imm_eq_p1, rvc_end };
673 static const rvc_constraint rvcc_snez[] = { rvc_rs1_eq_x0, rvc_end };
674 static const rvc_constraint rvcc_sltz[] = { rvc_rs2_eq_x0, rvc_end };
675 static const rvc_constraint rvcc_sgtz[] = { rvc_rs1_eq_x0, rvc_end };
676 static const rvc_constraint rvcc_fmv_s[] = { rvc_rs2_eq_rs1, rvc_end };
677 static const rvc_constraint rvcc_fabs_s[] = { rvc_rs2_eq_rs1, rvc_end };
678 static const rvc_constraint rvcc_fneg_s[] = { rvc_rs2_eq_rs1, rvc_end };
679 static const rvc_constraint rvcc_fmv_d[] = { rvc_rs2_eq_rs1, rvc_end };
680 static const rvc_constraint rvcc_fabs_d[] = { rvc_rs2_eq_rs1, rvc_end };
681 static const rvc_constraint rvcc_fneg_d[] = { rvc_rs2_eq_rs1, rvc_end };
682 static const rvc_constraint rvcc_fmv_q[] = { rvc_rs2_eq_rs1, rvc_end };
683 static const rvc_constraint rvcc_fabs_q[] = { rvc_rs2_eq_rs1, rvc_end };
684 static const rvc_constraint rvcc_fneg_q[] = { rvc_rs2_eq_rs1, rvc_end };
685 static const rvc_constraint rvcc_beqz[] = { rvc_rs2_eq_x0, rvc_end };
686 static const rvc_constraint rvcc_bnez[] = { rvc_rs2_eq_x0, rvc_end };
687 static const rvc_constraint rvcc_blez[] = { rvc_rs1_eq_x0, rvc_end };
688 static const rvc_constraint rvcc_bgez[] = { rvc_rs2_eq_x0, rvc_end };
689 static const rvc_constraint rvcc_bltz[] = { rvc_rs2_eq_x0, rvc_end };
690 static const rvc_constraint rvcc_bgtz[] = { rvc_rs1_eq_x0, rvc_end };
691 static const rvc_constraint rvcc_ble[] = { rvc_end };
692 static const rvc_constraint rvcc_bleu[] = { rvc_end };
693 static const rvc_constraint rvcc_bgt[] = { rvc_end };
694 static const rvc_constraint rvcc_bgtu[] = { rvc_end };
695 static const rvc_constraint rvcc_j[] = { rvc_rd_eq_x0, rvc_end };
696 static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, rvc_end };
697 static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, rvc_end };
698 static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00, rvc_end };
699 static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, rvc_end };
700 static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
701 static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
702 static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
703 static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0,
704 rvc_csr_eq_0xc82, rvc_end };
705 static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
706 static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
707 static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
708 static const rvc_constraint rvcc_fscsr[] = { rvc_csr_eq_0x003, rvc_end };
709 static const rvc_constraint rvcc_fsrm[] = { rvc_csr_eq_0x002, rvc_end };
710 static const rvc_constraint rvcc_fsflags[] = { rvc_csr_eq_0x001, rvc_end };
711 static const rvc_constraint rvcc_fsrmi[] = { rvc_csr_eq_0x002, rvc_end };
712 static const rvc_constraint rvcc_fsflagsi[] = { rvc_csr_eq_0x001, rvc_end };
714 /* pseudo-instruction metadata */
716 static const rv_comp_data rvcp_jal[] = {
718 { rv_op_jal, rvcc_jal },
719 { rv_op_illegal, NULL }
722 static const rv_comp_data rvcp_jalr[] = {
723 { rv_op_ret, rvcc_ret },
724 { rv_op_jr, rvcc_jr },
725 { rv_op_jalr, rvcc_jalr },
726 { rv_op_illegal, NULL }
729 static const rv_comp_data rvcp_beq[] = {
730 { rv_op_beqz, rvcc_beqz },
731 { rv_op_illegal, NULL }
734 static const rv_comp_data rvcp_bne[] = {
735 { rv_op_bnez, rvcc_bnez },
736 { rv_op_illegal, NULL }
739 static const rv_comp_data rvcp_blt[] = {
740 { rv_op_bltz, rvcc_bltz },
741 { rv_op_bgtz, rvcc_bgtz },
742 { rv_op_bgt, rvcc_bgt },
743 { rv_op_illegal, NULL }
746 static const rv_comp_data rvcp_bge[] = {
747 { rv_op_blez, rvcc_blez },
748 { rv_op_bgez, rvcc_bgez },
749 { rv_op_ble, rvcc_ble },
750 { rv_op_illegal, NULL }
753 static const rv_comp_data rvcp_bltu[] = {
754 { rv_op_bgtu, rvcc_bgtu },
755 { rv_op_illegal, NULL }
758 static const rv_comp_data rvcp_bgeu[] = {
759 { rv_op_bleu, rvcc_bleu },
760 { rv_op_illegal, NULL }
763 static const rv_comp_data rvcp_addi[] = {
764 { rv_op_nop, rvcc_nop },
765 { rv_op_mv, rvcc_mv },
766 { rv_op_illegal, NULL }
769 static const rv_comp_data rvcp_sltiu[] = {
770 { rv_op_seqz, rvcc_seqz },
771 { rv_op_illegal, NULL }
774 static const rv_comp_data rvcp_xori[] = {
775 { rv_op_not, rvcc_not },
776 { rv_op_illegal, NULL }
779 static const rv_comp_data rvcp_sub[] = {
780 { rv_op_neg, rvcc_neg },
781 { rv_op_illegal, NULL }
784 static const rv_comp_data rvcp_slt[] = {
785 { rv_op_sltz, rvcc_sltz },
786 { rv_op_sgtz, rvcc_sgtz },
787 { rv_op_illegal, NULL }
790 static const rv_comp_data rvcp_sltu[] = {
791 { rv_op_snez, rvcc_snez },
792 { rv_op_illegal, NULL }
795 static const rv_comp_data rvcp_addiw[] = {
796 { rv_op_sext_w, rvcc_sext_w },
797 { rv_op_illegal, NULL }
800 static const rv_comp_data rvcp_subw[] = {
801 { rv_op_negw, rvcc_negw },
802 { rv_op_illegal, NULL }
805 static const rv_comp_data rvcp_csrrw[] = {
806 { rv_op_fscsr, rvcc_fscsr },
807 { rv_op_fsrm, rvcc_fsrm },
808 { rv_op_fsflags, rvcc_fsflags },
809 { rv_op_illegal, NULL }
813 static const rv_comp_data rvcp_csrrs[] = {
814 { rv_op_rdcycle, rvcc_rdcycle },
815 { rv_op_rdtime, rvcc_rdtime },
816 { rv_op_rdinstret, rvcc_rdinstret },
817 { rv_op_rdcycleh, rvcc_rdcycleh },
818 { rv_op_rdtimeh, rvcc_rdtimeh },
819 { rv_op_rdinstreth, rvcc_rdinstreth },
820 { rv_op_frcsr, rvcc_frcsr },
821 { rv_op_frrm, rvcc_frrm },
822 { rv_op_frflags, rvcc_frflags },
823 { rv_op_illegal, NULL }
826 static const rv_comp_data rvcp_csrrwi[] = {
827 { rv_op_fsrmi, rvcc_fsrmi },
828 { rv_op_fsflagsi, rvcc_fsflagsi },
829 { rv_op_illegal, NULL }
832 static const rv_comp_data rvcp_fsgnj_s[] = {
833 { rv_op_fmv_s, rvcc_fmv_s },
834 { rv_op_illegal, NULL }
837 static const rv_comp_data rvcp_fsgnjn_s[] = {
838 { rv_op_fneg_s, rvcc_fneg_s },
839 { rv_op_illegal, NULL }
842 static const rv_comp_data rvcp_fsgnjx_s[] = {
843 { rv_op_fabs_s, rvcc_fabs_s },
844 { rv_op_illegal, NULL }
847 static const rv_comp_data rvcp_fsgnj_d[] = {
848 { rv_op_fmv_d, rvcc_fmv_d },
849 { rv_op_illegal, NULL }
852 static const rv_comp_data rvcp_fsgnjn_d[] = {
853 { rv_op_fneg_d, rvcc_fneg_d },
854 { rv_op_illegal, NULL }
857 static const rv_comp_data rvcp_fsgnjx_d[] = {
858 { rv_op_fabs_d, rvcc_fabs_d },
859 { rv_op_illegal, NULL }
862 static const rv_comp_data rvcp_fsgnj_q[] = {
863 { rv_op_fmv_q, rvcc_fmv_q },
864 { rv_op_illegal, NULL }
867 static const rv_comp_data rvcp_fsgnjn_q[] = {
868 { rv_op_fneg_q, rvcc_fneg_q },
869 { rv_op_illegal, NULL }
872 static const rv_comp_data rvcp_fsgnjx_q[] = {
873 { rv_op_fabs_q, rvcc_fabs_q },
874 { rv_op_illegal, NULL }
877 /* instruction metadata */
879 const rv_opcode_data opcode_data[] = {
880 { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
881 { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
882 { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
883 { "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
884 { "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
885 { "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
886 { "bne", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bne, 0, 0, 0 },
887 { "blt", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_blt, 0, 0, 0 },
888 { "bge", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bge, 0, 0, 0 },
889 { "bltu", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bltu, 0, 0, 0 },
890 { "bgeu", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bgeu, 0, 0, 0 },
891 { "lb", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
892 { "lh", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
893 { "lw", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
894 { "lbu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
895 { "lhu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
896 { "sb", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
897 { "sh", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
898 { "sw", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
899 { "addi", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_addi, 0, 0, 0 },
900 { "slti", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
901 { "sltiu", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_sltiu, 0, 0, 0 },
902 { "xori", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_xori, 0, 0, 0 },
903 { "ori", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
904 { "andi", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
905 { "slli", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
906 { "srli", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
907 { "srai", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
908 { "add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
909 { "sub", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_sub, 0, 0, 0 },
910 { "sll", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
911 { "slt", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_slt, 0, 0, 0 },
912 { "sltu", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_sltu, 0, 0, 0 },
913 { "xor", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
914 { "srl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
915 { "sra", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
916 { "or", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
917 { "and", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
918 { "fence", rv_codec_r_f, rv_fmt_pred_succ, NULL, 0, 0, 0 },
919 { "fence.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
920 { "lwu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
921 { "ld", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
922 { "sd", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
923 { "addiw", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_addiw, 0, 0, 0 },
924 { "slliw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
925 { "srliw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
926 { "sraiw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
927 { "addw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
928 { "subw", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_subw, 0, 0, 0 },
929 { "sllw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
930 { "srlw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
931 { "sraw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
932 { "ldu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
933 { "lq", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
934 { "sq", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
935 { "addid", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
936 { "sllid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
937 { "srlid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
938 { "sraid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
939 { "addd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
940 { "subd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
941 { "slld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
942 { "srld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
943 { "srad", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
944 { "mul", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
945 { "mulh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
946 { "mulhsu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
947 { "mulhu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
948 { "div", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
949 { "divu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
950 { "rem", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
951 { "remu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
952 { "mulw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
953 { "divw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
954 { "divuw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
955 { "remw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
956 { "remuw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
957 { "muld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
958 { "divd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
959 { "divud", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
960 { "remd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
961 { "remud", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
962 { "lr.w", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
963 { "sc.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
964 { "amoswap.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
965 { "amoadd.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
966 { "amoxor.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
967 { "amoor.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
968 { "amoand.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
969 { "amomin.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
970 { "amomax.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
971 { "amominu.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
972 { "amomaxu.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
973 { "lr.d", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
974 { "sc.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
975 { "amoswap.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
976 { "amoadd.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
977 { "amoxor.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
978 { "amoor.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
979 { "amoand.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
980 { "amomin.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
981 { "amomax.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
982 { "amominu.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
983 { "amomaxu.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
984 { "lr.q", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
985 { "sc.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
986 { "amoswap.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
987 { "amoadd.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
988 { "amoxor.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
989 { "amoor.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
990 { "amoand.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
991 { "amomin.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
992 { "amomax.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
993 { "amominu.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
994 { "amomaxu.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
995 { "ecall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
996 { "ebreak", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
997 { "uret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
998 { "sret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
999 { "hret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1000 { "mret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1001 { "dret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1002 { "sfence.vm", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
1003 { "sfence.vma", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 },
1004 { "wfi", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1005 { "csrrw", rv_codec_i_csr, rv_fmt_rd_csr_rs1, rvcp_csrrw, 0, 0, 0 },
1006 { "csrrs", rv_codec_i_csr, rv_fmt_rd_csr_rs1, rvcp_csrrs, 0, 0, 0 },
1007 { "csrrc", rv_codec_i_csr, rv_fmt_rd_csr_rs1, NULL, 0, 0, 0 },
1008 { "csrrwi", rv_codec_i_csr, rv_fmt_rd_csr_zimm, rvcp_csrrwi, 0, 0, 0 },
1009 { "csrrsi", rv_codec_i_csr, rv_fmt_rd_csr_zimm, NULL, 0, 0, 0 },
1010 { "csrrci", rv_codec_i_csr, rv_fmt_rd_csr_zimm, NULL, 0, 0, 0 },
1011 { "flw", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
1012 { "fsw", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
1013 { "fmadd.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1014 { "fmsub.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1015 { "fnmsub.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1016 { "fnmadd.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1017 { "fadd.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1018 { "fsub.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1019 { "fmul.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1020 { "fdiv.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1021 { "fsgnj.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_s, 0, 0, 0 },
1022 { "fsgnjn.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_s, 0, 0, 0 },
1023 { "fsgnjx.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_s, 0, 0, 0 },
1024 { "fmin.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1025 { "fmax.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1026 { "fsqrt.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1027 { "fle.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1028 { "flt.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1029 { "feq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1030 { "fcvt.w.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1031 { "fcvt.wu.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1032 { "fcvt.s.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1033 { "fcvt.s.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1034 { "fmv.x.s", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1035 { "fclass.s", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1036 { "fmv.s.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1037 { "fcvt.l.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1038 { "fcvt.lu.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1039 { "fcvt.s.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1040 { "fcvt.s.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1041 { "fld", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
1042 { "fsd", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
1043 { "fmadd.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1044 { "fmsub.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1045 { "fnmsub.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1046 { "fnmadd.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1047 { "fadd.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1048 { "fsub.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1049 { "fmul.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1050 { "fdiv.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1051 { "fsgnj.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_d, 0, 0, 0 },
1052 { "fsgnjn.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_d, 0, 0, 0 },
1053 { "fsgnjx.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_d, 0, 0, 0 },
1054 { "fmin.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1055 { "fmax.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1056 { "fcvt.s.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1057 { "fcvt.d.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1058 { "fsqrt.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1059 { "fle.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1060 { "flt.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1061 { "feq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1062 { "fcvt.w.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1063 { "fcvt.wu.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1064 { "fcvt.d.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1065 { "fcvt.d.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1066 { "fclass.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1067 { "fcvt.l.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1068 { "fcvt.lu.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1069 { "fmv.x.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1070 { "fcvt.d.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1071 { "fcvt.d.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1072 { "fmv.d.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1073 { "flq", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
1074 { "fsq", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
1075 { "fmadd.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1076 { "fmsub.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1077 { "fnmsub.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1078 { "fnmadd.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1079 { "fadd.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1080 { "fsub.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1081 { "fmul.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1082 { "fdiv.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1083 { "fsgnj.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_q, 0, 0, 0 },
1084 { "fsgnjn.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_q, 0, 0, 0 },
1085 { "fsgnjx.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_q, 0, 0, 0 },
1086 { "fmin.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1087 { "fmax.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1088 { "fcvt.s.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1089 { "fcvt.q.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1090 { "fcvt.d.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1091 { "fcvt.q.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1092 { "fsqrt.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1093 { "fle.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1094 { "flt.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1095 { "feq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1096 { "fcvt.w.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1097 { "fcvt.wu.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1098 { "fcvt.q.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1099 { "fcvt.q.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1100 { "fclass.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1101 { "fcvt.l.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1102 { "fcvt.lu.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1103 { "fcvt.q.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1104 { "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1105 { "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1106 { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1107 { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
1108 rv_op_addi, rv_op_addi, rvcd_imm_nz },
1109 { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
1110 { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
1111 { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
1112 { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
1113 { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
1114 { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
1115 { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1116 { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi,
1117 rv_op_addi, rvcd_imm_nz },
1118 { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
1119 { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1120 { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
1121 rv_op_addi, rv_op_addi, rvcd_imm_nz },
1122 { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
1123 rv_op_lui, rvcd_imm_nz },
1124 { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
1125 rv_op_srli, rv_op_srli, rvcd_imm_nz },
1126 { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai,
1127 rv_op_srai, rv_op_srai, rvcd_imm_nz },
1128 { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi,
1129 rv_op_andi, rv_op_andi },
1130 { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
1131 { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
1132 { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
1133 { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and, rv_op_and },
1134 { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw, rv_op_subw },
1135 { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw, rv_op_addw },
1136 { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
1137 { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
1138 { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
1139 { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli,
1140 rv_op_slli, rv_op_slli, rvcd_imm_nz },
1141 { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
1142 { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
1143 { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
1144 { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
1145 { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1146 { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak, rv_op_ebreak, rv_op_ebreak },
1147 { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
1148 { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add, rv_op_add },
1149 { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, rv_op_fsd },
1150 { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
1151 { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
1152 { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
1153 { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
1154 { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw, rv_op_addiw },
1155 { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
1156 { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
1157 { "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
1158 { "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
1159 { "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
1160 { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
1161 { "nop", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
1162 { "mv", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1163 { "not", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1164 { "neg", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1165 { "negw", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1166 { "sext.w", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1167 { "seqz", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1168 { "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1169 { "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1170 { "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1171 { "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1172 { "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1173 { "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1174 { "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1175 { "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1176 { "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1177 { "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1178 { "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1179 { "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1180 { "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1181 { "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1182 { "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
1183 { "bgez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1184 { "bltz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1185 { "bgtz", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
1186 { "ble", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1187 { "bleu", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1188 { "bgt", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1189 { "bgtu", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1190 { "j", rv_codec_uj, rv_fmt_offset, NULL, 0, 0, 0 },
1191 { "ret", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
1192 { "jr", rv_codec_i, rv_fmt_rs1, NULL, 0, 0, 0 },
1193 { "rdcycle", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1194 { "rdtime", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1195 { "rdinstret", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1196 { "rdcycleh", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1197 { "rdtimeh", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1198 { "rdinstreth", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1199 { "frcsr", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1200 { "frrm", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1201 { "frflags", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1202 { "fscsr", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1203 { "fsrm", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1204 { "fsflags", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1205 { "fsrmi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 },
1206 { "fsflagsi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 },
1207 { "bseti", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1208 { "bclri", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1209 { "binvi", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1210 { "bexti", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1211 { "rori", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1212 { "clz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1213 { "ctz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1214 { "cpop", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1215 { "sext.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1216 { "sext.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1217 { "xnor", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1218 { "orn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1219 { "andn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1220 { "rol", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1221 { "ror", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1222 { "sh1add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1223 { "sh2add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1224 { "sh3add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1225 { "sh1add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1226 { "sh2add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1227 { "sh3add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1228 { "clmul", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1229 { "clmulr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1230 { "clmulh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1231 { "min", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1232 { "minu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1233 { "max", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1234 { "maxu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1235 { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1236 { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1237 { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1238 { "slli.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1239 { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1240 { "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1241 { "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1242 { "rev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1243 { "zext.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1244 { "roriw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1245 { "orc.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1246 { "bset", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1247 { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1248 { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1249 { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1250 { "aes32esmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1251 { "aes32esi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1252 { "aes32dsmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1253 { "aes32dsi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1254 { "aes64ks1i", rv_codec_k_rnum, rv_fmt_rd_rs1_rnum, NULL, 0, 0, 0 },
1255 { "aes64ks2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1256 { "aes64im", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1257 { "aes64esm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1258 { "aes64es", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1259 { "aes64dsm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1260 { "aes64ds", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1261 { "sha256sig0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1262 { "sha256sig1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1263 { "sha256sum0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1264 { "sha256sum1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1265 { "sha512sig0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1266 { "sha512sig1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1267 { "sha512sum0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1268 { "sha512sum1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1269 { "sha512sum0r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1270 { "sha512sum1r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1271 { "sha512sig0l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1272 { "sha512sig0h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1273 { "sha512sig1l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1274 { "sha512sig1h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1275 { "sm3p0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1276 { "sm3p1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1277 { "sm4ed", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1278 { "sm4ks", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1279 { "brev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1280 { "pack", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1281 { "packh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1282 { "packw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1283 { "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1284 { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1285 { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1286 { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }
1291 static const char *csr_name(int csrno)
1294 case 0x0000: return "ustatus";
1295 case 0x0001: return "fflags";
1296 case 0x0002: return "frm";
1297 case 0x0003: return "fcsr";
1298 case 0x0004: return "uie";
1299 case 0x0005: return "utvec";
1300 case 0x0015: return "seed";
1301 case 0x0040: return "uscratch";
1302 case 0x0041: return "uepc";
1303 case 0x0042: return "ucause";
1304 case 0x0043: return "utval";
1305 case 0x0044: return "uip";
1306 case 0x0100: return "sstatus";
1307 case 0x0102: return "sedeleg";
1308 case 0x0103: return "sideleg";
1309 case 0x0104: return "sie";
1310 case 0x0105: return "stvec";
1311 case 0x0106: return "scounteren";
1312 case 0x0140: return "sscratch";
1313 case 0x0141: return "sepc";
1314 case 0x0142: return "scause";
1315 case 0x0143: return "stval";
1316 case 0x0144: return "sip";
1317 case 0x0180: return "satp";
1318 case 0x0200: return "hstatus";
1319 case 0x0202: return "hedeleg";
1320 case 0x0203: return "hideleg";
1321 case 0x0204: return "hie";
1322 case 0x0205: return "htvec";
1323 case 0x0240: return "hscratch";
1324 case 0x0241: return "hepc";
1325 case 0x0242: return "hcause";
1326 case 0x0243: return "hbadaddr";
1327 case 0x0244: return "hip";
1328 case 0x0300: return "mstatus";
1329 case 0x0301: return "misa";
1330 case 0x0302: return "medeleg";
1331 case 0x0303: return "mideleg";
1332 case 0x0304: return "mie";
1333 case 0x0305: return "mtvec";
1334 case 0x0306: return "mcounteren";
1335 case 0x0320: return "mucounteren";
1336 case 0x0321: return "mscounteren";
1337 case 0x0322: return "mhcounteren";
1338 case 0x0323: return "mhpmevent3";
1339 case 0x0324: return "mhpmevent4";
1340 case 0x0325: return "mhpmevent5";
1341 case 0x0326: return "mhpmevent6";
1342 case 0x0327: return "mhpmevent7";
1343 case 0x0328: return "mhpmevent8";
1344 case 0x0329: return "mhpmevent9";
1345 case 0x032a: return "mhpmevent10";
1346 case 0x032b: return "mhpmevent11";
1347 case 0x032c: return "mhpmevent12";
1348 case 0x032d: return "mhpmevent13";
1349 case 0x032e: return "mhpmevent14";
1350 case 0x032f: return "mhpmevent15";
1351 case 0x0330: return "mhpmevent16";
1352 case 0x0331: return "mhpmevent17";
1353 case 0x0332: return "mhpmevent18";
1354 case 0x0333: return "mhpmevent19";
1355 case 0x0334: return "mhpmevent20";
1356 case 0x0335: return "mhpmevent21";
1357 case 0x0336: return "mhpmevent22";
1358 case 0x0337: return "mhpmevent23";
1359 case 0x0338: return "mhpmevent24";
1360 case 0x0339: return "mhpmevent25";
1361 case 0x033a: return "mhpmevent26";
1362 case 0x033b: return "mhpmevent27";
1363 case 0x033c: return "mhpmevent28";
1364 case 0x033d: return "mhpmevent29";
1365 case 0x033e: return "mhpmevent30";
1366 case 0x033f: return "mhpmevent31";
1367 case 0x0340: return "mscratch";
1368 case 0x0341: return "mepc";
1369 case 0x0342: return "mcause";
1370 case 0x0343: return "mtval";
1371 case 0x0344: return "mip";
1372 case 0x0380: return "mbase";
1373 case 0x0381: return "mbound";
1374 case 0x0382: return "mibase";
1375 case 0x0383: return "mibound";
1376 case 0x0384: return "mdbase";
1377 case 0x0385: return "mdbound";
1378 case 0x03a0: return "pmpcfg3";
1379 case 0x03b0: return "pmpaddr0";
1380 case 0x03b1: return "pmpaddr1";
1381 case 0x03b2: return "pmpaddr2";
1382 case 0x03b3: return "pmpaddr3";
1383 case 0x03b4: return "pmpaddr4";
1384 case 0x03b5: return "pmpaddr5";
1385 case 0x03b6: return "pmpaddr6";
1386 case 0x03b7: return "pmpaddr7";
1387 case 0x03b8: return "pmpaddr8";
1388 case 0x03b9: return "pmpaddr9";
1389 case 0x03ba: return "pmpaddr10";
1390 case 0x03bb: return "pmpaddr11";
1391 case 0x03bc: return "pmpaddr12";
1392 case 0x03bd: return "pmpaddr14";
1393 case 0x03be: return "pmpaddr13";
1394 case 0x03bf: return "pmpaddr15";
1395 case 0x0780: return "mtohost";
1396 case 0x0781: return "mfromhost";
1397 case 0x0782: return "mreset";
1398 case 0x0783: return "mipi";
1399 case 0x0784: return "miobase";
1400 case 0x07a0: return "tselect";
1401 case 0x07a1: return "tdata1";
1402 case 0x07a2: return "tdata2";
1403 case 0x07a3: return "tdata3";
1404 case 0x07b0: return "dcsr";
1405 case 0x07b1: return "dpc";
1406 case 0x07b2: return "dscratch";
1407 case 0x0b00: return "mcycle";
1408 case 0x0b01: return "mtime";
1409 case 0x0b02: return "minstret";
1410 case 0x0b03: return "mhpmcounter3";
1411 case 0x0b04: return "mhpmcounter4";
1412 case 0x0b05: return "mhpmcounter5";
1413 case 0x0b06: return "mhpmcounter6";
1414 case 0x0b07: return "mhpmcounter7";
1415 case 0x0b08: return "mhpmcounter8";
1416 case 0x0b09: return "mhpmcounter9";
1417 case 0x0b0a: return "mhpmcounter10";
1418 case 0x0b0b: return "mhpmcounter11";
1419 case 0x0b0c: return "mhpmcounter12";
1420 case 0x0b0d: return "mhpmcounter13";
1421 case 0x0b0e: return "mhpmcounter14";
1422 case 0x0b0f: return "mhpmcounter15";
1423 case 0x0b10: return "mhpmcounter16";
1424 case 0x0b11: return "mhpmcounter17";
1425 case 0x0b12: return "mhpmcounter18";
1426 case 0x0b13: return "mhpmcounter19";
1427 case 0x0b14: return "mhpmcounter20";
1428 case 0x0b15: return "mhpmcounter21";
1429 case 0x0b16: return "mhpmcounter22";
1430 case 0x0b17: return "mhpmcounter23";
1431 case 0x0b18: return "mhpmcounter24";
1432 case 0x0b19: return "mhpmcounter25";
1433 case 0x0b1a: return "mhpmcounter26";
1434 case 0x0b1b: return "mhpmcounter27";
1435 case 0x0b1c: return "mhpmcounter28";
1436 case 0x0b1d: return "mhpmcounter29";
1437 case 0x0b1e: return "mhpmcounter30";
1438 case 0x0b1f: return "mhpmcounter31";
1439 case 0x0b80: return "mcycleh";
1440 case 0x0b81: return "mtimeh";
1441 case 0x0b82: return "minstreth";
1442 case 0x0b83: return "mhpmcounter3h";
1443 case 0x0b84: return "mhpmcounter4h";
1444 case 0x0b85: return "mhpmcounter5h";
1445 case 0x0b86: return "mhpmcounter6h";
1446 case 0x0b87: return "mhpmcounter7h";
1447 case 0x0b88: return "mhpmcounter8h";
1448 case 0x0b89: return "mhpmcounter9h";
1449 case 0x0b8a: return "mhpmcounter10h";
1450 case 0x0b8b: return "mhpmcounter11h";
1451 case 0x0b8c: return "mhpmcounter12h";
1452 case 0x0b8d: return "mhpmcounter13h";
1453 case 0x0b8e: return "mhpmcounter14h";
1454 case 0x0b8f: return "mhpmcounter15h";
1455 case 0x0b90: return "mhpmcounter16h";
1456 case 0x0b91: return "mhpmcounter17h";
1457 case 0x0b92: return "mhpmcounter18h";
1458 case 0x0b93: return "mhpmcounter19h";
1459 case 0x0b94: return "mhpmcounter20h";
1460 case 0x0b95: return "mhpmcounter21h";
1461 case 0x0b96: return "mhpmcounter22h";
1462 case 0x0b97: return "mhpmcounter23h";
1463 case 0x0b98: return "mhpmcounter24h";
1464 case 0x0b99: return "mhpmcounter25h";
1465 case 0x0b9a: return "mhpmcounter26h";
1466 case 0x0b9b: return "mhpmcounter27h";
1467 case 0x0b9c: return "mhpmcounter28h";
1468 case 0x0b9d: return "mhpmcounter29h";
1469 case 0x0b9e: return "mhpmcounter30h";
1470 case 0x0b9f: return "mhpmcounter31h";
1471 case 0x0c00: return "cycle";
1472 case 0x0c01: return "time";
1473 case 0x0c02: return "instret";
1474 case 0x0c80: return "cycleh";
1475 case 0x0c81: return "timeh";
1476 case 0x0c82: return "instreth";
1477 case 0x0d00: return "scycle";
1478 case 0x0d01: return "stime";
1479 case 0x0d02: return "sinstret";
1480 case 0x0d80: return "scycleh";
1481 case 0x0d81: return "stimeh";
1482 case 0x0d82: return "sinstreth";
1483 case 0x0e00: return "hcycle";
1484 case 0x0e01: return "htime";
1485 case 0x0e02: return "hinstret";
1486 case 0x0e80: return "hcycleh";
1487 case 0x0e81: return "htimeh";
1488 case 0x0e82: return "hinstreth";
1489 case 0x0f11: return "mvendorid";
1490 case 0x0f12: return "marchid";
1491 case 0x0f13: return "mimpid";
1492 case 0x0f14: return "mhartid";
1493 default: return NULL;
1499 static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
1501 rv_inst inst = dec->inst;
1502 rv_opcode op = rv_op_illegal;
1503 switch (((inst >> 0) & 0b11)) {
1505 switch (((inst >> 13) & 0b111)) {
1506 case 0: op = rv_op_c_addi4spn; break;
1514 case 2: op = rv_op_c_lw; break;
1529 case 6: op = rv_op_c_sw; break;
1540 switch (((inst >> 13) & 0b111)) {
1542 switch (((inst >> 2) & 0b11111111111)) {
1543 case 0: op = rv_op_c_nop; break;
1544 default: op = rv_op_c_addi; break;
1554 case 2: op = rv_op_c_li; break;
1556 switch (((inst >> 7) & 0b11111)) {
1557 case 2: op = rv_op_c_addi16sp; break;
1558 default: op = rv_op_c_lui; break;
1562 switch (((inst >> 10) & 0b11)) {
1569 case 2: op = rv_op_c_andi; break;
1571 switch (((inst >> 10) & 0b100) | ((inst >> 5) & 0b011)) {
1572 case 0: op = rv_op_c_sub; break;
1573 case 1: op = rv_op_c_xor; break;
1574 case 2: op = rv_op_c_or; break;
1575 case 3: op = rv_op_c_and; break;
1576 case 4: op = rv_op_c_subw; break;
1577 case 5: op = rv_op_c_addw; break;
1582 case 5: op = rv_op_c_j; break;
1583 case 6: op = rv_op_c_beqz; break;
1584 case 7: op = rv_op_c_bnez; break;
1588 switch (((inst >> 13) & 0b111)) {
1599 case 2: op = rv_op_c_lwsp; break;
1608 switch (((inst >> 12) & 0b1)) {
1610 switch (((inst >> 2) & 0b11111)) {
1611 case 0: op = rv_op_c_jr; break;
1612 default: op = rv_op_c_mv; break;
1616 switch (((inst >> 2) & 0b11111)) {
1618 switch (((inst >> 7) & 0b11111)) {
1619 case 0: op = rv_op_c_ebreak; break;
1620 default: op = rv_op_c_jalr; break;
1623 default: op = rv_op_c_add; break;
1635 case 6: op = rv_op_c_swsp; break;
1646 switch (((inst >> 2) & 0b11111)) {
1648 switch (((inst >> 12) & 0b111)) {
1649 case 0: op = rv_op_lb; break;
1650 case 1: op = rv_op_lh; break;
1651 case 2: op = rv_op_lw; break;
1652 case 3: op = rv_op_ld; break;
1653 case 4: op = rv_op_lbu; break;
1654 case 5: op = rv_op_lhu; break;
1655 case 6: op = rv_op_lwu; break;
1656 case 7: op = rv_op_ldu; break;
1660 switch (((inst >> 12) & 0b111)) {
1661 case 2: op = rv_op_flw; break;
1662 case 3: op = rv_op_fld; break;
1663 case 4: op = rv_op_flq; break;
1667 switch (((inst >> 12) & 0b111)) {
1668 case 0: op = rv_op_fence; break;
1669 case 1: op = rv_op_fence_i; break;
1670 case 2: op = rv_op_lq; break;
1674 switch (((inst >> 12) & 0b111)) {
1675 case 0: op = rv_op_addi; break;
1677 switch (((inst >> 27) & 0b11111)) {
1678 case 0b00000: op = rv_op_slli; break;
1680 switch (((inst >> 20) & 0b1111111)) {
1681 case 0b0001111: op = rv_op_zip; break;
1685 switch (((inst >> 20) & 0b1111111)) {
1686 case 0b0000000: op = rv_op_sha256sum0; break;
1687 case 0b0000001: op = rv_op_sha256sum1; break;
1688 case 0b0000010: op = rv_op_sha256sig0; break;
1689 case 0b0000011: op = rv_op_sha256sig1; break;
1690 case 0b0000100: op = rv_op_sha512sum0; break;
1691 case 0b0000101: op = rv_op_sha512sum1; break;
1692 case 0b0000110: op = rv_op_sha512sig0; break;
1693 case 0b0000111: op = rv_op_sha512sig1; break;
1694 case 0b0001000: op = rv_op_sm3p0; break;
1695 case 0b0001001: op = rv_op_sm3p1; break;
1698 case 0b00101: op = rv_op_bseti; break;
1700 switch (((inst >> 20) & 0b1111111)) {
1701 case 0b0000000: op = rv_op_aes64im; break;
1703 if (((inst >> 24) & 0b0111) == 0b001) {
1704 op = rv_op_aes64ks1i;
1709 case 0b01001: op = rv_op_bclri; break;
1710 case 0b01101: op = rv_op_binvi; break;
1712 switch (((inst >> 20) & 0b1111111)) {
1713 case 0b0000000: op = rv_op_clz; break;
1714 case 0b0000001: op = rv_op_ctz; break;
1715 case 0b0000010: op = rv_op_cpop; break;
1717 case 0b0000100: op = rv_op_sext_b; break;
1718 case 0b0000101: op = rv_op_sext_h; break;
1723 case 2: op = rv_op_slti; break;
1724 case 3: op = rv_op_sltiu; break;
1725 case 4: op = rv_op_xori; break;
1727 switch (((inst >> 27) & 0b11111)) {
1728 case 0b00000: op = rv_op_srli; break;
1730 switch (((inst >> 20) & 0b1111111)) {
1731 case 0b0001111: op = rv_op_unzip; break;
1734 case 0b00101: op = rv_op_orc_b; break;
1735 case 0b01000: op = rv_op_srai; break;
1736 case 0b01001: op = rv_op_bexti; break;
1737 case 0b01100: op = rv_op_rori; break;
1739 switch ((inst >> 20) & 0b1111111) {
1740 case 0b0011000: op = rv_op_rev8; break;
1741 case 0b0111000: op = rv_op_rev8; break;
1742 case 0b0000111: op = rv_op_brev8; break;
1747 case 6: op = rv_op_ori; break;
1748 case 7: op = rv_op_andi; break;
1751 case 5: op = rv_op_auipc; break;
1753 switch (((inst >> 12) & 0b111)) {
1754 case 0: op = rv_op_addiw; break;
1756 switch (((inst >> 25) & 0b1111111)) {
1757 case 0: op = rv_op_slliw; break;
1758 case 4: op = rv_op_slli_uw; break;
1760 switch ((inst >> 20) & 0b11111) {
1761 case 0b00000: op = rv_op_clzw; break;
1762 case 0b00001: op = rv_op_ctzw; break;
1763 case 0b00010: op = rv_op_cpopw; break;
1769 switch (((inst >> 25) & 0b1111111)) {
1770 case 0: op = rv_op_srliw; break;
1771 case 32: op = rv_op_sraiw; break;
1772 case 48: op = rv_op_roriw; break;
1778 switch (((inst >> 12) & 0b111)) {
1779 case 0: op = rv_op_sb; break;
1780 case 1: op = rv_op_sh; break;
1781 case 2: op = rv_op_sw; break;
1782 case 3: op = rv_op_sd; break;
1783 case 4: op = rv_op_sq; break;
1787 switch (((inst >> 12) & 0b111)) {
1788 case 2: op = rv_op_fsw; break;
1789 case 3: op = rv_op_fsd; break;
1790 case 4: op = rv_op_fsq; break;
1794 switch (((inst >> 24) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1795 case 2: op = rv_op_amoadd_w; break;
1796 case 3: op = rv_op_amoadd_d; break;
1797 case 4: op = rv_op_amoadd_q; break;
1798 case 10: op = rv_op_amoswap_w; break;
1799 case 11: op = rv_op_amoswap_d; break;
1800 case 12: op = rv_op_amoswap_q; break;
1802 switch (((inst >> 20) & 0b11111)) {
1803 case 0: op = rv_op_lr_w; break;
1807 switch (((inst >> 20) & 0b11111)) {
1808 case 0: op = rv_op_lr_d; break;
1812 switch (((inst >> 20) & 0b11111)) {
1813 case 0: op = rv_op_lr_q; break;
1816 case 26: op = rv_op_sc_w; break;
1817 case 27: op = rv_op_sc_d; break;
1818 case 28: op = rv_op_sc_q; break;
1819 case 34: op = rv_op_amoxor_w; break;
1820 case 35: op = rv_op_amoxor_d; break;
1821 case 36: op = rv_op_amoxor_q; break;
1822 case 66: op = rv_op_amoor_w; break;
1823 case 67: op = rv_op_amoor_d; break;
1824 case 68: op = rv_op_amoor_q; break;
1825 case 98: op = rv_op_amoand_w; break;
1826 case 99: op = rv_op_amoand_d; break;
1827 case 100: op = rv_op_amoand_q; break;
1828 case 130: op = rv_op_amomin_w; break;
1829 case 131: op = rv_op_amomin_d; break;
1830 case 132: op = rv_op_amomin_q; break;
1831 case 162: op = rv_op_amomax_w; break;
1832 case 163: op = rv_op_amomax_d; break;
1833 case 164: op = rv_op_amomax_q; break;
1834 case 194: op = rv_op_amominu_w; break;
1835 case 195: op = rv_op_amominu_d; break;
1836 case 196: op = rv_op_amominu_q; break;
1837 case 226: op = rv_op_amomaxu_w; break;
1838 case 227: op = rv_op_amomaxu_d; break;
1839 case 228: op = rv_op_amomaxu_q; break;
1843 switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1844 case 0: op = rv_op_add; break;
1845 case 1: op = rv_op_sll; break;
1846 case 2: op = rv_op_slt; break;
1847 case 3: op = rv_op_sltu; break;
1848 case 4: op = rv_op_xor; break;
1849 case 5: op = rv_op_srl; break;
1850 case 6: op = rv_op_or; break;
1851 case 7: op = rv_op_and; break;
1852 case 8: op = rv_op_mul; break;
1853 case 9: op = rv_op_mulh; break;
1854 case 10: op = rv_op_mulhsu; break;
1855 case 11: op = rv_op_mulhu; break;
1856 case 12: op = rv_op_div; break;
1857 case 13: op = rv_op_divu; break;
1858 case 14: op = rv_op_rem; break;
1859 case 15: op = rv_op_remu; break;
1861 switch ((inst >> 20) & 0b11111) {
1862 case 0: op = rv_op_zext_h; break;
1863 default: op = rv_op_pack; break;
1866 case 39: op = rv_op_packh; break;
1868 case 41: op = rv_op_clmul; break;
1869 case 42: op = rv_op_clmulr; break;
1870 case 43: op = rv_op_clmulh; break;
1871 case 44: op = rv_op_min; break;
1872 case 45: op = rv_op_minu; break;
1873 case 46: op = rv_op_max; break;
1874 case 47: op = rv_op_maxu; break;
1875 case 130: op = rv_op_sh1add; break;
1876 case 132: op = rv_op_sh2add; break;
1877 case 134: op = rv_op_sh3add; break;
1878 case 161: op = rv_op_bset; break;
1879 case 162: op = rv_op_xperm4; break;
1880 case 164: op = rv_op_xperm8; break;
1881 case 200: op = rv_op_aes64es; break;
1882 case 216: op = rv_op_aes64esm; break;
1883 case 232: op = rv_op_aes64ds; break;
1884 case 248: op = rv_op_aes64dsm; break;
1885 case 256: op = rv_op_sub; break;
1886 case 260: op = rv_op_xnor; break;
1887 case 261: op = rv_op_sra; break;
1888 case 262: op = rv_op_orn; break;
1889 case 263: op = rv_op_andn; break;
1890 case 289: op = rv_op_bclr; break;
1891 case 293: op = rv_op_bext; break;
1892 case 320: op = rv_op_sha512sum0r; break;
1893 case 328: op = rv_op_sha512sum1r; break;
1894 case 336: op = rv_op_sha512sig0l; break;
1895 case 344: op = rv_op_sha512sig1l; break;
1896 case 368: op = rv_op_sha512sig0h; break;
1897 case 376: op = rv_op_sha512sig1h; break;
1898 case 385: op = rv_op_rol; break;
1899 case 389: op = rv_op_ror; break;
1900 case 417: op = rv_op_binv; break;
1901 case 504: op = rv_op_aes64ks2; break;
1903 switch ((inst >> 25) & 0b0011111) {
1904 case 17: op = rv_op_aes32esi; break;
1905 case 19: op = rv_op_aes32esmi; break;
1906 case 21: op = rv_op_aes32dsi; break;
1907 case 23: op = rv_op_aes32dsmi; break;
1908 case 24: op = rv_op_sm4ed; break;
1909 case 26: op = rv_op_sm4ks; break;
1912 case 13: op = rv_op_lui; break;
1914 switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1915 case 0: op = rv_op_addw; break;
1916 case 1: op = rv_op_sllw; break;
1917 case 5: op = rv_op_srlw; break;
1918 case 8: op = rv_op_mulw; break;
1919 case 12: op = rv_op_divw; break;
1920 case 13: op = rv_op_divuw; break;
1921 case 14: op = rv_op_remw; break;
1922 case 15: op = rv_op_remuw; break;
1923 case 32: op = rv_op_add_uw; break;
1925 switch ((inst >> 20) & 0b11111) {
1926 case 0: op = rv_op_zext_h; break;
1927 default: op = rv_op_packw; break;
1930 case 130: op = rv_op_sh1add_uw; break;
1931 case 132: op = rv_op_sh2add_uw; break;
1932 case 134: op = rv_op_sh3add_uw; break;
1933 case 256: op = rv_op_subw; break;
1934 case 261: op = rv_op_sraw; break;
1935 case 385: op = rv_op_rolw; break;
1936 case 389: op = rv_op_rorw; break;
1940 switch (((inst >> 25) & 0b11)) {
1941 case 0: op = rv_op_fmadd_s; break;
1942 case 1: op = rv_op_fmadd_d; break;
1943 case 3: op = rv_op_fmadd_q; break;
1947 switch (((inst >> 25) & 0b11)) {
1948 case 0: op = rv_op_fmsub_s; break;
1949 case 1: op = rv_op_fmsub_d; break;
1950 case 3: op = rv_op_fmsub_q; break;
1954 switch (((inst >> 25) & 0b11)) {
1955 case 0: op = rv_op_fnmsub_s; break;
1956 case 1: op = rv_op_fnmsub_d; break;
1957 case 3: op = rv_op_fnmsub_q; break;
1961 switch (((inst >> 25) & 0b11)) {
1962 case 0: op = rv_op_fnmadd_s; break;
1963 case 1: op = rv_op_fnmadd_d; break;
1964 case 3: op = rv_op_fnmadd_q; break;
1968 switch (((inst >> 25) & 0b1111111)) {
1969 case 0: op = rv_op_fadd_s; break;
1970 case 1: op = rv_op_fadd_d; break;
1971 case 3: op = rv_op_fadd_q; break;
1972 case 4: op = rv_op_fsub_s; break;
1973 case 5: op = rv_op_fsub_d; break;
1974 case 7: op = rv_op_fsub_q; break;
1975 case 8: op = rv_op_fmul_s; break;
1976 case 9: op = rv_op_fmul_d; break;
1977 case 11: op = rv_op_fmul_q; break;
1978 case 12: op = rv_op_fdiv_s; break;
1979 case 13: op = rv_op_fdiv_d; break;
1980 case 15: op = rv_op_fdiv_q; break;
1982 switch (((inst >> 12) & 0b111)) {
1983 case 0: op = rv_op_fsgnj_s; break;
1984 case 1: op = rv_op_fsgnjn_s; break;
1985 case 2: op = rv_op_fsgnjx_s; break;
1989 switch (((inst >> 12) & 0b111)) {
1990 case 0: op = rv_op_fsgnj_d; break;
1991 case 1: op = rv_op_fsgnjn_d; break;
1992 case 2: op = rv_op_fsgnjx_d; break;
1996 switch (((inst >> 12) & 0b111)) {
1997 case 0: op = rv_op_fsgnj_q; break;
1998 case 1: op = rv_op_fsgnjn_q; break;
1999 case 2: op = rv_op_fsgnjx_q; break;
2003 switch (((inst >> 12) & 0b111)) {
2004 case 0: op = rv_op_fmin_s; break;
2005 case 1: op = rv_op_fmax_s; break;
2009 switch (((inst >> 12) & 0b111)) {
2010 case 0: op = rv_op_fmin_d; break;
2011 case 1: op = rv_op_fmax_d; break;
2015 switch (((inst >> 12) & 0b111)) {
2016 case 0: op = rv_op_fmin_q; break;
2017 case 1: op = rv_op_fmax_q; break;
2021 switch (((inst >> 20) & 0b11111)) {
2022 case 1: op = rv_op_fcvt_s_d; break;
2023 case 3: op = rv_op_fcvt_s_q; break;
2027 switch (((inst >> 20) & 0b11111)) {
2028 case 0: op = rv_op_fcvt_d_s; break;
2029 case 3: op = rv_op_fcvt_d_q; break;
2033 switch (((inst >> 20) & 0b11111)) {
2034 case 0: op = rv_op_fcvt_q_s; break;
2035 case 1: op = rv_op_fcvt_q_d; break;
2039 switch (((inst >> 20) & 0b11111)) {
2040 case 0: op = rv_op_fsqrt_s; break;
2044 switch (((inst >> 20) & 0b11111)) {
2045 case 0: op = rv_op_fsqrt_d; break;
2049 switch (((inst >> 20) & 0b11111)) {
2050 case 0: op = rv_op_fsqrt_q; break;
2054 switch (((inst >> 12) & 0b111)) {
2055 case 0: op = rv_op_fle_s; break;
2056 case 1: op = rv_op_flt_s; break;
2057 case 2: op = rv_op_feq_s; break;
2061 switch (((inst >> 12) & 0b111)) {
2062 case 0: op = rv_op_fle_d; break;
2063 case 1: op = rv_op_flt_d; break;
2064 case 2: op = rv_op_feq_d; break;
2068 switch (((inst >> 12) & 0b111)) {
2069 case 0: op = rv_op_fle_q; break;
2070 case 1: op = rv_op_flt_q; break;
2071 case 2: op = rv_op_feq_q; break;
2075 switch (((inst >> 20) & 0b11111)) {
2076 case 0: op = rv_op_fcvt_w_s; break;
2077 case 1: op = rv_op_fcvt_wu_s; break;
2078 case 2: op = rv_op_fcvt_l_s; break;
2079 case 3: op = rv_op_fcvt_lu_s; break;
2083 switch (((inst >> 20) & 0b11111)) {
2084 case 0: op = rv_op_fcvt_w_d; break;
2085 case 1: op = rv_op_fcvt_wu_d; break;
2086 case 2: op = rv_op_fcvt_l_d; break;
2087 case 3: op = rv_op_fcvt_lu_d; break;
2091 switch (((inst >> 20) & 0b11111)) {
2092 case 0: op = rv_op_fcvt_w_q; break;
2093 case 1: op = rv_op_fcvt_wu_q; break;
2094 case 2: op = rv_op_fcvt_l_q; break;
2095 case 3: op = rv_op_fcvt_lu_q; break;
2099 switch (((inst >> 20) & 0b11111)) {
2100 case 0: op = rv_op_fcvt_s_w; break;
2101 case 1: op = rv_op_fcvt_s_wu; break;
2102 case 2: op = rv_op_fcvt_s_l; break;
2103 case 3: op = rv_op_fcvt_s_lu; break;
2107 switch (((inst >> 20) & 0b11111)) {
2108 case 0: op = rv_op_fcvt_d_w; break;
2109 case 1: op = rv_op_fcvt_d_wu; break;
2110 case 2: op = rv_op_fcvt_d_l; break;
2111 case 3: op = rv_op_fcvt_d_lu; break;
2115 switch (((inst >> 20) & 0b11111)) {
2116 case 0: op = rv_op_fcvt_q_w; break;
2117 case 1: op = rv_op_fcvt_q_wu; break;
2118 case 2: op = rv_op_fcvt_q_l; break;
2119 case 3: op = rv_op_fcvt_q_lu; break;
2123 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2124 case 0: op = rv_op_fmv_x_s; break;
2125 case 1: op = rv_op_fclass_s; break;
2129 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2130 case 0: op = rv_op_fmv_x_d; break;
2131 case 1: op = rv_op_fclass_d; break;
2135 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2136 case 0: op = rv_op_fmv_x_q; break;
2137 case 1: op = rv_op_fclass_q; break;
2141 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2142 case 0: op = rv_op_fmv_s_x; break;
2146 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2147 case 0: op = rv_op_fmv_d_x; break;
2151 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2152 case 0: op = rv_op_fmv_q_x; break;
2158 switch (((inst >> 12) & 0b111)) {
2159 case 0: op = rv_op_addid; break;
2161 switch (((inst >> 26) & 0b111111)) {
2162 case 0: op = rv_op_sllid; break;
2166 switch (((inst >> 26) & 0b111111)) {
2167 case 0: op = rv_op_srlid; break;
2168 case 16: op = rv_op_sraid; break;
2174 switch (((inst >> 12) & 0b111)) {
2175 case 0: op = rv_op_beq; break;
2176 case 1: op = rv_op_bne; break;
2177 case 4: op = rv_op_blt; break;
2178 case 5: op = rv_op_bge; break;
2179 case 6: op = rv_op_bltu; break;
2180 case 7: op = rv_op_bgeu; break;
2184 switch (((inst >> 12) & 0b111)) {
2185 case 0: op = rv_op_jalr; break;
2188 case 27: op = rv_op_jal; break;
2190 switch (((inst >> 12) & 0b111)) {
2192 switch (((inst >> 20) & 0b111111100000) | ((inst >> 7) & 0b000000011111)) {
2194 switch (((inst >> 15) & 0b1111111111)) {
2195 case 0: op = rv_op_ecall; break;
2196 case 32: op = rv_op_ebreak; break;
2197 case 64: op = rv_op_uret; break;
2201 switch (((inst >> 20) & 0b11111)) {
2203 switch (((inst >> 15) & 0b11111)) {
2204 case 0: op = rv_op_sret; break;
2207 case 4: op = rv_op_sfence_vm; break;
2209 switch (((inst >> 15) & 0b11111)) {
2210 case 0: op = rv_op_wfi; break;
2215 case 288: op = rv_op_sfence_vma; break;
2217 switch (((inst >> 15) & 0b1111111111)) {
2218 case 64: op = rv_op_hret; break;
2222 switch (((inst >> 15) & 0b1111111111)) {
2223 case 64: op = rv_op_mret; break;
2227 switch (((inst >> 15) & 0b1111111111)) {
2228 case 576: op = rv_op_dret; break;
2233 case 1: op = rv_op_csrrw; break;
2234 case 2: op = rv_op_csrrs; break;
2235 case 3: op = rv_op_csrrc; break;
2236 case 5: op = rv_op_csrrwi; break;
2237 case 6: op = rv_op_csrrsi; break;
2238 case 7: op = rv_op_csrrci; break;
2242 switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
2243 case 0: op = rv_op_addd; break;
2244 case 1: op = rv_op_slld; break;
2245 case 5: op = rv_op_srld; break;
2246 case 8: op = rv_op_muld; break;
2247 case 12: op = rv_op_divd; break;
2248 case 13: op = rv_op_divud; break;
2249 case 14: op = rv_op_remd; break;
2250 case 15: op = rv_op_remud; break;
2251 case 256: op = rv_op_subd; break;
2252 case 261: op = rv_op_srad; break;
2261 /* operand extractors */
2263 static uint32_t operand_rd(rv_inst inst)
2265 return (inst << 52) >> 59;
2268 static uint32_t operand_rs1(rv_inst inst)
2270 return (inst << 44) >> 59;
2273 static uint32_t operand_rs2(rv_inst inst)
2275 return (inst << 39) >> 59;
2278 static uint32_t operand_rs3(rv_inst inst)
2280 return (inst << 32) >> 59;
2283 static uint32_t operand_aq(rv_inst inst)
2285 return (inst << 37) >> 63;
2288 static uint32_t operand_rl(rv_inst inst)
2290 return (inst << 38) >> 63;
2293 static uint32_t operand_pred(rv_inst inst)
2295 return (inst << 36) >> 60;
2298 static uint32_t operand_succ(rv_inst inst)
2300 return (inst << 40) >> 60;
2303 static uint32_t operand_rm(rv_inst inst)
2305 return (inst << 49) >> 61;
2308 static uint32_t operand_shamt5(rv_inst inst)
2310 return (inst << 39) >> 59;
2313 static uint32_t operand_shamt6(rv_inst inst)
2315 return (inst << 38) >> 58;
2318 static uint32_t operand_shamt7(rv_inst inst)
2320 return (inst << 37) >> 57;
2323 static uint32_t operand_crdq(rv_inst inst)
2325 return (inst << 59) >> 61;
2328 static uint32_t operand_crs1q(rv_inst inst)
2330 return (inst << 54) >> 61;
2333 static uint32_t operand_crs1rdq(rv_inst inst)
2335 return (inst << 54) >> 61;
2338 static uint32_t operand_crs2q(rv_inst inst)
2340 return (inst << 59) >> 61;
2343 static uint32_t operand_crd(rv_inst inst)
2345 return (inst << 52) >> 59;
2348 static uint32_t operand_crs1(rv_inst inst)
2350 return (inst << 52) >> 59;
2353 static uint32_t operand_crs1rd(rv_inst inst)
2355 return (inst << 52) >> 59;
2358 static uint32_t operand_crs2(rv_inst inst)
2360 return (inst << 57) >> 59;
2363 static uint32_t operand_cimmsh5(rv_inst inst)
2365 return (inst << 57) >> 59;
2368 static uint32_t operand_csr12(rv_inst inst)
2370 return (inst << 32) >> 52;
2373 static int32_t operand_imm12(rv_inst inst)
2375 return ((int64_t)inst << 32) >> 52;
2378 static int32_t operand_imm20(rv_inst inst)
2380 return (((int64_t)inst << 32) >> 44) << 12;
2383 static int32_t operand_jimm20(rv_inst inst)
2385 return (((int64_t)inst << 32) >> 63) << 20 |
2386 ((inst << 33) >> 54) << 1 |
2387 ((inst << 43) >> 63) << 11 |
2388 ((inst << 44) >> 56) << 12;
2391 static int32_t operand_simm12(rv_inst inst)
2393 return (((int64_t)inst << 32) >> 57) << 5 |
2397 static int32_t operand_sbimm12(rv_inst inst)
2399 return (((int64_t)inst << 32) >> 63) << 12 |
2400 ((inst << 33) >> 58) << 5 |
2401 ((inst << 52) >> 60) << 1 |
2402 ((inst << 56) >> 63) << 11;
2405 static uint32_t operand_cimmsh6(rv_inst inst)
2407 return ((inst << 51) >> 63) << 5 |
2411 static int32_t operand_cimmi(rv_inst inst)
2413 return (((int64_t)inst << 51) >> 63) << 5 |
2417 static int32_t operand_cimmui(rv_inst inst)
2419 return (((int64_t)inst << 51) >> 63) << 17 |
2420 ((inst << 57) >> 59) << 12;
2423 static uint32_t operand_cimmlwsp(rv_inst inst)
2425 return ((inst << 51) >> 63) << 5 |
2426 ((inst << 57) >> 61) << 2 |
2427 ((inst << 60) >> 62) << 6;
2430 static uint32_t operand_cimmldsp(rv_inst inst)
2432 return ((inst << 51) >> 63) << 5 |
2433 ((inst << 57) >> 62) << 3 |
2434 ((inst << 59) >> 61) << 6;
2437 static uint32_t operand_cimmlqsp(rv_inst inst)
2439 return ((inst << 51) >> 63) << 5 |
2440 ((inst << 57) >> 63) << 4 |
2441 ((inst << 58) >> 60) << 6;
2444 static int32_t operand_cimm16sp(rv_inst inst)
2446 return (((int64_t)inst << 51) >> 63) << 9 |
2447 ((inst << 57) >> 63) << 4 |
2448 ((inst << 58) >> 63) << 6 |
2449 ((inst << 59) >> 62) << 7 |
2450 ((inst << 61) >> 63) << 5;
2453 static int32_t operand_cimmj(rv_inst inst)
2455 return (((int64_t)inst << 51) >> 63) << 11 |
2456 ((inst << 52) >> 63) << 4 |
2457 ((inst << 53) >> 62) << 8 |
2458 ((inst << 55) >> 63) << 10 |
2459 ((inst << 56) >> 63) << 6 |
2460 ((inst << 57) >> 63) << 7 |
2461 ((inst << 58) >> 61) << 1 |
2462 ((inst << 61) >> 63) << 5;
2465 static int32_t operand_cimmb(rv_inst inst)
2467 return (((int64_t)inst << 51) >> 63) << 8 |
2468 ((inst << 52) >> 62) << 3 |
2469 ((inst << 57) >> 62) << 6 |
2470 ((inst << 59) >> 62) << 1 |
2471 ((inst << 61) >> 63) << 5;
2474 static uint32_t operand_cimmswsp(rv_inst inst)
2476 return ((inst << 51) >> 60) << 2 |
2477 ((inst << 55) >> 62) << 6;
2480 static uint32_t operand_cimmsdsp(rv_inst inst)
2482 return ((inst << 51) >> 61) << 3 |
2483 ((inst << 54) >> 61) << 6;
2486 static uint32_t operand_cimmsqsp(rv_inst inst)
2488 return ((inst << 51) >> 62) << 4 |
2489 ((inst << 53) >> 60) << 6;
2492 static uint32_t operand_cimm4spn(rv_inst inst)
2494 return ((inst << 51) >> 62) << 4 |
2495 ((inst << 53) >> 60) << 6 |
2496 ((inst << 57) >> 63) << 2 |
2497 ((inst << 58) >> 63) << 3;
2500 static uint32_t operand_cimmw(rv_inst inst)
2502 return ((inst << 51) >> 61) << 3 |
2503 ((inst << 57) >> 63) << 2 |
2504 ((inst << 58) >> 63) << 6;
2507 static uint32_t operand_cimmd(rv_inst inst)
2509 return ((inst << 51) >> 61) << 3 |
2510 ((inst << 57) >> 62) << 6;
2513 static uint32_t operand_cimmq(rv_inst inst)
2515 return ((inst << 51) >> 62) << 4 |
2516 ((inst << 53) >> 63) << 8 |
2517 ((inst << 57) >> 62) << 6;
2520 static uint32_t operand_bs(rv_inst inst)
2522 return (inst << 32) >> 62;
2525 static uint32_t operand_rnum(rv_inst inst)
2527 return (inst << 40) >> 60;
2530 /* decode operands */
2532 static void decode_inst_operands(rv_decode *dec)
2534 rv_inst inst = dec->inst;
2535 dec->codec = opcode_data[dec->op].codec;
2536 switch (dec->codec) {
2538 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2542 dec->rd = operand_rd(inst);
2543 dec->rs1 = dec->rs2 = rv_ireg_zero;
2544 dec->imm = operand_imm20(inst);
2547 dec->rd = operand_rd(inst);
2548 dec->rs1 = dec->rs2 = rv_ireg_zero;
2549 dec->imm = operand_jimm20(inst);
2552 dec->rd = operand_rd(inst);
2553 dec->rs1 = operand_rs1(inst);
2554 dec->rs2 = rv_ireg_zero;
2555 dec->imm = operand_imm12(inst);
2557 case rv_codec_i_sh5:
2558 dec->rd = operand_rd(inst);
2559 dec->rs1 = operand_rs1(inst);
2560 dec->rs2 = rv_ireg_zero;
2561 dec->imm = operand_shamt5(inst);
2563 case rv_codec_i_sh6:
2564 dec->rd = operand_rd(inst);
2565 dec->rs1 = operand_rs1(inst);
2566 dec->rs2 = rv_ireg_zero;
2567 dec->imm = operand_shamt6(inst);
2569 case rv_codec_i_sh7:
2570 dec->rd = operand_rd(inst);
2571 dec->rs1 = operand_rs1(inst);
2572 dec->rs2 = rv_ireg_zero;
2573 dec->imm = operand_shamt7(inst);
2575 case rv_codec_i_csr:
2576 dec->rd = operand_rd(inst);
2577 dec->rs1 = operand_rs1(inst);
2578 dec->rs2 = rv_ireg_zero;
2579 dec->imm = operand_csr12(inst);
2582 dec->rd = rv_ireg_zero;
2583 dec->rs1 = operand_rs1(inst);
2584 dec->rs2 = operand_rs2(inst);
2585 dec->imm = operand_simm12(inst);
2588 dec->rd = rv_ireg_zero;
2589 dec->rs1 = operand_rs1(inst);
2590 dec->rs2 = operand_rs2(inst);
2591 dec->imm = operand_sbimm12(inst);
2594 dec->rd = operand_rd(inst);
2595 dec->rs1 = operand_rs1(inst);
2596 dec->rs2 = operand_rs2(inst);
2600 dec->rd = operand_rd(inst);
2601 dec->rs1 = operand_rs1(inst);
2602 dec->rs2 = operand_rs2(inst);
2604 dec->rm = operand_rm(inst);
2607 dec->rd = operand_rd(inst);
2608 dec->rs1 = operand_rs1(inst);
2609 dec->rs2 = operand_rs2(inst);
2610 dec->rs3 = operand_rs3(inst);
2612 dec->rm = operand_rm(inst);
2615 dec->rd = operand_rd(inst);
2616 dec->rs1 = operand_rs1(inst);
2617 dec->rs2 = operand_rs2(inst);
2619 dec->aq = operand_aq(inst);
2620 dec->rl = operand_rl(inst);
2623 dec->rd = operand_rd(inst);
2624 dec->rs1 = operand_rs1(inst);
2625 dec->rs2 = rv_ireg_zero;
2627 dec->aq = operand_aq(inst);
2628 dec->rl = operand_rl(inst);
2631 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2632 dec->pred = operand_pred(inst);
2633 dec->succ = operand_succ(inst);
2637 dec->rd = rv_ireg_zero;
2638 dec->rs1 = operand_crs1q(inst) + 8;
2639 dec->rs2 = rv_ireg_zero;
2640 dec->imm = operand_cimmb(inst);
2642 case rv_codec_cb_imm:
2643 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2644 dec->rs2 = rv_ireg_zero;
2645 dec->imm = operand_cimmi(inst);
2647 case rv_codec_cb_sh5:
2648 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2649 dec->rs2 = rv_ireg_zero;
2650 dec->imm = operand_cimmsh5(inst);
2652 case rv_codec_cb_sh6:
2653 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2654 dec->rs2 = rv_ireg_zero;
2655 dec->imm = operand_cimmsh6(inst);
2658 dec->rd = dec->rs1 = operand_crs1rd(inst);
2659 dec->rs2 = rv_ireg_zero;
2660 dec->imm = operand_cimmi(inst);
2662 case rv_codec_ci_sh5:
2663 dec->rd = dec->rs1 = operand_crs1rd(inst);
2664 dec->rs2 = rv_ireg_zero;
2665 dec->imm = operand_cimmsh5(inst);
2667 case rv_codec_ci_sh6:
2668 dec->rd = dec->rs1 = operand_crs1rd(inst);
2669 dec->rs2 = rv_ireg_zero;
2670 dec->imm = operand_cimmsh6(inst);
2672 case rv_codec_ci_16sp:
2673 dec->rd = rv_ireg_sp;
2674 dec->rs1 = rv_ireg_sp;
2675 dec->rs2 = rv_ireg_zero;
2676 dec->imm = operand_cimm16sp(inst);
2678 case rv_codec_ci_lwsp:
2679 dec->rd = operand_crd(inst);
2680 dec->rs1 = rv_ireg_sp;
2681 dec->rs2 = rv_ireg_zero;
2682 dec->imm = operand_cimmlwsp(inst);
2684 case rv_codec_ci_ldsp:
2685 dec->rd = operand_crd(inst);
2686 dec->rs1 = rv_ireg_sp;
2687 dec->rs2 = rv_ireg_zero;
2688 dec->imm = operand_cimmldsp(inst);
2690 case rv_codec_ci_lqsp:
2691 dec->rd = operand_crd(inst);
2692 dec->rs1 = rv_ireg_sp;
2693 dec->rs2 = rv_ireg_zero;
2694 dec->imm = operand_cimmlqsp(inst);
2696 case rv_codec_ci_li:
2697 dec->rd = operand_crd(inst);
2698 dec->rs1 = rv_ireg_zero;
2699 dec->rs2 = rv_ireg_zero;
2700 dec->imm = operand_cimmi(inst);
2702 case rv_codec_ci_lui:
2703 dec->rd = operand_crd(inst);
2704 dec->rs1 = rv_ireg_zero;
2705 dec->rs2 = rv_ireg_zero;
2706 dec->imm = operand_cimmui(inst);
2708 case rv_codec_ci_none:
2709 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2712 case rv_codec_ciw_4spn:
2713 dec->rd = operand_crdq(inst) + 8;
2714 dec->rs1 = rv_ireg_sp;
2715 dec->rs2 = rv_ireg_zero;
2716 dec->imm = operand_cimm4spn(inst);
2719 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2720 dec->imm = operand_cimmj(inst);
2722 case rv_codec_cj_jal:
2723 dec->rd = rv_ireg_ra;
2724 dec->rs1 = dec->rs2 = rv_ireg_zero;
2725 dec->imm = operand_cimmj(inst);
2727 case rv_codec_cl_lw:
2728 dec->rd = operand_crdq(inst) + 8;
2729 dec->rs1 = operand_crs1q(inst) + 8;
2730 dec->rs2 = rv_ireg_zero;
2731 dec->imm = operand_cimmw(inst);
2733 case rv_codec_cl_ld:
2734 dec->rd = operand_crdq(inst) + 8;
2735 dec->rs1 = operand_crs1q(inst) + 8;
2736 dec->rs2 = rv_ireg_zero;
2737 dec->imm = operand_cimmd(inst);
2739 case rv_codec_cl_lq:
2740 dec->rd = operand_crdq(inst) + 8;
2741 dec->rs1 = operand_crs1q(inst) + 8;
2742 dec->rs2 = rv_ireg_zero;
2743 dec->imm = operand_cimmq(inst);
2746 dec->rd = dec->rs1 = operand_crs1rd(inst);
2747 dec->rs2 = operand_crs2(inst);
2750 case rv_codec_cr_mv:
2751 dec->rd = operand_crd(inst);
2752 dec->rs1 = operand_crs2(inst);
2753 dec->rs2 = rv_ireg_zero;
2756 case rv_codec_cr_jalr:
2757 dec->rd = rv_ireg_ra;
2758 dec->rs1 = operand_crs1(inst);
2759 dec->rs2 = rv_ireg_zero;
2762 case rv_codec_cr_jr:
2763 dec->rd = rv_ireg_zero;
2764 dec->rs1 = operand_crs1(inst);
2765 dec->rs2 = rv_ireg_zero;
2769 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2770 dec->rs2 = operand_crs2q(inst) + 8;
2773 case rv_codec_cs_sw:
2774 dec->rd = rv_ireg_zero;
2775 dec->rs1 = operand_crs1q(inst) + 8;
2776 dec->rs2 = operand_crs2q(inst) + 8;
2777 dec->imm = operand_cimmw(inst);
2779 case rv_codec_cs_sd:
2780 dec->rd = rv_ireg_zero;
2781 dec->rs1 = operand_crs1q(inst) + 8;
2782 dec->rs2 = operand_crs2q(inst) + 8;
2783 dec->imm = operand_cimmd(inst);
2785 case rv_codec_cs_sq:
2786 dec->rd = rv_ireg_zero;
2787 dec->rs1 = operand_crs1q(inst) + 8;
2788 dec->rs2 = operand_crs2q(inst) + 8;
2789 dec->imm = operand_cimmq(inst);
2791 case rv_codec_css_swsp:
2792 dec->rd = rv_ireg_zero;
2793 dec->rs1 = rv_ireg_sp;
2794 dec->rs2 = operand_crs2(inst);
2795 dec->imm = operand_cimmswsp(inst);
2797 case rv_codec_css_sdsp:
2798 dec->rd = rv_ireg_zero;
2799 dec->rs1 = rv_ireg_sp;
2800 dec->rs2 = operand_crs2(inst);
2801 dec->imm = operand_cimmsdsp(inst);
2803 case rv_codec_css_sqsp:
2804 dec->rd = rv_ireg_zero;
2805 dec->rs1 = rv_ireg_sp;
2806 dec->rs2 = operand_crs2(inst);
2807 dec->imm = operand_cimmsqsp(inst);
2810 dec->rs1 = operand_rs1(inst);
2811 dec->rs2 = operand_rs2(inst);
2812 dec->bs = operand_bs(inst);
2814 case rv_codec_k_rnum:
2815 dec->rd = operand_rd(inst);
2816 dec->rs1 = operand_rs1(inst);
2817 dec->rnum = operand_rnum(inst);
2822 /* check constraint */
2824 static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
2826 int32_t imm = dec->imm;
2827 uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
2828 while (*c != rvc_end) {
2850 case rvc_rs2_eq_rs1:
2851 if (!(rs2 == rs1)) {
2860 case rvc_imm_eq_zero:
2875 case rvc_csr_eq_0x001:
2876 if (!(imm == 0x001)) {
2880 case rvc_csr_eq_0x002:
2881 if (!(imm == 0x002)) {
2885 case rvc_csr_eq_0x003:
2886 if (!(imm == 0x003)) {
2890 case rvc_csr_eq_0xc00:
2891 if (!(imm == 0xc00)) {
2895 case rvc_csr_eq_0xc01:
2896 if (!(imm == 0xc01)) {
2900 case rvc_csr_eq_0xc02:
2901 if (!(imm == 0xc02)) {
2905 case rvc_csr_eq_0xc80:
2906 if (!(imm == 0xc80)) {
2910 case rvc_csr_eq_0xc81:
2911 if (!(imm == 0xc81)) {
2915 case rvc_csr_eq_0xc82:
2916 if (!(imm == 0xc82)) {
2927 /* instruction length */
2929 static size_t inst_length(rv_inst inst)
2931 /* NOTE: supports maximum instruction size of 64-bits */
2933 /* instruction length coding
2935 * aa - 16 bit aa != 11
2936 * bbb11 - 32 bit bbb != 111
2941 return (inst & 0b11) != 0b11 ? 2
2942 : (inst & 0b11100) != 0b11100 ? 4
2943 : (inst & 0b111111) == 0b011111 ? 6
2944 : (inst & 0b1111111) == 0b0111111 ? 8
2948 /* format instruction */
2950 static void append(char *s1, const char *s2, size_t n)
2952 size_t l1 = strlen(s1);
2953 if (n - l1 - 1 > 0) {
2954 strncat(s1, s2, n - l1);
2958 static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
2963 fmt = opcode_data[dec->op].format;
2967 append(buf, opcode_data[dec->op].name, buflen);
2970 append(buf, "(", buflen);
2973 append(buf, ",", buflen);
2976 append(buf, ")", buflen);
2979 snprintf(tmp, sizeof(tmp), "%d", dec->bs);
2980 append(buf, tmp, buflen);
2983 snprintf(tmp, sizeof(tmp), "%d", dec->rnum);
2984 append(buf, tmp, buflen);
2987 append(buf, rv_ireg_name_sym[dec->rd], buflen);
2990 append(buf, rv_ireg_name_sym[dec->rs1], buflen);
2993 append(buf, rv_ireg_name_sym[dec->rs2], buflen);
2996 append(buf, rv_freg_name_sym[dec->rd], buflen);
2999 append(buf, rv_freg_name_sym[dec->rs1], buflen);
3002 append(buf, rv_freg_name_sym[dec->rs2], buflen);
3005 append(buf, rv_freg_name_sym[dec->rs3], buflen);
3008 snprintf(tmp, sizeof(tmp), "%d", dec->rs1);
3009 append(buf, tmp, buflen);
3012 snprintf(tmp, sizeof(tmp), "%d", dec->imm);
3013 append(buf, tmp, buflen);
3016 snprintf(tmp, sizeof(tmp), "%d", dec->imm);
3017 append(buf, tmp, buflen);
3018 while (strlen(buf) < tab * 2) {
3019 append(buf, " ", buflen);
3021 snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
3022 dec->pc + dec->imm);
3023 append(buf, tmp, buflen);
3026 const char *name = csr_name(dec->imm & 0xfff);
3028 append(buf, name, buflen);
3030 snprintf(tmp, sizeof(tmp), "0x%03x", dec->imm & 0xfff);
3031 append(buf, tmp, buflen);
3038 append(buf, "rne", buflen);
3041 append(buf, "rtz", buflen);
3044 append(buf, "rdn", buflen);
3047 append(buf, "rup", buflen);
3050 append(buf, "rmm", buflen);
3053 append(buf, "dyn", buflen);
3056 append(buf, "inv", buflen);
3061 if (dec->pred & rv_fence_i) {
3062 append(buf, "i", buflen);
3064 if (dec->pred & rv_fence_o) {
3065 append(buf, "o", buflen);
3067 if (dec->pred & rv_fence_r) {
3068 append(buf, "r", buflen);
3070 if (dec->pred & rv_fence_w) {
3071 append(buf, "w", buflen);
3075 if (dec->succ & rv_fence_i) {
3076 append(buf, "i", buflen);
3078 if (dec->succ & rv_fence_o) {
3079 append(buf, "o", buflen);
3081 if (dec->succ & rv_fence_r) {
3082 append(buf, "r", buflen);
3084 if (dec->succ & rv_fence_w) {
3085 append(buf, "w", buflen);
3089 while (strlen(buf) < tab) {
3090 append(buf, " ", buflen);
3095 append(buf, ".aq", buflen);
3100 append(buf, ".rl", buflen);
3110 /* lift instruction to pseudo-instruction */
3112 static void decode_inst_lift_pseudo(rv_decode *dec)
3114 const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
3118 while (comp_data->constraints) {
3119 if (check_constraints(dec, comp_data->constraints)) {
3120 dec->op = comp_data->op;
3121 dec->codec = opcode_data[dec->op].codec;
3128 /* decompress instruction */
3130 static void decode_inst_decompress_rv32(rv_decode *dec)
3132 int decomp_op = opcode_data[dec->op].decomp_rv32;
3133 if (decomp_op != rv_op_illegal) {
3134 if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3136 dec->op = rv_op_illegal;
3138 dec->op = decomp_op;
3139 dec->codec = opcode_data[decomp_op].codec;
3144 static void decode_inst_decompress_rv64(rv_decode *dec)
3146 int decomp_op = opcode_data[dec->op].decomp_rv64;
3147 if (decomp_op != rv_op_illegal) {
3148 if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3150 dec->op = rv_op_illegal;
3152 dec->op = decomp_op;
3153 dec->codec = opcode_data[decomp_op].codec;
3158 static void decode_inst_decompress_rv128(rv_decode *dec)
3160 int decomp_op = opcode_data[dec->op].decomp_rv128;
3161 if (decomp_op != rv_op_illegal) {
3162 if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3164 dec->op = rv_op_illegal;
3166 dec->op = decomp_op;
3167 dec->codec = opcode_data[decomp_op].codec;
3172 static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
3176 decode_inst_decompress_rv32(dec);
3179 decode_inst_decompress_rv64(dec);
3182 decode_inst_decompress_rv128(dec);
3187 /* disassemble instruction */
3190 disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
3192 rv_decode dec = { 0 };
3195 decode_inst_opcode(&dec, isa);
3196 decode_inst_operands(&dec);
3197 decode_inst_decompress(&dec, isa);
3198 decode_inst_lift_pseudo(&dec);
3199 format_inst(buf, buflen, 16, &dec);
3202 #define INST_FMT_2 "%04" PRIx64 " "
3203 #define INST_FMT_4 "%08" PRIx64 " "
3204 #define INST_FMT_6 "%012" PRIx64 " "
3205 #define INST_FMT_8 "%016" PRIx64 " "
3208 print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
3210 char buf[128] = { 0 };
3217 /* Instructions are made of 2-byte packets in little-endian order */
3218 for (n = 0; n < len; n += 2) {
3219 status = (*info->read_memory_func)(memaddr + n, packet, 2, info);
3221 /* Don't fail just because we fell off the end. */
3225 (*info->memory_error_func)(status, memaddr, info);
3228 inst |= ((rv_inst) bfd_getl16(packet)) << (8 * n);
3230 len = inst_length(inst);
3236 (*info->fprintf_func)(info->stream, INST_FMT_2, inst);
3239 (*info->fprintf_func)(info->stream, INST_FMT_4, inst);
3242 (*info->fprintf_func)(info->stream, INST_FMT_6, inst);
3245 (*info->fprintf_func)(info->stream, INST_FMT_8, inst);
3249 disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
3250 (*info->fprintf_func)(info->stream, "%s", buf);
3255 int print_insn_riscv32(bfd_vma memaddr, struct disassemble_info *info)
3257 return print_insn_riscv(memaddr, info, rv32);
3260 int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info)
3262 return print_insn_riscv(memaddr, info, rv64);
3265 int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
3267 return print_insn_riscv(memaddr, info, rv128);