qemu/disas/riscv.c
<<
>>
Prefs
   1/*
   2 * QEMU RISC-V Disassembler
   3 *
   4 * Copyright (c) 2016-2017 Michael Clark <michaeljclark@mac.com>
   5 * Copyright (c) 2017-2018 SiFive, Inc.
   6 *
   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.
  10 *
  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
  14 * more details.
  15 *
  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/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "disas/bfd.h"
  22
  23
  24/* types */
  25
  26typedef uint64_t rv_inst;
  27typedef uint16_t rv_opcode;
  28
  29/* enums */
  30
  31typedef enum {
  32    rv32,
  33    rv64,
  34    rv128
  35} rv_isa;
  36
  37typedef enum {
  38    rv_rm_rne = 0,
  39    rv_rm_rtz = 1,
  40    rv_rm_rdn = 2,
  41    rv_rm_rup = 3,
  42    rv_rm_rmm = 4,
  43    rv_rm_dyn = 7,
  44} rv_rm;
  45
  46typedef enum {
  47    rv_fence_i = 8,
  48    rv_fence_o = 4,
  49    rv_fence_r = 2,
  50    rv_fence_w = 1,
  51} rv_fence;
  52
  53typedef enum {
  54    rv_ireg_zero,
  55    rv_ireg_ra,
  56    rv_ireg_sp,
  57    rv_ireg_gp,
  58    rv_ireg_tp,
  59    rv_ireg_t0,
  60    rv_ireg_t1,
  61    rv_ireg_t2,
  62    rv_ireg_s0,
  63    rv_ireg_s1,
  64    rv_ireg_a0,
  65    rv_ireg_a1,
  66    rv_ireg_a2,
  67    rv_ireg_a3,
  68    rv_ireg_a4,
  69    rv_ireg_a5,
  70    rv_ireg_a6,
  71    rv_ireg_a7,
  72    rv_ireg_s2,
  73    rv_ireg_s3,
  74    rv_ireg_s4,
  75    rv_ireg_s5,
  76    rv_ireg_s6,
  77    rv_ireg_s7,
  78    rv_ireg_s8,
  79    rv_ireg_s9,
  80    rv_ireg_s10,
  81    rv_ireg_s11,
  82    rv_ireg_t3,
  83    rv_ireg_t4,
  84    rv_ireg_t5,
  85    rv_ireg_t6,
  86} rv_ireg;
  87
  88typedef enum {
  89    rvc_end,
  90    rvc_rd_eq_ra,
  91    rvc_rd_eq_x0,
  92    rvc_rs1_eq_x0,
  93    rvc_rs2_eq_x0,
  94    rvc_rs2_eq_rs1,
  95    rvc_rs1_eq_ra,
  96    rvc_imm_eq_zero,
  97    rvc_imm_eq_n1,
  98    rvc_imm_eq_p1,
  99    rvc_csr_eq_0x001,
 100    rvc_csr_eq_0x002,
 101    rvc_csr_eq_0x003,
 102    rvc_csr_eq_0xc00,
 103    rvc_csr_eq_0xc01,
 104    rvc_csr_eq_0xc02,
 105    rvc_csr_eq_0xc80,
 106    rvc_csr_eq_0xc81,
 107    rvc_csr_eq_0xc82,
 108} rvc_constraint;
 109
 110typedef enum {
 111    rv_codec_illegal,
 112    rv_codec_none,
 113    rv_codec_u,
 114    rv_codec_uj,
 115    rv_codec_i,
 116    rv_codec_i_sh5,
 117    rv_codec_i_sh6,
 118    rv_codec_i_sh7,
 119    rv_codec_i_csr,
 120    rv_codec_s,
 121    rv_codec_sb,
 122    rv_codec_r,
 123    rv_codec_r_m,
 124    rv_codec_r4_m,
 125    rv_codec_r_a,
 126    rv_codec_r_l,
 127    rv_codec_r_f,
 128    rv_codec_cb,
 129    rv_codec_cb_imm,
 130    rv_codec_cb_sh5,
 131    rv_codec_cb_sh6,
 132    rv_codec_ci,
 133    rv_codec_ci_sh5,
 134    rv_codec_ci_sh6,
 135    rv_codec_ci_16sp,
 136    rv_codec_ci_lwsp,
 137    rv_codec_ci_ldsp,
 138    rv_codec_ci_lqsp,
 139    rv_codec_ci_li,
 140    rv_codec_ci_lui,
 141    rv_codec_ci_none,
 142    rv_codec_ciw_4spn,
 143    rv_codec_cj,
 144    rv_codec_cj_jal,
 145    rv_codec_cl_lw,
 146    rv_codec_cl_ld,
 147    rv_codec_cl_lq,
 148    rv_codec_cr,
 149    rv_codec_cr_mv,
 150    rv_codec_cr_jalr,
 151    rv_codec_cr_jr,
 152    rv_codec_cs,
 153    rv_codec_cs_sw,
 154    rv_codec_cs_sd,
 155    rv_codec_cs_sq,
 156    rv_codec_css_swsp,
 157    rv_codec_css_sdsp,
 158    rv_codec_css_sqsp,
 159} rv_codec;
 160
 161typedef enum {
 162    rv_op_illegal = 0,
 163    rv_op_lui = 1,
 164    rv_op_auipc = 2,
 165    rv_op_jal = 3,
 166    rv_op_jalr = 4,
 167    rv_op_beq = 5,
 168    rv_op_bne = 6,
 169    rv_op_blt = 7,
 170    rv_op_bge = 8,
 171    rv_op_bltu = 9,
 172    rv_op_bgeu = 10,
 173    rv_op_lb = 11,
 174    rv_op_lh = 12,
 175    rv_op_lw = 13,
 176    rv_op_lbu = 14,
 177    rv_op_lhu = 15,
 178    rv_op_sb = 16,
 179    rv_op_sh = 17,
 180    rv_op_sw = 18,
 181    rv_op_addi = 19,
 182    rv_op_slti = 20,
 183    rv_op_sltiu = 21,
 184    rv_op_xori = 22,
 185    rv_op_ori = 23,
 186    rv_op_andi = 24,
 187    rv_op_slli = 25,
 188    rv_op_srli = 26,
 189    rv_op_srai = 27,
 190    rv_op_add = 28,
 191    rv_op_sub = 29,
 192    rv_op_sll = 30,
 193    rv_op_slt = 31,
 194    rv_op_sltu = 32,
 195    rv_op_xor = 33,
 196    rv_op_srl = 34,
 197    rv_op_sra = 35,
 198    rv_op_or = 36,
 199    rv_op_and = 37,
 200    rv_op_fence = 38,
 201    rv_op_fence_i = 39,
 202    rv_op_lwu = 40,
 203    rv_op_ld = 41,
 204    rv_op_sd = 42,
 205    rv_op_addiw = 43,
 206    rv_op_slliw = 44,
 207    rv_op_srliw = 45,
 208    rv_op_sraiw = 46,
 209    rv_op_addw = 47,
 210    rv_op_subw = 48,
 211    rv_op_sllw = 49,
 212    rv_op_srlw = 50,
 213    rv_op_sraw = 51,
 214    rv_op_ldu = 52,
 215    rv_op_lq = 53,
 216    rv_op_sq = 54,
 217    rv_op_addid = 55,
 218    rv_op_sllid = 56,
 219    rv_op_srlid = 57,
 220    rv_op_sraid = 58,
 221    rv_op_addd = 59,
 222    rv_op_subd = 60,
 223    rv_op_slld = 61,
 224    rv_op_srld = 62,
 225    rv_op_srad = 63,
 226    rv_op_mul = 64,
 227    rv_op_mulh = 65,
 228    rv_op_mulhsu = 66,
 229    rv_op_mulhu = 67,
 230    rv_op_div = 68,
 231    rv_op_divu = 69,
 232    rv_op_rem = 70,
 233    rv_op_remu = 71,
 234    rv_op_mulw = 72,
 235    rv_op_divw = 73,
 236    rv_op_divuw = 74,
 237    rv_op_remw = 75,
 238    rv_op_remuw = 76,
 239    rv_op_muld = 77,
 240    rv_op_divd = 78,
 241    rv_op_divud = 79,
 242    rv_op_remd = 80,
 243    rv_op_remud = 81,
 244    rv_op_lr_w = 82,
 245    rv_op_sc_w = 83,
 246    rv_op_amoswap_w = 84,
 247    rv_op_amoadd_w = 85,
 248    rv_op_amoxor_w = 86,
 249    rv_op_amoor_w = 87,
 250    rv_op_amoand_w = 88,
 251    rv_op_amomin_w = 89,
 252    rv_op_amomax_w = 90,
 253    rv_op_amominu_w = 91,
 254    rv_op_amomaxu_w = 92,
 255    rv_op_lr_d = 93,
 256    rv_op_sc_d = 94,
 257    rv_op_amoswap_d = 95,
 258    rv_op_amoadd_d = 96,
 259    rv_op_amoxor_d = 97,
 260    rv_op_amoor_d = 98,
 261    rv_op_amoand_d = 99,
 262    rv_op_amomin_d = 100,
 263    rv_op_amomax_d = 101,
 264    rv_op_amominu_d = 102,
 265    rv_op_amomaxu_d = 103,
 266    rv_op_lr_q = 104,
 267    rv_op_sc_q = 105,
 268    rv_op_amoswap_q = 106,
 269    rv_op_amoadd_q = 107,
 270    rv_op_amoxor_q = 108,
 271    rv_op_amoor_q = 109,
 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,
 277    rv_op_ecall = 115,
 278    rv_op_ebreak = 116,
 279    rv_op_uret = 117,
 280    rv_op_sret = 118,
 281    rv_op_hret = 119,
 282    rv_op_mret = 120,
 283    rv_op_dret = 121,
 284    rv_op_sfence_vm = 122,
 285    rv_op_sfence_vma = 123,
 286    rv_op_wfi = 124,
 287    rv_op_csrrw = 125,
 288    rv_op_csrrs = 126,
 289    rv_op_csrrc = 127,
 290    rv_op_csrrwi = 128,
 291    rv_op_csrrsi = 129,
 292    rv_op_csrrci = 130,
 293    rv_op_flw = 131,
 294    rv_op_fsw = 132,
 295    rv_op_fmadd_s = 133,
 296    rv_op_fmsub_s = 134,
 297    rv_op_fnmsub_s = 135,
 298    rv_op_fnmadd_s = 136,
 299    rv_op_fadd_s = 137,
 300    rv_op_fsub_s = 138,
 301    rv_op_fmul_s = 139,
 302    rv_op_fdiv_s = 140,
 303    rv_op_fsgnj_s = 141,
 304    rv_op_fsgnjn_s = 142,
 305    rv_op_fsgnjx_s = 143,
 306    rv_op_fmin_s = 144,
 307    rv_op_fmax_s = 145,
 308    rv_op_fsqrt_s = 146,
 309    rv_op_fle_s = 147,
 310    rv_op_flt_s = 148,
 311    rv_op_feq_s = 149,
 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,
 316    rv_op_fmv_x_s = 154,
 317    rv_op_fclass_s = 155,
 318    rv_op_fmv_s_x = 156,
 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,
 323    rv_op_fld = 161,
 324    rv_op_fsd = 162,
 325    rv_op_fmadd_d = 163,
 326    rv_op_fmsub_d = 164,
 327    rv_op_fnmsub_d = 165,
 328    rv_op_fnmadd_d = 166,
 329    rv_op_fadd_d = 167,
 330    rv_op_fsub_d = 168,
 331    rv_op_fmul_d = 169,
 332    rv_op_fdiv_d = 170,
 333    rv_op_fsgnj_d = 171,
 334    rv_op_fsgnjn_d = 172,
 335    rv_op_fsgnjx_d = 173,
 336    rv_op_fmin_d = 174,
 337    rv_op_fmax_d = 175,
 338    rv_op_fcvt_s_d = 176,
 339    rv_op_fcvt_d_s = 177,
 340    rv_op_fsqrt_d = 178,
 341    rv_op_fle_d = 179,
 342    rv_op_flt_d = 180,
 343    rv_op_feq_d = 181,
 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,
 351    rv_op_fmv_x_d = 189,
 352    rv_op_fcvt_d_l = 190,
 353    rv_op_fcvt_d_lu = 191,
 354    rv_op_fmv_d_x = 192,
 355    rv_op_flq = 193,
 356    rv_op_fsq = 194,
 357    rv_op_fmadd_q = 195,
 358    rv_op_fmsub_q = 196,
 359    rv_op_fnmsub_q = 197,
 360    rv_op_fnmadd_q = 198,
 361    rv_op_fadd_q = 199,
 362    rv_op_fsub_q = 200,
 363    rv_op_fmul_q = 201,
 364    rv_op_fdiv_q = 202,
 365    rv_op_fsgnj_q = 203,
 366    rv_op_fsgnjn_q = 204,
 367    rv_op_fsgnjx_q = 205,
 368    rv_op_fmin_q = 206,
 369    rv_op_fmax_q = 207,
 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,
 374    rv_op_fsqrt_q = 212,
 375    rv_op_fle_q = 213,
 376    rv_op_flt_q = 214,
 377    rv_op_feq_q = 215,
 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,
 387    rv_op_fmv_x_q = 225,
 388    rv_op_fmv_q_x = 226,
 389    rv_op_c_addi4spn = 227,
 390    rv_op_c_fld = 228,
 391    rv_op_c_lw = 229,
 392    rv_op_c_flw = 230,
 393    rv_op_c_fsd = 231,
 394    rv_op_c_sw = 232,
 395    rv_op_c_fsw = 233,
 396    rv_op_c_nop = 234,
 397    rv_op_c_addi = 235,
 398    rv_op_c_jal = 236,
 399    rv_op_c_li = 237,
 400    rv_op_c_addi16sp = 238,
 401    rv_op_c_lui = 239,
 402    rv_op_c_srli = 240,
 403    rv_op_c_srai = 241,
 404    rv_op_c_andi = 242,
 405    rv_op_c_sub = 243,
 406    rv_op_c_xor = 244,
 407    rv_op_c_or = 245,
 408    rv_op_c_and = 246,
 409    rv_op_c_subw = 247,
 410    rv_op_c_addw = 248,
 411    rv_op_c_j = 249,
 412    rv_op_c_beqz = 250,
 413    rv_op_c_bnez = 251,
 414    rv_op_c_slli = 252,
 415    rv_op_c_fldsp = 253,
 416    rv_op_c_lwsp = 254,
 417    rv_op_c_flwsp = 255,
 418    rv_op_c_jr = 256,
 419    rv_op_c_mv = 257,
 420    rv_op_c_ebreak = 258,
 421    rv_op_c_jalr = 259,
 422    rv_op_c_add = 260,
 423    rv_op_c_fsdsp = 261,
 424    rv_op_c_swsp = 262,
 425    rv_op_c_fswsp = 263,
 426    rv_op_c_ld = 264,
 427    rv_op_c_sd = 265,
 428    rv_op_c_addiw = 266,
 429    rv_op_c_ldsp = 267,
 430    rv_op_c_sdsp = 268,
 431    rv_op_c_lq = 269,
 432    rv_op_c_sq = 270,
 433    rv_op_c_lqsp = 271,
 434    rv_op_c_sqsp = 272,
 435    rv_op_nop = 273,
 436    rv_op_mv = 274,
 437    rv_op_not = 275,
 438    rv_op_neg = 276,
 439    rv_op_negw = 277,
 440    rv_op_sext_w = 278,
 441    rv_op_seqz = 279,
 442    rv_op_snez = 280,
 443    rv_op_sltz = 281,
 444    rv_op_sgtz = 282,
 445    rv_op_fmv_s = 283,
 446    rv_op_fabs_s = 284,
 447    rv_op_fneg_s = 285,
 448    rv_op_fmv_d = 286,
 449    rv_op_fabs_d = 287,
 450    rv_op_fneg_d = 288,
 451    rv_op_fmv_q = 289,
 452    rv_op_fabs_q = 290,
 453    rv_op_fneg_q = 291,
 454    rv_op_beqz = 292,
 455    rv_op_bnez = 293,
 456    rv_op_blez = 294,
 457    rv_op_bgez = 295,
 458    rv_op_bltz = 296,
 459    rv_op_bgtz = 297,
 460    rv_op_ble = 298,
 461    rv_op_bleu = 299,
 462    rv_op_bgt = 300,
 463    rv_op_bgtu = 301,
 464    rv_op_j = 302,
 465    rv_op_ret = 303,
 466    rv_op_jr = 304,
 467    rv_op_rdcycle = 305,
 468    rv_op_rdtime = 306,
 469    rv_op_rdinstret = 307,
 470    rv_op_rdcycleh = 308,
 471    rv_op_rdtimeh = 309,
 472    rv_op_rdinstreth = 310,
 473    rv_op_frcsr = 311,
 474    rv_op_frrm = 312,
 475    rv_op_frflags = 313,
 476    rv_op_fscsr = 314,
 477    rv_op_fsrm = 315,
 478    rv_op_fsflags = 316,
 479    rv_op_fsrmi = 317,
 480    rv_op_fsflagsi = 318,
 481} rv_op;
 482
 483/* structures */
 484
 485typedef struct {
 486    uint64_t  pc;
 487    uint64_t  inst;
 488    int32_t   imm;
 489    uint16_t  op;
 490    uint8_t   codec;
 491    uint8_t   rd;
 492    uint8_t   rs1;
 493    uint8_t   rs2;
 494    uint8_t   rs3;
 495    uint8_t   rm;
 496    uint8_t   pred;
 497    uint8_t   succ;
 498    uint8_t   aq;
 499    uint8_t   rl;
 500} rv_decode;
 501
 502typedef struct {
 503    const int op;
 504    const rvc_constraint *constraints;
 505} rv_comp_data;
 506
 507typedef struct {
 508    const char * const name;
 509    const rv_codec codec;
 510    const char * const format;
 511    const rv_comp_data *pseudo;
 512    const int decomp_rv32;
 513    const int decomp_rv64;
 514    const int decomp_rv128;
 515} rv_opcode_data;
 516
 517/* register names */
 518
 519static const char rv_ireg_name_sym[32][5] = {
 520    "zero", "ra",   "sp",   "gp",   "tp",   "t0",   "t1",   "t2",
 521    "s0",   "s1",   "a0",   "a1",   "a2",   "a3",   "a4",   "a5",
 522    "a6",   "a7",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
 523    "s8",   "s9",   "s10",  "s11",  "t3",   "t4",   "t5",   "t6",
 524};
 525
 526static const char rv_freg_name_sym[32][5] = {
 527    "ft0",  "ft1",  "ft2",  "ft3",  "ft4",  "ft5",  "ft6",  "ft7",
 528    "fs0",  "fs1",  "fa0",  "fa1",  "fa2",  "fa3",  "fa4",  "fa5",
 529    "fa6",  "fa7",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7",
 530    "fs8",  "fs9",  "fs10", "fs11", "ft8",  "ft9",  "ft10", "ft11",
 531};
 532
 533/* instruction formats */
 534
 535#define rv_fmt_none                   "O\t"
 536#define rv_fmt_rs1                    "O\t1"
 537#define rv_fmt_offset                 "O\to"
 538#define rv_fmt_pred_succ              "O\tp,s"
 539#define rv_fmt_rs1_rs2                "O\t1,2"
 540#define rv_fmt_rd_imm                 "O\t0,i"
 541#define rv_fmt_rd_offset              "O\t0,o"
 542#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
 543#define rv_fmt_frd_rs1                "O\t3,1"
 544#define rv_fmt_rd_frs1                "O\t0,4"
 545#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
 546#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
 547#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
 548#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
 549#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
 550#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
 551#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
 552#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
 553#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
 554#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
 555#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
 556#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
 557#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
 558#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
 559#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
 560#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
 561#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
 562#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
 563#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
 564#define rv_fmt_rd                     "O\t0"
 565#define rv_fmt_rd_zimm                "O\t0,7"
 566#define rv_fmt_rd_rs1                 "O\t0,1"
 567#define rv_fmt_rd_rs2                 "O\t0,2"
 568#define rv_fmt_rs1_offset             "O\t1,o"
 569#define rv_fmt_rs2_offset             "O\t2,o"
 570
 571/* pseudo-instruction constraints */
 572
 573static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
 574static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, rvc_end };
 575static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, rvc_imm_eq_zero, rvc_end };
 576static const rvc_constraint rvcc_mv[] = { rvc_imm_eq_zero, rvc_end };
 577static const rvc_constraint rvcc_not[] = { rvc_imm_eq_n1, rvc_end };
 578static const rvc_constraint rvcc_neg[] = { rvc_rs1_eq_x0, rvc_end };
 579static const rvc_constraint rvcc_negw[] = { rvc_rs1_eq_x0, rvc_end };
 580static const rvc_constraint rvcc_sext_w[] = { rvc_imm_eq_zero, rvc_end };
 581static const rvc_constraint rvcc_seqz[] = { rvc_imm_eq_p1, rvc_end };
 582static const rvc_constraint rvcc_snez[] = { rvc_rs1_eq_x0, rvc_end };
 583static const rvc_constraint rvcc_sltz[] = { rvc_rs2_eq_x0, rvc_end };
 584static const rvc_constraint rvcc_sgtz[] = { rvc_rs1_eq_x0, rvc_end };
 585static const rvc_constraint rvcc_fmv_s[] = { rvc_rs2_eq_rs1, rvc_end };
 586static const rvc_constraint rvcc_fabs_s[] = { rvc_rs2_eq_rs1, rvc_end };
 587static const rvc_constraint rvcc_fneg_s[] = { rvc_rs2_eq_rs1, rvc_end };
 588static const rvc_constraint rvcc_fmv_d[] = { rvc_rs2_eq_rs1, rvc_end };
 589static const rvc_constraint rvcc_fabs_d[] = { rvc_rs2_eq_rs1, rvc_end };
 590static const rvc_constraint rvcc_fneg_d[] = { rvc_rs2_eq_rs1, rvc_end };
 591static const rvc_constraint rvcc_fmv_q[] = { rvc_rs2_eq_rs1, rvc_end };
 592static const rvc_constraint rvcc_fabs_q[] = { rvc_rs2_eq_rs1, rvc_end };
 593static const rvc_constraint rvcc_fneg_q[] = { rvc_rs2_eq_rs1, rvc_end };
 594static const rvc_constraint rvcc_beqz[] = { rvc_rs2_eq_x0, rvc_end };
 595static const rvc_constraint rvcc_bnez[] = { rvc_rs2_eq_x0, rvc_end };
 596static const rvc_constraint rvcc_blez[] = { rvc_rs1_eq_x0, rvc_end };
 597static const rvc_constraint rvcc_bgez[] = { rvc_rs2_eq_x0, rvc_end };
 598static const rvc_constraint rvcc_bltz[] = { rvc_rs2_eq_x0, rvc_end };
 599static const rvc_constraint rvcc_bgtz[] = { rvc_rs1_eq_x0, rvc_end };
 600static const rvc_constraint rvcc_ble[] = { rvc_end };
 601static const rvc_constraint rvcc_bleu[] = { rvc_end };
 602static const rvc_constraint rvcc_bgt[] = { rvc_end };
 603static const rvc_constraint rvcc_bgtu[] = { rvc_end };
 604static const rvc_constraint rvcc_j[] = { rvc_rd_eq_x0, rvc_end };
 605static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, rvc_end };
 606static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, rvc_end };
 607static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00, rvc_end };
 608static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, rvc_end };
 609static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
 610static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
 611static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
 612static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
 613static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
 614static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
 615static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
 616static const rvc_constraint rvcc_fscsr[] = { rvc_csr_eq_0x003, rvc_end };
 617static const rvc_constraint rvcc_fsrm[] = { rvc_csr_eq_0x002, rvc_end };
 618static const rvc_constraint rvcc_fsflags[] = { rvc_csr_eq_0x001, rvc_end };
 619static const rvc_constraint rvcc_fsrmi[] = { rvc_csr_eq_0x002, rvc_end };
 620static const rvc_constraint rvcc_fsflagsi[] = { rvc_csr_eq_0x001, rvc_end };
 621
 622/* pseudo-instruction metadata */
 623
 624static const rv_comp_data rvcp_jal[] = {
 625    { rv_op_j, rvcc_j },
 626    { rv_op_jal, rvcc_jal },
 627    { rv_op_illegal, NULL }
 628};
 629
 630static const rv_comp_data rvcp_jalr[] = {
 631    { rv_op_ret, rvcc_ret },
 632    { rv_op_jr, rvcc_jr },
 633    { rv_op_jalr, rvcc_jalr },
 634    { rv_op_illegal, NULL }
 635};
 636
 637static const rv_comp_data rvcp_beq[] = {
 638    { rv_op_beqz, rvcc_beqz },
 639    { rv_op_illegal, NULL }
 640};
 641
 642static const rv_comp_data rvcp_bne[] = {
 643    { rv_op_bnez, rvcc_bnez },
 644    { rv_op_illegal, NULL }
 645};
 646
 647static const rv_comp_data rvcp_blt[] = {
 648    { rv_op_bltz, rvcc_bltz },
 649    { rv_op_bgtz, rvcc_bgtz },
 650    { rv_op_bgt, rvcc_bgt },
 651    { rv_op_illegal, NULL }
 652};
 653
 654static const rv_comp_data rvcp_bge[] = {
 655    { rv_op_blez, rvcc_blez },
 656    { rv_op_bgez, rvcc_bgez },
 657    { rv_op_ble, rvcc_ble },
 658    { rv_op_illegal, NULL }
 659};
 660
 661static const rv_comp_data rvcp_bltu[] = {
 662    { rv_op_bgtu, rvcc_bgtu },
 663    { rv_op_illegal, NULL }
 664};
 665
 666static const rv_comp_data rvcp_bgeu[] = {
 667    { rv_op_bleu, rvcc_bleu },
 668    { rv_op_illegal, NULL }
 669};
 670
 671static const rv_comp_data rvcp_addi[] = {
 672    { rv_op_nop, rvcc_nop },
 673    { rv_op_mv, rvcc_mv },
 674    { rv_op_illegal, NULL }
 675};
 676
 677static const rv_comp_data rvcp_sltiu[] = {
 678    { rv_op_seqz, rvcc_seqz },
 679    { rv_op_illegal, NULL }
 680};
 681
 682static const rv_comp_data rvcp_xori[] = {
 683    { rv_op_not, rvcc_not },
 684    { rv_op_illegal, NULL }
 685};
 686
 687static const rv_comp_data rvcp_sub[] = {
 688    { rv_op_neg, rvcc_neg },
 689    { rv_op_illegal, NULL }
 690};
 691
 692static const rv_comp_data rvcp_slt[] = {
 693    { rv_op_sltz, rvcc_sltz },
 694    { rv_op_sgtz, rvcc_sgtz },
 695    { rv_op_illegal, NULL }
 696};
 697
 698static const rv_comp_data rvcp_sltu[] = {
 699    { rv_op_snez, rvcc_snez },
 700    { rv_op_illegal, NULL }
 701};
 702
 703static const rv_comp_data rvcp_addiw[] = {
 704    { rv_op_sext_w, rvcc_sext_w },
 705    { rv_op_illegal, NULL }
 706};
 707
 708static const rv_comp_data rvcp_subw[] = {
 709    { rv_op_negw, rvcc_negw },
 710    { rv_op_illegal, NULL }
 711};
 712
 713static const rv_comp_data rvcp_csrrw[] = {
 714    { rv_op_fscsr, rvcc_fscsr },
 715    { rv_op_fsrm, rvcc_fsrm },
 716    { rv_op_fsflags, rvcc_fsflags },
 717    { rv_op_illegal, NULL }
 718};
 719
 720static const rv_comp_data rvcp_csrrs[] = {
 721    { rv_op_rdcycle, rvcc_rdcycle },
 722    { rv_op_rdtime, rvcc_rdtime },
 723    { rv_op_rdinstret, rvcc_rdinstret },
 724    { rv_op_rdcycleh, rvcc_rdcycleh },
 725    { rv_op_rdtimeh, rvcc_rdtimeh },
 726    { rv_op_rdinstreth, rvcc_rdinstreth },
 727    { rv_op_frcsr, rvcc_frcsr },
 728    { rv_op_frrm, rvcc_frrm },
 729    { rv_op_frflags, rvcc_frflags },
 730    { rv_op_illegal, NULL }
 731};
 732
 733static const rv_comp_data rvcp_csrrwi[] = {
 734    { rv_op_fsrmi, rvcc_fsrmi },
 735    { rv_op_fsflagsi, rvcc_fsflagsi },
 736    { rv_op_illegal, NULL }
 737};
 738
 739static const rv_comp_data rvcp_fsgnj_s[] = {
 740    { rv_op_fmv_s, rvcc_fmv_s },
 741    { rv_op_illegal, NULL }
 742};
 743
 744static const rv_comp_data rvcp_fsgnjn_s[] = {
 745    { rv_op_fneg_s, rvcc_fneg_s },
 746    { rv_op_illegal, NULL }
 747};
 748
 749static const rv_comp_data rvcp_fsgnjx_s[] = {
 750    { rv_op_fabs_s, rvcc_fabs_s },
 751    { rv_op_illegal, NULL }
 752};
 753
 754static const rv_comp_data rvcp_fsgnj_d[] = {
 755    { rv_op_fmv_d, rvcc_fmv_d },
 756    { rv_op_illegal, NULL }
 757};
 758
 759static const rv_comp_data rvcp_fsgnjn_d[] = {
 760    { rv_op_fneg_d, rvcc_fneg_d },
 761    { rv_op_illegal, NULL }
 762};
 763
 764static const rv_comp_data rvcp_fsgnjx_d[] = {
 765    { rv_op_fabs_d, rvcc_fabs_d },
 766    { rv_op_illegal, NULL }
 767};
 768
 769static const rv_comp_data rvcp_fsgnj_q[] = {
 770    { rv_op_fmv_q, rvcc_fmv_q },
 771    { rv_op_illegal, NULL }
 772};
 773
 774static const rv_comp_data rvcp_fsgnjn_q[] = {
 775    { rv_op_fneg_q, rvcc_fneg_q },
 776    { rv_op_illegal, NULL }
 777};
 778
 779static const rv_comp_data rvcp_fsgnjx_q[] = {
 780    { rv_op_fabs_q, rvcc_fabs_q },
 781    { rv_op_illegal, NULL }
 782};
 783
 784/* instruction metadata */
 785
 786const rv_opcode_data opcode_data[] = {
 787    { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
 788    { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
 789    { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
 790    { "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
 791    { "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
 792    { "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
 793    { "bne", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bne, 0, 0, 0 },
 794    { "blt", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_blt, 0, 0, 0 },
 795    { "bge", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bge, 0, 0, 0 },
 796    { "bltu", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bltu, 0, 0, 0 },
 797    { "bgeu", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bgeu, 0, 0, 0 },
 798    { "lb", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 799    { "lh", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 800    { "lw", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 801    { "lbu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 802    { "lhu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 803    { "sb", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
 804    { "sh", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
 805    { "sw", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
 806    { "addi", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_addi, 0, 0, 0 },
 807    { "slti", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 808    { "sltiu", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_sltiu, 0, 0, 0 },
 809    { "xori", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_xori, 0, 0, 0 },
 810    { "ori", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 811    { "andi", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 812    { "slli", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 813    { "srli", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 814    { "srai", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 815    { "add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 816    { "sub", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_sub, 0, 0, 0 },
 817    { "sll", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 818    { "slt", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_slt, 0, 0, 0 },
 819    { "sltu", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_sltu, 0, 0, 0 },
 820    { "xor", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 821    { "srl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 822    { "sra", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 823    { "or", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 824    { "and", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 825    { "fence", rv_codec_r_f, rv_fmt_pred_succ, NULL, 0, 0, 0 },
 826    { "fence.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 827    { "lwu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 828    { "ld", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 829    { "sd", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
 830    { "addiw", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_addiw, 0, 0, 0 },
 831    { "slliw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 832    { "srliw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 833    { "sraiw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 834    { "addw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 835    { "subw", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_subw, 0, 0, 0 },
 836    { "sllw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 837    { "srlw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 838    { "sraw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 839    { "ldu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 840    { "lq", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
 841    { "sq", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
 842    { "addid", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 843    { "sllid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 844    { "srlid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 845    { "sraid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
 846    { "addd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 847    { "subd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 848    { "slld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 849    { "srld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 850    { "srad", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 851    { "mul", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 852    { "mulh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 853    { "mulhsu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 854    { "mulhu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 855    { "div", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 856    { "divu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 857    { "rem", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 858    { "remu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 859    { "mulw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 860    { "divw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 861    { "divuw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 862    { "remw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 863    { "remuw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 864    { "muld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 865    { "divd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 866    { "divud", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 867    { "remd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 868    { "remud", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 869    { "lr.w", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
 870    { "sc.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 871    { "amoswap.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 872    { "amoadd.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 873    { "amoxor.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 874    { "amoor.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 875    { "amoand.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 876    { "amomin.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 877    { "amomax.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 878    { "amominu.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 879    { "amomaxu.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 880    { "lr.d", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
 881    { "sc.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 882    { "amoswap.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 883    { "amoadd.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 884    { "amoxor.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 885    { "amoor.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 886    { "amoand.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 887    { "amomin.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 888    { "amomax.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 889    { "amominu.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 890    { "amomaxu.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 891    { "lr.q", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
 892    { "sc.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 893    { "amoswap.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 894    { "amoadd.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 895    { "amoxor.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 896    { "amoor.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 897    { "amoand.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 898    { "amomin.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 899    { "amomax.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 900    { "amominu.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 901    { "amomaxu.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 902    { "ecall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 903    { "ebreak", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 904    { "uret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 905    { "sret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 906    { "hret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 907    { "mret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 908    { "dret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 909    { "sfence.vm", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
 910    { "sfence.vma", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 },
 911    { "wfi", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
 912    { "csrrw", rv_codec_i_csr, rv_fmt_rd_csr_rs1, rvcp_csrrw, 0, 0, 0 },
 913    { "csrrs", rv_codec_i_csr, rv_fmt_rd_csr_rs1, rvcp_csrrs, 0, 0, 0 },
 914    { "csrrc", rv_codec_i_csr, rv_fmt_rd_csr_rs1, NULL, 0, 0, 0 },
 915    { "csrrwi", rv_codec_i_csr, rv_fmt_rd_csr_zimm, rvcp_csrrwi, 0, 0, 0 },
 916    { "csrrsi", rv_codec_i_csr, rv_fmt_rd_csr_zimm, NULL, 0, 0, 0 },
 917    { "csrrci", rv_codec_i_csr, rv_fmt_rd_csr_zimm, NULL, 0, 0, 0 },
 918    { "flw", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
 919    { "fsw", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
 920    { "fmadd.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 921    { "fmsub.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 922    { "fnmsub.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 923    { "fnmadd.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 924    { "fadd.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 925    { "fsub.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 926    { "fmul.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 927    { "fdiv.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 928    { "fsgnj.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_s, 0, 0, 0 },
 929    { "fsgnjn.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_s, 0, 0, 0 },
 930    { "fsgnjx.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_s, 0, 0, 0 },
 931    { "fmin.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
 932    { "fmax.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
 933    { "fsqrt.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 934    { "fle.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
 935    { "flt.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
 936    { "feq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
 937    { "fcvt.w.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 938    { "fcvt.wu.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 939    { "fcvt.s.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 940    { "fcvt.s.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 941    { "fmv.x.s", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
 942    { "fclass.s", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
 943    { "fmv.s.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
 944    { "fcvt.l.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 945    { "fcvt.lu.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 946    { "fcvt.s.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 947    { "fcvt.s.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 948    { "fld", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
 949    { "fsd", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
 950    { "fmadd.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 951    { "fmsub.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 952    { "fnmsub.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 953    { "fnmadd.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 954    { "fadd.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 955    { "fsub.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 956    { "fmul.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 957    { "fdiv.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 958    { "fsgnj.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_d, 0, 0, 0 },
 959    { "fsgnjn.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_d, 0, 0, 0 },
 960    { "fsgnjx.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_d, 0, 0, 0 },
 961    { "fmin.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
 962    { "fmax.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
 963    { "fcvt.s.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 964    { "fcvt.d.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 965    { "fsqrt.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 966    { "fle.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
 967    { "flt.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
 968    { "feq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
 969    { "fcvt.w.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 970    { "fcvt.wu.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 971    { "fcvt.d.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 972    { "fcvt.d.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 973    { "fclass.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
 974    { "fcvt.l.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 975    { "fcvt.lu.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
 976    { "fmv.x.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
 977    { "fcvt.d.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 978    { "fcvt.d.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 979    { "fmv.d.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
 980    { "flq", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
 981    { "fsq", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
 982    { "fmadd.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 983    { "fmsub.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 984    { "fnmsub.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 985    { "fnmadd.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
 986    { "fadd.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 987    { "fsub.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 988    { "fmul.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 989    { "fdiv.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
 990    { "fsgnj.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_q, 0, 0, 0 },
 991    { "fsgnjn.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_q, 0, 0, 0 },
 992    { "fsgnjx.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_q, 0, 0, 0 },
 993    { "fmin.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
 994    { "fmax.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
 995    { "fcvt.s.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 996    { "fcvt.q.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 997    { "fcvt.d.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 998    { "fcvt.q.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
 999    { "fsqrt.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1000    { "fle.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1001    { "flt.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1002    { "feq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1003    { "fcvt.w.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1004    { "fcvt.wu.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1005    { "fcvt.q.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1006    { "fcvt.q.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1007    { "fclass.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1008    { "fcvt.l.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1009    { "fcvt.lu.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1010    { "fcvt.q.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1011    { "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1012    { "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1013    { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1014    { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1015    { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
1016    { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
1017    { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
1018    { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
1019    { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
1020    { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
1021    { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1022    { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1023    { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
1024    { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1025    { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1026    { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui },
1027    { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli },
1028    { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai },
1029    { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi },
1030    { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
1031    { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
1032    { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
1033    { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and, rv_op_and },
1034    { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw, rv_op_subw },
1035    { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw, rv_op_addw },
1036    { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
1037    { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
1038    { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
1039    { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli },
1040    { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
1041    { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
1042    { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
1043    { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
1044    { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1045    { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak, rv_op_ebreak, rv_op_ebreak },
1046    { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
1047    { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add, rv_op_add },
1048    { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, rv_op_fsd },
1049    { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
1050    { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
1051    { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
1052    { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
1053    { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw, rv_op_addiw },
1054    { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
1055    { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
1056    { "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
1057    { "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
1058    { "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
1059    { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
1060    { "nop", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
1061    { "mv", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1062    { "not", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1063    { "neg", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1064    { "negw", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1065    { "sext.w", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1066    { "seqz", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1067    { "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1068    { "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1069    { "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1070    { "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1071    { "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1072    { "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1073    { "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1074    { "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1075    { "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1076    { "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1077    { "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1078    { "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1079    { "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1080    { "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1081    { "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
1082    { "bgez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1083    { "bltz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1084    { "bgtz", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
1085    { "ble", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1086    { "bleu", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1087    { "bgt", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1088    { "bgtu", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1089    { "j", rv_codec_uj, rv_fmt_offset, NULL, 0, 0, 0 },
1090    { "ret", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
1091    { "jr", rv_codec_i, rv_fmt_rs1, NULL, 0, 0, 0 },
1092    { "rdcycle", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1093    { "rdtime", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1094    { "rdinstret", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1095    { "rdcycleh", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1096    { "rdtimeh", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1097    { "rdinstreth", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1098    { "frcsr", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1099    { "frrm", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1100    { "frflags", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1101    { "fscsr", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1102    { "fsrm", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1103    { "fsflags", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1104    { "fsrmi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 },
1105    { "fsflagsi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 },
1106};
1107
1108/* CSR names */
1109
1110static const char *csr_name(int csrno)
1111{
1112    switch (csrno) {
1113    case 0x0000: return "ustatus";
1114    case 0x0001: return "fflags";
1115    case 0x0002: return "frm";
1116    case 0x0003: return "fcsr";
1117    case 0x0004: return "uie";
1118    case 0x0005: return "utvec";
1119    case 0x0040: return "uscratch";
1120    case 0x0041: return "uepc";
1121    case 0x0042: return "ucause";
1122    case 0x0043: return "utval";
1123    case 0x0044: return "uip";
1124    case 0x0100: return "sstatus";
1125    case 0x0102: return "sedeleg";
1126    case 0x0103: return "sideleg";
1127    case 0x0104: return "sie";
1128    case 0x0105: return "stvec";
1129    case 0x0106: return "scounteren";
1130    case 0x0140: return "sscratch";
1131    case 0x0141: return "sepc";
1132    case 0x0142: return "scause";
1133    case 0x0143: return "stval";
1134    case 0x0144: return "sip";
1135    case 0x0180: return "satp";
1136    case 0x0200: return "hstatus";
1137    case 0x0202: return "hedeleg";
1138    case 0x0203: return "hideleg";
1139    case 0x0204: return "hie";
1140    case 0x0205: return "htvec";
1141    case 0x0240: return "hscratch";
1142    case 0x0241: return "hepc";
1143    case 0x0242: return "hcause";
1144    case 0x0243: return "hbadaddr";
1145    case 0x0244: return "hip";
1146    case 0x0300: return "mstatus";
1147    case 0x0301: return "misa";
1148    case 0x0302: return "medeleg";
1149    case 0x0303: return "mideleg";
1150    case 0x0304: return "mie";
1151    case 0x0305: return "mtvec";
1152    case 0x0306: return "mcounteren";
1153    case 0x0320: return "mucounteren";
1154    case 0x0321: return "mscounteren";
1155    case 0x0322: return "mhcounteren";
1156    case 0x0323: return "mhpmevent3";
1157    case 0x0324: return "mhpmevent4";
1158    case 0x0325: return "mhpmevent5";
1159    case 0x0326: return "mhpmevent6";
1160    case 0x0327: return "mhpmevent7";
1161    case 0x0328: return "mhpmevent8";
1162    case 0x0329: return "mhpmevent9";
1163    case 0x032a: return "mhpmevent10";
1164    case 0x032b: return "mhpmevent11";
1165    case 0x032c: return "mhpmevent12";
1166    case 0x032d: return "mhpmevent13";
1167    case 0x032e: return "mhpmevent14";
1168    case 0x032f: return "mhpmevent15";
1169    case 0x0330: return "mhpmevent16";
1170    case 0x0331: return "mhpmevent17";
1171    case 0x0332: return "mhpmevent18";
1172    case 0x0333: return "mhpmevent19";
1173    case 0x0334: return "mhpmevent20";
1174    case 0x0335: return "mhpmevent21";
1175    case 0x0336: return "mhpmevent22";
1176    case 0x0337: return "mhpmevent23";
1177    case 0x0338: return "mhpmevent24";
1178    case 0x0339: return "mhpmevent25";
1179    case 0x033a: return "mhpmevent26";
1180    case 0x033b: return "mhpmevent27";
1181    case 0x033c: return "mhpmevent28";
1182    case 0x033d: return "mhpmevent29";
1183    case 0x033e: return "mhpmevent30";
1184    case 0x033f: return "mhpmevent31";
1185    case 0x0340: return "mscratch";
1186    case 0x0341: return "mepc";
1187    case 0x0342: return "mcause";
1188    case 0x0343: return "mtval";
1189    case 0x0344: return "mip";
1190    case 0x0380: return "mbase";
1191    case 0x0381: return "mbound";
1192    case 0x0382: return "mibase";
1193    case 0x0383: return "mibound";
1194    case 0x0384: return "mdbase";
1195    case 0x0385: return "mdbound";
1196    case 0x03a0: return "pmpcfg3";
1197    case 0x03b0: return "pmpaddr0";
1198    case 0x03b1: return "pmpaddr1";
1199    case 0x03b2: return "pmpaddr2";
1200    case 0x03b3: return "pmpaddr3";
1201    case 0x03b4: return "pmpaddr4";
1202    case 0x03b5: return "pmpaddr5";
1203    case 0x03b6: return "pmpaddr6";
1204    case 0x03b7: return "pmpaddr7";
1205    case 0x03b8: return "pmpaddr8";
1206    case 0x03b9: return "pmpaddr9";
1207    case 0x03ba: return "pmpaddr10";
1208    case 0x03bb: return "pmpaddr11";
1209    case 0x03bc: return "pmpaddr12";
1210    case 0x03bd: return "pmpaddr14";
1211    case 0x03be: return "pmpaddr13";
1212    case 0x03bf: return "pmpaddr15";
1213    case 0x0780: return "mtohost";
1214    case 0x0781: return "mfromhost";
1215    case 0x0782: return "mreset";
1216    case 0x0783: return "mipi";
1217    case 0x0784: return "miobase";
1218    case 0x07a0: return "tselect";
1219    case 0x07a1: return "tdata1";
1220    case 0x07a2: return "tdata2";
1221    case 0x07a3: return "tdata3";
1222    case 0x07b0: return "dcsr";
1223    case 0x07b1: return "dpc";
1224    case 0x07b2: return "dscratch";
1225    case 0x0b00: return "mcycle";
1226    case 0x0b01: return "mtime";
1227    case 0x0b02: return "minstret";
1228    case 0x0b03: return "mhpmcounter3";
1229    case 0x0b04: return "mhpmcounter4";
1230    case 0x0b05: return "mhpmcounter5";
1231    case 0x0b06: return "mhpmcounter6";
1232    case 0x0b07: return "mhpmcounter7";
1233    case 0x0b08: return "mhpmcounter8";
1234    case 0x0b09: return "mhpmcounter9";
1235    case 0x0b0a: return "mhpmcounter10";
1236    case 0x0b0b: return "mhpmcounter11";
1237    case 0x0b0c: return "mhpmcounter12";
1238    case 0x0b0d: return "mhpmcounter13";
1239    case 0x0b0e: return "mhpmcounter14";
1240    case 0x0b0f: return "mhpmcounter15";
1241    case 0x0b10: return "mhpmcounter16";
1242    case 0x0b11: return "mhpmcounter17";
1243    case 0x0b12: return "mhpmcounter18";
1244    case 0x0b13: return "mhpmcounter19";
1245    case 0x0b14: return "mhpmcounter20";
1246    case 0x0b15: return "mhpmcounter21";
1247    case 0x0b16: return "mhpmcounter22";
1248    case 0x0b17: return "mhpmcounter23";
1249    case 0x0b18: return "mhpmcounter24";
1250    case 0x0b19: return "mhpmcounter25";
1251    case 0x0b1a: return "mhpmcounter26";
1252    case 0x0b1b: return "mhpmcounter27";
1253    case 0x0b1c: return "mhpmcounter28";
1254    case 0x0b1d: return "mhpmcounter29";
1255    case 0x0b1e: return "mhpmcounter30";
1256    case 0x0b1f: return "mhpmcounter31";
1257    case 0x0b80: return "mcycleh";
1258    case 0x0b81: return "mtimeh";
1259    case 0x0b82: return "minstreth";
1260    case 0x0b83: return "mhpmcounter3h";
1261    case 0x0b84: return "mhpmcounter4h";
1262    case 0x0b85: return "mhpmcounter5h";
1263    case 0x0b86: return "mhpmcounter6h";
1264    case 0x0b87: return "mhpmcounter7h";
1265    case 0x0b88: return "mhpmcounter8h";
1266    case 0x0b89: return "mhpmcounter9h";
1267    case 0x0b8a: return "mhpmcounter10h";
1268    case 0x0b8b: return "mhpmcounter11h";
1269    case 0x0b8c: return "mhpmcounter12h";
1270    case 0x0b8d: return "mhpmcounter13h";
1271    case 0x0b8e: return "mhpmcounter14h";
1272    case 0x0b8f: return "mhpmcounter15h";
1273    case 0x0b90: return "mhpmcounter16h";
1274    case 0x0b91: return "mhpmcounter17h";
1275    case 0x0b92: return "mhpmcounter18h";
1276    case 0x0b93: return "mhpmcounter19h";
1277    case 0x0b94: return "mhpmcounter20h";
1278    case 0x0b95: return "mhpmcounter21h";
1279    case 0x0b96: return "mhpmcounter22h";
1280    case 0x0b97: return "mhpmcounter23h";
1281    case 0x0b98: return "mhpmcounter24h";
1282    case 0x0b99: return "mhpmcounter25h";
1283    case 0x0b9a: return "mhpmcounter26h";
1284    case 0x0b9b: return "mhpmcounter27h";
1285    case 0x0b9c: return "mhpmcounter28h";
1286    case 0x0b9d: return "mhpmcounter29h";
1287    case 0x0b9e: return "mhpmcounter30h";
1288    case 0x0b9f: return "mhpmcounter31h";
1289    case 0x0c00: return "cycle";
1290    case 0x0c01: return "time";
1291    case 0x0c02: return "instret";
1292    case 0x0c80: return "cycleh";
1293    case 0x0c81: return "timeh";
1294    case 0x0c82: return "instreth";
1295    case 0x0d00: return "scycle";
1296    case 0x0d01: return "stime";
1297    case 0x0d02: return "sinstret";
1298    case 0x0d80: return "scycleh";
1299    case 0x0d81: return "stimeh";
1300    case 0x0d82: return "sinstreth";
1301    case 0x0e00: return "hcycle";
1302    case 0x0e01: return "htime";
1303    case 0x0e02: return "hinstret";
1304    case 0x0e80: return "hcycleh";
1305    case 0x0e81: return "htimeh";
1306    case 0x0e82: return "hinstreth";
1307    case 0x0f11: return "mvendorid";
1308    case 0x0f12: return "marchid";
1309    case 0x0f13: return "mimpid";
1310    case 0x0f14: return "mhartid";
1311    default: return NULL;
1312    }
1313}
1314
1315/* decode opcode */
1316
1317static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
1318{
1319    rv_inst inst = dec->inst;
1320    rv_opcode op = rv_op_illegal;
1321    switch (((inst >> 0) & 0b11)) {
1322    case 0:
1323        switch (((inst >> 13) & 0b111)) {
1324        case 0: op = rv_op_c_addi4spn; break;
1325        case 1:
1326            if (isa == rv128) {
1327                op = rv_op_c_lq;
1328            } else {
1329                op = rv_op_c_fld;
1330            }
1331            break;
1332        case 2: op = rv_op_c_lw; break;
1333        case 3:
1334            if (isa == rv32) {
1335                op = rv_op_c_flw;
1336            } else {
1337                op = rv_op_c_ld;
1338            }
1339            break;
1340        case 5:
1341            if (isa == rv128) {
1342                op = rv_op_c_sq;
1343            } else {
1344                op = rv_op_c_fsd;
1345            }
1346            break;
1347        case 6: op = rv_op_c_sw; break;
1348        case 7:
1349            if (isa == rv32) {
1350                op = rv_op_c_fsw;
1351            } else {
1352                op = rv_op_c_sd;
1353            }
1354            break;
1355        }
1356        break;
1357    case 1:
1358        switch (((inst >> 13) & 0b111)) {
1359        case 0:
1360            switch (((inst >> 2) & 0b11111111111)) {
1361            case 0: op = rv_op_c_nop; break;
1362            default: op = rv_op_c_addi; break;
1363            }
1364            break;
1365        case 1:
1366            if (isa == rv32) {
1367                op = rv_op_c_jal;
1368            } else {
1369                op = rv_op_c_addiw;
1370            }
1371            break;
1372        case 2: op = rv_op_c_li; break;
1373        case 3:
1374            switch (((inst >> 7) & 0b11111)) {
1375            case 2: op = rv_op_c_addi16sp; break;
1376            default: op = rv_op_c_lui; break;
1377            }
1378            break;
1379        case 4:
1380            switch (((inst >> 10) & 0b11)) {
1381            case 0:
1382                op = rv_op_c_srli;
1383                break;
1384            case 1:
1385                op = rv_op_c_srai;
1386                break;
1387            case 2: op = rv_op_c_andi; break;
1388            case 3:
1389                switch (((inst >> 10) & 0b100) | ((inst >> 5) & 0b011)) {
1390                case 0: op = rv_op_c_sub; break;
1391                case 1: op = rv_op_c_xor; break;
1392                case 2: op = rv_op_c_or; break;
1393                case 3: op = rv_op_c_and; break;
1394                case 4: op = rv_op_c_subw; break;
1395                case 5: op = rv_op_c_addw; break;
1396                }
1397                break;
1398            }
1399            break;
1400        case 5: op = rv_op_c_j; break;
1401        case 6: op = rv_op_c_beqz; break;
1402        case 7: op = rv_op_c_bnez; break;
1403        }
1404        break;
1405    case 2:
1406        switch (((inst >> 13) & 0b111)) {
1407        case 0:
1408            op = rv_op_c_slli;
1409            break;
1410        case 1:
1411            if (isa == rv128) {
1412                op = rv_op_c_lqsp;
1413            } else {
1414                op = rv_op_c_fldsp;
1415            }
1416            break;
1417        case 2: op = rv_op_c_lwsp; break;
1418        case 3:
1419            if (isa == rv32) {
1420                op = rv_op_c_flwsp;
1421            } else {
1422                op = rv_op_c_ldsp;
1423            }
1424            break;
1425        case 4:
1426            switch (((inst >> 12) & 0b1)) {
1427            case 0:
1428                switch (((inst >> 2) & 0b11111)) {
1429                case 0: op = rv_op_c_jr; break;
1430                default: op = rv_op_c_mv; break;
1431                }
1432                break;
1433            case 1:
1434                switch (((inst >> 2) & 0b11111)) {
1435                case 0:
1436                    switch (((inst >> 7) & 0b11111)) {
1437                    case 0: op = rv_op_c_ebreak; break;
1438                    default: op = rv_op_c_jalr; break;
1439                    }
1440                    break;
1441                default: op = rv_op_c_add; break;
1442                }
1443                break;
1444            }
1445            break;
1446        case 5:
1447            if (isa == rv128) {
1448                op = rv_op_c_sqsp;
1449            } else {
1450                op = rv_op_c_fsdsp;
1451            }
1452            break;
1453        case 6: op = rv_op_c_swsp; break;
1454        case 7:
1455            if (isa == rv32) {
1456                op = rv_op_c_fswsp;
1457            } else {
1458                op = rv_op_c_sdsp;
1459            }
1460            break;
1461        }
1462        break;
1463    case 3:
1464        switch (((inst >> 2) & 0b11111)) {
1465        case 0:
1466            switch (((inst >> 12) & 0b111)) {
1467            case 0: op = rv_op_lb; break;
1468            case 1: op = rv_op_lh; break;
1469            case 2: op = rv_op_lw; break;
1470            case 3: op = rv_op_ld; break;
1471            case 4: op = rv_op_lbu; break;
1472            case 5: op = rv_op_lhu; break;
1473            case 6: op = rv_op_lwu; break;
1474            case 7: op = rv_op_ldu; break;
1475            }
1476            break;
1477        case 1:
1478            switch (((inst >> 12) & 0b111)) {
1479            case 2: op = rv_op_flw; break;
1480            case 3: op = rv_op_fld; break;
1481            case 4: op = rv_op_flq; break;
1482            }
1483            break;
1484        case 3:
1485            switch (((inst >> 12) & 0b111)) {
1486            case 0: op = rv_op_fence; break;
1487            case 1: op = rv_op_fence_i; break;
1488            case 2: op = rv_op_lq; break;
1489            }
1490            break;
1491        case 4:
1492            switch (((inst >> 12) & 0b111)) {
1493            case 0: op = rv_op_addi; break;
1494            case 1:
1495                switch (((inst >> 27) & 0b11111)) {
1496                case 0: op = rv_op_slli; break;
1497                }
1498                break;
1499            case 2: op = rv_op_slti; break;
1500            case 3: op = rv_op_sltiu; break;
1501            case 4: op = rv_op_xori; break;
1502            case 5:
1503                switch (((inst >> 27) & 0b11111)) {
1504                case 0: op = rv_op_srli; break;
1505                case 8: op = rv_op_srai; break;
1506                }
1507                break;
1508            case 6: op = rv_op_ori; break;
1509            case 7: op = rv_op_andi; break;
1510            }
1511            break;
1512        case 5: op = rv_op_auipc; break;
1513        case 6:
1514            switch (((inst >> 12) & 0b111)) {
1515            case 0: op = rv_op_addiw; break;
1516            case 1:
1517                switch (((inst >> 25) & 0b1111111)) {
1518                case 0: op = rv_op_slliw; break;
1519                }
1520                break;
1521            case 5:
1522                switch (((inst >> 25) & 0b1111111)) {
1523                case 0: op = rv_op_srliw; break;
1524                case 32: op = rv_op_sraiw; break;
1525                }
1526                break;
1527            }
1528            break;
1529        case 8:
1530            switch (((inst >> 12) & 0b111)) {
1531            case 0: op = rv_op_sb; break;
1532            case 1: op = rv_op_sh; break;
1533            case 2: op = rv_op_sw; break;
1534            case 3: op = rv_op_sd; break;
1535            case 4: op = rv_op_sq; break;
1536            }
1537            break;
1538        case 9:
1539            switch (((inst >> 12) & 0b111)) {
1540            case 2: op = rv_op_fsw; break;
1541            case 3: op = rv_op_fsd; break;
1542            case 4: op = rv_op_fsq; break;
1543            }
1544            break;
1545        case 11:
1546            switch (((inst >> 24) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1547            case 2: op = rv_op_amoadd_w; break;
1548            case 3: op = rv_op_amoadd_d; break;
1549            case 4: op = rv_op_amoadd_q; break;
1550            case 10: op = rv_op_amoswap_w; break;
1551            case 11: op = rv_op_amoswap_d; break;
1552            case 12: op = rv_op_amoswap_q; break;
1553            case 18:
1554                switch (((inst >> 20) & 0b11111)) {
1555                case 0: op = rv_op_lr_w; break;
1556                }
1557                break;
1558            case 19:
1559                switch (((inst >> 20) & 0b11111)) {
1560                case 0: op = rv_op_lr_d; break;
1561                }
1562                break;
1563            case 20:
1564                switch (((inst >> 20) & 0b11111)) {
1565                case 0: op = rv_op_lr_q; break;
1566                }
1567                break;
1568            case 26: op = rv_op_sc_w; break;
1569            case 27: op = rv_op_sc_d; break;
1570            case 28: op = rv_op_sc_q; break;
1571            case 34: op = rv_op_amoxor_w; break;
1572            case 35: op = rv_op_amoxor_d; break;
1573            case 36: op = rv_op_amoxor_q; break;
1574            case 66: op = rv_op_amoor_w; break;
1575            case 67: op = rv_op_amoor_d; break;
1576            case 68: op = rv_op_amoor_q; break;
1577            case 98: op = rv_op_amoand_w; break;
1578            case 99: op = rv_op_amoand_d; break;
1579            case 100: op = rv_op_amoand_q; break;
1580            case 130: op = rv_op_amomin_w; break;
1581            case 131: op = rv_op_amomin_d; break;
1582            case 132: op = rv_op_amomin_q; break;
1583            case 162: op = rv_op_amomax_w; break;
1584            case 163: op = rv_op_amomax_d; break;
1585            case 164: op = rv_op_amomax_q; break;
1586            case 194: op = rv_op_amominu_w; break;
1587            case 195: op = rv_op_amominu_d; break;
1588            case 196: op = rv_op_amominu_q; break;
1589            case 226: op = rv_op_amomaxu_w; break;
1590            case 227: op = rv_op_amomaxu_d; break;
1591            case 228: op = rv_op_amomaxu_q; break;
1592            }
1593            break;
1594        case 12:
1595            switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1596            case 0: op = rv_op_add; break;
1597            case 1: op = rv_op_sll; break;
1598            case 2: op = rv_op_slt; break;
1599            case 3: op = rv_op_sltu; break;
1600            case 4: op = rv_op_xor; break;
1601            case 5: op = rv_op_srl; break;
1602            case 6: op = rv_op_or; break;
1603            case 7: op = rv_op_and; break;
1604            case 8: op = rv_op_mul; break;
1605            case 9: op = rv_op_mulh; break;
1606            case 10: op = rv_op_mulhsu; break;
1607            case 11: op = rv_op_mulhu; break;
1608            case 12: op = rv_op_div; break;
1609            case 13: op = rv_op_divu; break;
1610            case 14: op = rv_op_rem; break;
1611            case 15: op = rv_op_remu; break;
1612            case 256: op = rv_op_sub; break;
1613            case 261: op = rv_op_sra; break;
1614            }
1615            break;
1616        case 13: op = rv_op_lui; break;
1617        case 14:
1618            switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1619            case 0: op = rv_op_addw; break;
1620            case 1: op = rv_op_sllw; break;
1621            case 5: op = rv_op_srlw; break;
1622            case 8: op = rv_op_mulw; break;
1623            case 12: op = rv_op_divw; break;
1624            case 13: op = rv_op_divuw; break;
1625            case 14: op = rv_op_remw; break;
1626            case 15: op = rv_op_remuw; break;
1627            case 256: op = rv_op_subw; break;
1628            case 261: op = rv_op_sraw; break;
1629            }
1630            break;
1631        case 16:
1632            switch (((inst >> 25) & 0b11)) {
1633            case 0: op = rv_op_fmadd_s; break;
1634            case 1: op = rv_op_fmadd_d; break;
1635            case 3: op = rv_op_fmadd_q; break;
1636            }
1637            break;
1638        case 17:
1639            switch (((inst >> 25) & 0b11)) {
1640            case 0: op = rv_op_fmsub_s; break;
1641            case 1: op = rv_op_fmsub_d; break;
1642            case 3: op = rv_op_fmsub_q; break;
1643            }
1644            break;
1645        case 18:
1646            switch (((inst >> 25) & 0b11)) {
1647            case 0: op = rv_op_fnmsub_s; break;
1648            case 1: op = rv_op_fnmsub_d; break;
1649            case 3: op = rv_op_fnmsub_q; break;
1650            }
1651            break;
1652        case 19:
1653            switch (((inst >> 25) & 0b11)) {
1654            case 0: op = rv_op_fnmadd_s; break;
1655            case 1: op = rv_op_fnmadd_d; break;
1656            case 3: op = rv_op_fnmadd_q; break;
1657            }
1658            break;
1659        case 20:
1660            switch (((inst >> 25) & 0b1111111)) {
1661            case 0: op = rv_op_fadd_s; break;
1662            case 1: op = rv_op_fadd_d; break;
1663            case 3: op = rv_op_fadd_q; break;
1664            case 4: op = rv_op_fsub_s; break;
1665            case 5: op = rv_op_fsub_d; break;
1666            case 7: op = rv_op_fsub_q; break;
1667            case 8: op = rv_op_fmul_s; break;
1668            case 9: op = rv_op_fmul_d; break;
1669            case 11: op = rv_op_fmul_q; break;
1670            case 12: op = rv_op_fdiv_s; break;
1671            case 13: op = rv_op_fdiv_d; break;
1672            case 15: op = rv_op_fdiv_q; break;
1673            case 16:
1674                switch (((inst >> 12) & 0b111)) {
1675                case 0: op = rv_op_fsgnj_s; break;
1676                case 1: op = rv_op_fsgnjn_s; break;
1677                case 2: op = rv_op_fsgnjx_s; break;
1678                }
1679                break;
1680            case 17:
1681                switch (((inst >> 12) & 0b111)) {
1682                case 0: op = rv_op_fsgnj_d; break;
1683                case 1: op = rv_op_fsgnjn_d; break;
1684                case 2: op = rv_op_fsgnjx_d; break;
1685                }
1686                break;
1687            case 19:
1688                switch (((inst >> 12) & 0b111)) {
1689                case 0: op = rv_op_fsgnj_q; break;
1690                case 1: op = rv_op_fsgnjn_q; break;
1691                case 2: op = rv_op_fsgnjx_q; break;
1692                }
1693                break;
1694            case 20:
1695                switch (((inst >> 12) & 0b111)) {
1696                case 0: op = rv_op_fmin_s; break;
1697                case 1: op = rv_op_fmax_s; break;
1698                }
1699                break;
1700            case 21:
1701                switch (((inst >> 12) & 0b111)) {
1702                case 0: op = rv_op_fmin_d; break;
1703                case 1: op = rv_op_fmax_d; break;
1704                }
1705                break;
1706            case 23:
1707                switch (((inst >> 12) & 0b111)) {
1708                case 0: op = rv_op_fmin_q; break;
1709                case 1: op = rv_op_fmax_q; break;
1710                }
1711                break;
1712            case 32:
1713                switch (((inst >> 20) & 0b11111)) {
1714                case 1: op = rv_op_fcvt_s_d; break;
1715                case 3: op = rv_op_fcvt_s_q; break;
1716                }
1717                break;
1718            case 33:
1719                switch (((inst >> 20) & 0b11111)) {
1720                case 0: op = rv_op_fcvt_d_s; break;
1721                case 3: op = rv_op_fcvt_d_q; break;
1722                }
1723                break;
1724            case 35:
1725                switch (((inst >> 20) & 0b11111)) {
1726                case 0: op = rv_op_fcvt_q_s; break;
1727                case 1: op = rv_op_fcvt_q_d; break;
1728                }
1729                break;
1730            case 44:
1731                switch (((inst >> 20) & 0b11111)) {
1732                case 0: op = rv_op_fsqrt_s; break;
1733                }
1734                break;
1735            case 45:
1736                switch (((inst >> 20) & 0b11111)) {
1737                case 0: op = rv_op_fsqrt_d; break;
1738                }
1739                break;
1740            case 47:
1741                switch (((inst >> 20) & 0b11111)) {
1742                case 0: op = rv_op_fsqrt_q; break;
1743                }
1744                break;
1745            case 80:
1746                switch (((inst >> 12) & 0b111)) {
1747                case 0: op = rv_op_fle_s; break;
1748                case 1: op = rv_op_flt_s; break;
1749                case 2: op = rv_op_feq_s; break;
1750                }
1751                break;
1752            case 81:
1753                switch (((inst >> 12) & 0b111)) {
1754                case 0: op = rv_op_fle_d; break;
1755                case 1: op = rv_op_flt_d; break;
1756                case 2: op = rv_op_feq_d; break;
1757                }
1758                break;
1759            case 83:
1760                switch (((inst >> 12) & 0b111)) {
1761                case 0: op = rv_op_fle_q; break;
1762                case 1: op = rv_op_flt_q; break;
1763                case 2: op = rv_op_feq_q; break;
1764                }
1765                break;
1766            case 96:
1767                switch (((inst >> 20) & 0b11111)) {
1768                case 0: op = rv_op_fcvt_w_s; break;
1769                case 1: op = rv_op_fcvt_wu_s; break;
1770                case 2: op = rv_op_fcvt_l_s; break;
1771                case 3: op = rv_op_fcvt_lu_s; break;
1772                }
1773                break;
1774            case 97:
1775                switch (((inst >> 20) & 0b11111)) {
1776                case 0: op = rv_op_fcvt_w_d; break;
1777                case 1: op = rv_op_fcvt_wu_d; break;
1778                case 2: op = rv_op_fcvt_l_d; break;
1779                case 3: op = rv_op_fcvt_lu_d; break;
1780                }
1781                break;
1782            case 99:
1783                switch (((inst >> 20) & 0b11111)) {
1784                case 0: op = rv_op_fcvt_w_q; break;
1785                case 1: op = rv_op_fcvt_wu_q; break;
1786                case 2: op = rv_op_fcvt_l_q; break;
1787                case 3: op = rv_op_fcvt_lu_q; break;
1788                }
1789                break;
1790            case 104:
1791                switch (((inst >> 20) & 0b11111)) {
1792                case 0: op = rv_op_fcvt_s_w; break;
1793                case 1: op = rv_op_fcvt_s_wu; break;
1794                case 2: op = rv_op_fcvt_s_l; break;
1795                case 3: op = rv_op_fcvt_s_lu; break;
1796                }
1797                break;
1798            case 105:
1799                switch (((inst >> 20) & 0b11111)) {
1800                case 0: op = rv_op_fcvt_d_w; break;
1801                case 1: op = rv_op_fcvt_d_wu; break;
1802                case 2: op = rv_op_fcvt_d_l; break;
1803                case 3: op = rv_op_fcvt_d_lu; break;
1804                }
1805                break;
1806            case 107:
1807                switch (((inst >> 20) & 0b11111)) {
1808                case 0: op = rv_op_fcvt_q_w; break;
1809                case 1: op = rv_op_fcvt_q_wu; break;
1810                case 2: op = rv_op_fcvt_q_l; break;
1811                case 3: op = rv_op_fcvt_q_lu; break;
1812                }
1813                break;
1814            case 112:
1815                switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1816                case 0: op = rv_op_fmv_x_s; break;
1817                case 1: op = rv_op_fclass_s; break;
1818                }
1819                break;
1820            case 113:
1821                switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1822                case 0: op = rv_op_fmv_x_d; break;
1823                case 1: op = rv_op_fclass_d; break;
1824                }
1825                break;
1826            case 115:
1827                switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1828                case 0: op = rv_op_fmv_x_q; break;
1829                case 1: op = rv_op_fclass_q; break;
1830                }
1831                break;
1832            case 120:
1833                switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1834                case 0: op = rv_op_fmv_s_x; break;
1835                }
1836                break;
1837            case 121:
1838                switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1839                case 0: op = rv_op_fmv_d_x; break;
1840                }
1841                break;
1842            case 123:
1843                switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1844                case 0: op = rv_op_fmv_q_x; break;
1845                }
1846                break;
1847            }
1848            break;
1849        case 22:
1850            switch (((inst >> 12) & 0b111)) {
1851            case 0: op = rv_op_addid; break;
1852            case 1:
1853                switch (((inst >> 26) & 0b111111)) {
1854                case 0: op = rv_op_sllid; break;
1855                }
1856                break;
1857            case 5:
1858                switch (((inst >> 26) & 0b111111)) {
1859                case 0: op = rv_op_srlid; break;
1860                case 16: op = rv_op_sraid; break;
1861                }
1862                break;
1863            }
1864            break;
1865        case 24:
1866            switch (((inst >> 12) & 0b111)) {
1867            case 0: op = rv_op_beq; break;
1868            case 1: op = rv_op_bne; break;
1869            case 4: op = rv_op_blt; break;
1870            case 5: op = rv_op_bge; break;
1871            case 6: op = rv_op_bltu; break;
1872            case 7: op = rv_op_bgeu; break;
1873            }
1874            break;
1875        case 25:
1876            switch (((inst >> 12) & 0b111)) {
1877            case 0: op = rv_op_jalr; break;
1878            }
1879            break;
1880        case 27: op = rv_op_jal; break;
1881        case 28:
1882            switch (((inst >> 12) & 0b111)) {
1883            case 0:
1884                switch (((inst >> 20) & 0b111111100000) | ((inst >> 7) & 0b000000011111)) {
1885                case 0:
1886                    switch (((inst >> 15) & 0b1111111111)) {
1887                    case 0: op = rv_op_ecall; break;
1888                    case 32: op = rv_op_ebreak; break;
1889                    case 64: op = rv_op_uret; break;
1890                    }
1891                    break;
1892                case 256:
1893                    switch (((inst >> 20) & 0b11111)) {
1894                    case 2:
1895                        switch (((inst >> 15) & 0b11111)) {
1896                        case 0: op = rv_op_sret; break;
1897                        }
1898                        break;
1899                    case 4: op = rv_op_sfence_vm; break;
1900                    case 5:
1901                        switch (((inst >> 15) & 0b11111)) {
1902                        case 0: op = rv_op_wfi; break;
1903                        }
1904                        break;
1905                    }
1906                    break;
1907                case 288: op = rv_op_sfence_vma; break;
1908                case 512:
1909                    switch (((inst >> 15) & 0b1111111111)) {
1910                    case 64: op = rv_op_hret; break;
1911                    }
1912                    break;
1913                case 768:
1914                    switch (((inst >> 15) & 0b1111111111)) {
1915                    case 64: op = rv_op_mret; break;
1916                    }
1917                    break;
1918                case 1952:
1919                    switch (((inst >> 15) & 0b1111111111)) {
1920                    case 576: op = rv_op_dret; break;
1921                    }
1922                    break;
1923                }
1924                break;
1925            case 1: op = rv_op_csrrw; break;
1926            case 2: op = rv_op_csrrs; break;
1927            case 3: op = rv_op_csrrc; break;
1928            case 5: op = rv_op_csrrwi; break;
1929            case 6: op = rv_op_csrrsi; break;
1930            case 7: op = rv_op_csrrci; break;
1931            }
1932            break;
1933        case 30:
1934            switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1935            case 0: op = rv_op_addd; break;
1936            case 1: op = rv_op_slld; break;
1937            case 5: op = rv_op_srld; break;
1938            case 8: op = rv_op_muld; break;
1939            case 12: op = rv_op_divd; break;
1940            case 13: op = rv_op_divud; break;
1941            case 14: op = rv_op_remd; break;
1942            case 15: op = rv_op_remud; break;
1943            case 256: op = rv_op_subd; break;
1944            case 261: op = rv_op_srad; break;
1945            }
1946            break;
1947        }
1948        break;
1949    }
1950    dec->op = op;
1951}
1952
1953/* operand extractors */
1954
1955static uint32_t operand_rd(rv_inst inst)
1956{
1957    return (inst << 52) >> 59;
1958}
1959
1960static uint32_t operand_rs1(rv_inst inst)
1961{
1962    return (inst << 44) >> 59;
1963}
1964
1965static uint32_t operand_rs2(rv_inst inst)
1966{
1967    return (inst << 39) >> 59;
1968}
1969
1970static uint32_t operand_rs3(rv_inst inst)
1971{
1972    return (inst << 32) >> 59;
1973}
1974
1975static uint32_t operand_aq(rv_inst inst)
1976{
1977    return (inst << 37) >> 63;
1978}
1979
1980static uint32_t operand_rl(rv_inst inst)
1981{
1982    return (inst << 38) >> 63;
1983}
1984
1985static uint32_t operand_pred(rv_inst inst)
1986{
1987    return (inst << 36) >> 60;
1988}
1989
1990static uint32_t operand_succ(rv_inst inst)
1991{
1992    return (inst << 40) >> 60;
1993}
1994
1995static uint32_t operand_rm(rv_inst inst)
1996{
1997    return (inst << 49) >> 61;
1998}
1999
2000static uint32_t operand_shamt5(rv_inst inst)
2001{
2002    return (inst << 39) >> 59;
2003}
2004
2005static uint32_t operand_shamt6(rv_inst inst)
2006{
2007    return (inst << 38) >> 58;
2008}
2009
2010static uint32_t operand_shamt7(rv_inst inst)
2011{
2012    return (inst << 37) >> 57;
2013}
2014
2015static uint32_t operand_crdq(rv_inst inst)
2016{
2017    return (inst << 59) >> 61;
2018}
2019
2020static uint32_t operand_crs1q(rv_inst inst)
2021{
2022    return (inst << 54) >> 61;
2023}
2024
2025static uint32_t operand_crs1rdq(rv_inst inst)
2026{
2027    return (inst << 54) >> 61;
2028}
2029
2030static uint32_t operand_crs2q(rv_inst inst)
2031{
2032    return (inst << 59) >> 61;
2033}
2034
2035static uint32_t operand_crd(rv_inst inst)
2036{
2037    return (inst << 52) >> 59;
2038}
2039
2040static uint32_t operand_crs1(rv_inst inst)
2041{
2042    return (inst << 52) >> 59;
2043}
2044
2045static uint32_t operand_crs1rd(rv_inst inst)
2046{
2047    return (inst << 52) >> 59;
2048}
2049
2050static uint32_t operand_crs2(rv_inst inst)
2051{
2052    return (inst << 57) >> 59;
2053}
2054
2055static uint32_t operand_cimmsh5(rv_inst inst)
2056{
2057    return (inst << 57) >> 59;
2058}
2059
2060static uint32_t operand_csr12(rv_inst inst)
2061{
2062    return (inst << 32) >> 52;
2063}
2064
2065static int32_t operand_imm12(rv_inst inst)
2066{
2067    return ((int64_t)inst << 32) >> 52;
2068}
2069
2070static int32_t operand_imm20(rv_inst inst)
2071{
2072    return (((int64_t)inst << 32) >> 44) << 12;
2073}
2074
2075static int32_t operand_jimm20(rv_inst inst)
2076{
2077    return (((int64_t)inst << 32) >> 63) << 20 |
2078        ((inst << 33) >> 54) << 1 |
2079        ((inst << 43) >> 63) << 11 |
2080        ((inst << 44) >> 56) << 12;
2081}
2082
2083static int32_t operand_simm12(rv_inst inst)
2084{
2085    return (((int64_t)inst << 32) >> 57) << 5 |
2086        (inst << 52) >> 59;
2087}
2088
2089static int32_t operand_sbimm12(rv_inst inst)
2090{
2091    return (((int64_t)inst << 32) >> 63) << 12 |
2092        ((inst << 33) >> 58) << 5 |
2093        ((inst << 52) >> 60) << 1 |
2094        ((inst << 56) >> 63) << 11;
2095}
2096
2097static uint32_t operand_cimmsh6(rv_inst inst)
2098{
2099    return ((inst << 51) >> 63) << 5 |
2100        (inst << 57) >> 59;
2101}
2102
2103static int32_t operand_cimmi(rv_inst inst)
2104{
2105    return (((int64_t)inst << 51) >> 63) << 5 |
2106        (inst << 57) >> 59;
2107}
2108
2109static int32_t operand_cimmui(rv_inst inst)
2110{
2111    return (((int64_t)inst << 51) >> 63) << 17 |
2112        ((inst << 57) >> 59) << 12;
2113}
2114
2115static uint32_t operand_cimmlwsp(rv_inst inst)
2116{
2117    return ((inst << 51) >> 63) << 5 |
2118        ((inst << 57) >> 61) << 2 |
2119        ((inst << 60) >> 62) << 6;
2120}
2121
2122static uint32_t operand_cimmldsp(rv_inst inst)
2123{
2124    return ((inst << 51) >> 63) << 5 |
2125        ((inst << 57) >> 62) << 3 |
2126        ((inst << 59) >> 61) << 6;
2127}
2128
2129static uint32_t operand_cimmlqsp(rv_inst inst)
2130{
2131    return ((inst << 51) >> 63) << 5 |
2132        ((inst << 57) >> 63) << 4 |
2133        ((inst << 58) >> 60) << 6;
2134}
2135
2136static int32_t operand_cimm16sp(rv_inst inst)
2137{
2138    return (((int64_t)inst << 51) >> 63) << 9 |
2139        ((inst << 57) >> 63) << 4 |
2140        ((inst << 58) >> 63) << 6 |
2141        ((inst << 59) >> 62) << 7 |
2142        ((inst << 61) >> 63) << 5;
2143}
2144
2145static int32_t operand_cimmj(rv_inst inst)
2146{
2147    return (((int64_t)inst << 51) >> 63) << 11 |
2148        ((inst << 52) >> 63) << 4 |
2149        ((inst << 53) >> 62) << 8 |
2150        ((inst << 55) >> 63) << 10 |
2151        ((inst << 56) >> 63) << 6 |
2152        ((inst << 57) >> 63) << 7 |
2153        ((inst << 58) >> 61) << 1 |
2154        ((inst << 61) >> 63) << 5;
2155}
2156
2157static int32_t operand_cimmb(rv_inst inst)
2158{
2159    return (((int64_t)inst << 51) >> 63) << 8 |
2160        ((inst << 52) >> 62) << 3 |
2161        ((inst << 57) >> 62) << 6 |
2162        ((inst << 59) >> 62) << 1 |
2163        ((inst << 61) >> 63) << 5;
2164}
2165
2166static uint32_t operand_cimmswsp(rv_inst inst)
2167{
2168    return ((inst << 51) >> 60) << 2 |
2169        ((inst << 55) >> 62) << 6;
2170}
2171
2172static uint32_t operand_cimmsdsp(rv_inst inst)
2173{
2174    return ((inst << 51) >> 61) << 3 |
2175        ((inst << 54) >> 61) << 6;
2176}
2177
2178static uint32_t operand_cimmsqsp(rv_inst inst)
2179{
2180    return ((inst << 51) >> 62) << 4 |
2181        ((inst << 53) >> 60) << 6;
2182}
2183
2184static uint32_t operand_cimm4spn(rv_inst inst)
2185{
2186    return ((inst << 51) >> 62) << 4 |
2187        ((inst << 53) >> 60) << 6 |
2188        ((inst << 57) >> 63) << 2 |
2189        ((inst << 58) >> 63) << 3;
2190}
2191
2192static uint32_t operand_cimmw(rv_inst inst)
2193{
2194    return ((inst << 51) >> 61) << 3 |
2195        ((inst << 57) >> 63) << 2 |
2196        ((inst << 58) >> 63) << 6;
2197}
2198
2199static uint32_t operand_cimmd(rv_inst inst)
2200{
2201    return ((inst << 51) >> 61) << 3 |
2202        ((inst << 57) >> 62) << 6;
2203}
2204
2205static uint32_t operand_cimmq(rv_inst inst)
2206{
2207    return ((inst << 51) >> 62) << 4 |
2208        ((inst << 53) >> 63) << 8 |
2209        ((inst << 57) >> 62) << 6;
2210}
2211
2212/* decode operands */
2213
2214static void decode_inst_operands(rv_decode *dec)
2215{
2216    rv_inst inst = dec->inst;
2217    dec->codec = opcode_data[dec->op].codec;
2218    switch (dec->codec) {
2219    case rv_codec_none:
2220        dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2221        dec->imm = 0;
2222        break;
2223    case rv_codec_u:
2224        dec->rd = operand_rd(inst);
2225        dec->rs1 = dec->rs2 = rv_ireg_zero;
2226        dec->imm = operand_imm20(inst);
2227        break;
2228    case rv_codec_uj:
2229        dec->rd = operand_rd(inst);
2230        dec->rs1 = dec->rs2 = rv_ireg_zero;
2231        dec->imm = operand_jimm20(inst);
2232        break;
2233    case rv_codec_i:
2234        dec->rd = operand_rd(inst);
2235        dec->rs1 = operand_rs1(inst);
2236        dec->rs2 = rv_ireg_zero;
2237        dec->imm = operand_imm12(inst);
2238        break;
2239    case rv_codec_i_sh5:
2240        dec->rd = operand_rd(inst);
2241        dec->rs1 = operand_rs1(inst);
2242        dec->rs2 = rv_ireg_zero;
2243        dec->imm = operand_shamt5(inst);
2244        break;
2245    case rv_codec_i_sh6:
2246        dec->rd = operand_rd(inst);
2247        dec->rs1 = operand_rs1(inst);
2248        dec->rs2 = rv_ireg_zero;
2249        dec->imm = operand_shamt6(inst);
2250        break;
2251    case rv_codec_i_sh7:
2252        dec->rd = operand_rd(inst);
2253        dec->rs1 = operand_rs1(inst);
2254        dec->rs2 = rv_ireg_zero;
2255        dec->imm = operand_shamt7(inst);
2256        break;
2257    case rv_codec_i_csr:
2258        dec->rd = operand_rd(inst);
2259        dec->rs1 = operand_rs1(inst);
2260        dec->rs2 = rv_ireg_zero;
2261        dec->imm = operand_csr12(inst);
2262        break;
2263    case rv_codec_s:
2264        dec->rd = rv_ireg_zero;
2265        dec->rs1 = operand_rs1(inst);
2266        dec->rs2 = operand_rs2(inst);
2267        dec->imm = operand_simm12(inst);
2268        break;
2269    case rv_codec_sb:
2270        dec->rd = rv_ireg_zero;
2271        dec->rs1 = operand_rs1(inst);
2272        dec->rs2 = operand_rs2(inst);
2273        dec->imm = operand_sbimm12(inst);
2274        break;
2275    case rv_codec_r:
2276        dec->rd = operand_rd(inst);
2277        dec->rs1 = operand_rs1(inst);
2278        dec->rs2 = operand_rs2(inst);
2279        dec->imm = 0;
2280        break;
2281    case rv_codec_r_m:
2282        dec->rd = operand_rd(inst);
2283        dec->rs1 = operand_rs1(inst);
2284        dec->rs2 = operand_rs2(inst);
2285        dec->imm = 0;
2286        dec->rm = operand_rm(inst);
2287        break;
2288    case rv_codec_r4_m:
2289        dec->rd = operand_rd(inst);
2290        dec->rs1 = operand_rs1(inst);
2291        dec->rs2 = operand_rs2(inst);
2292        dec->rs3 = operand_rs3(inst);
2293        dec->imm = 0;
2294        dec->rm = operand_rm(inst);
2295        break;
2296    case rv_codec_r_a:
2297        dec->rd = operand_rd(inst);
2298        dec->rs1 = operand_rs1(inst);
2299        dec->rs2 = operand_rs2(inst);
2300        dec->imm = 0;
2301        dec->aq = operand_aq(inst);
2302        dec->rl = operand_rl(inst);
2303        break;
2304    case rv_codec_r_l:
2305        dec->rd = operand_rd(inst);
2306        dec->rs1 = operand_rs1(inst);
2307        dec->rs2 = rv_ireg_zero;
2308        dec->imm = 0;
2309        dec->aq = operand_aq(inst);
2310        dec->rl = operand_rl(inst);
2311        break;
2312    case rv_codec_r_f:
2313        dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2314        dec->pred = operand_pred(inst);
2315        dec->succ = operand_succ(inst);
2316        dec->imm = 0;
2317        break;
2318    case rv_codec_cb:
2319        dec->rd = rv_ireg_zero;
2320        dec->rs1 = operand_crs1q(inst) + 8;
2321        dec->rs2 = rv_ireg_zero;
2322        dec->imm = operand_cimmb(inst);
2323        break;
2324    case rv_codec_cb_imm:
2325        dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2326        dec->rs2 = rv_ireg_zero;
2327        dec->imm = operand_cimmi(inst);
2328        break;
2329    case rv_codec_cb_sh5:
2330        dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2331        dec->rs2 = rv_ireg_zero;
2332        dec->imm = operand_cimmsh5(inst);
2333        break;
2334    case rv_codec_cb_sh6:
2335        dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2336        dec->rs2 = rv_ireg_zero;
2337        dec->imm = operand_cimmsh6(inst);
2338        break;
2339    case rv_codec_ci:
2340        dec->rd = dec->rs1 = operand_crs1rd(inst);
2341        dec->rs2 = rv_ireg_zero;
2342        dec->imm = operand_cimmi(inst);
2343        break;
2344    case rv_codec_ci_sh5:
2345        dec->rd = dec->rs1 = operand_crs1rd(inst);
2346        dec->rs2 = rv_ireg_zero;
2347        dec->imm = operand_cimmsh5(inst);
2348        break;
2349    case rv_codec_ci_sh6:
2350        dec->rd = dec->rs1 = operand_crs1rd(inst);
2351        dec->rs2 = rv_ireg_zero;
2352        dec->imm = operand_cimmsh6(inst);
2353        break;
2354    case rv_codec_ci_16sp:
2355        dec->rd = rv_ireg_sp;
2356        dec->rs1 = rv_ireg_sp;
2357        dec->rs2 = rv_ireg_zero;
2358        dec->imm = operand_cimm16sp(inst);
2359        break;
2360    case rv_codec_ci_lwsp:
2361        dec->rd = operand_crd(inst);
2362        dec->rs1 = rv_ireg_sp;
2363        dec->rs2 = rv_ireg_zero;
2364        dec->imm = operand_cimmlwsp(inst);
2365        break;
2366    case rv_codec_ci_ldsp:
2367        dec->rd = operand_crd(inst);
2368        dec->rs1 = rv_ireg_sp;
2369        dec->rs2 = rv_ireg_zero;
2370        dec->imm = operand_cimmldsp(inst);
2371        break;
2372    case rv_codec_ci_lqsp:
2373        dec->rd = operand_crd(inst);
2374        dec->rs1 = rv_ireg_sp;
2375        dec->rs2 = rv_ireg_zero;
2376        dec->imm = operand_cimmlqsp(inst);
2377        break;
2378    case rv_codec_ci_li:
2379        dec->rd = operand_crd(inst);
2380        dec->rs1 = rv_ireg_zero;
2381        dec->rs2 = rv_ireg_zero;
2382        dec->imm = operand_cimmi(inst);
2383        break;
2384    case rv_codec_ci_lui:
2385        dec->rd = operand_crd(inst);
2386        dec->rs1 = rv_ireg_zero;
2387        dec->rs2 = rv_ireg_zero;
2388        dec->imm = operand_cimmui(inst);
2389        break;
2390    case rv_codec_ci_none:
2391        dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2392        dec->imm = 0;
2393        break;
2394    case rv_codec_ciw_4spn:
2395        dec->rd = operand_crdq(inst) + 8;
2396        dec->rs1 = rv_ireg_sp;
2397        dec->rs2 = rv_ireg_zero;
2398        dec->imm = operand_cimm4spn(inst);
2399        break;
2400    case rv_codec_cj:
2401        dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2402        dec->imm = operand_cimmj(inst);
2403        break;
2404    case rv_codec_cj_jal:
2405        dec->rd = rv_ireg_ra;
2406        dec->rs1 = dec->rs2 = rv_ireg_zero;
2407        dec->imm = operand_cimmj(inst);
2408        break;
2409    case rv_codec_cl_lw:
2410        dec->rd = operand_crdq(inst) + 8;
2411        dec->rs1 = operand_crs1q(inst) + 8;
2412        dec->rs2 = rv_ireg_zero;
2413        dec->imm = operand_cimmw(inst);
2414        break;
2415    case rv_codec_cl_ld:
2416        dec->rd = operand_crdq(inst) + 8;
2417        dec->rs1 = operand_crs1q(inst) + 8;
2418        dec->rs2 = rv_ireg_zero;
2419        dec->imm = operand_cimmd(inst);
2420        break;
2421    case rv_codec_cl_lq:
2422        dec->rd = operand_crdq(inst) + 8;
2423        dec->rs1 = operand_crs1q(inst) + 8;
2424        dec->rs2 = rv_ireg_zero;
2425        dec->imm = operand_cimmq(inst);
2426        break;
2427    case rv_codec_cr:
2428        dec->rd = dec->rs1 = operand_crs1rd(inst);
2429        dec->rs2 = operand_crs2(inst);
2430        dec->imm = 0;
2431        break;
2432    case rv_codec_cr_mv:
2433        dec->rd = operand_crd(inst);
2434        dec->rs1 = operand_crs2(inst);
2435        dec->rs2 = rv_ireg_zero;
2436        dec->imm = 0;
2437        break;
2438    case rv_codec_cr_jalr:
2439        dec->rd = rv_ireg_ra;
2440        dec->rs1 = operand_crs1(inst);
2441        dec->rs2 = rv_ireg_zero;
2442        dec->imm = 0;
2443        break;
2444    case rv_codec_cr_jr:
2445        dec->rd = rv_ireg_zero;
2446        dec->rs1 = operand_crs1(inst);
2447        dec->rs2 = rv_ireg_zero;
2448        dec->imm = 0;
2449        break;
2450    case rv_codec_cs:
2451        dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2452        dec->rs2 = operand_crs2q(inst) + 8;
2453        dec->imm = 0;
2454        break;
2455    case rv_codec_cs_sw:
2456        dec->rd = rv_ireg_zero;
2457        dec->rs1 = operand_crs1q(inst) + 8;
2458        dec->rs2 = operand_crs2q(inst) + 8;
2459        dec->imm = operand_cimmw(inst);
2460        break;
2461    case rv_codec_cs_sd:
2462        dec->rd = rv_ireg_zero;
2463        dec->rs1 = operand_crs1q(inst) + 8;
2464        dec->rs2 = operand_crs2q(inst) + 8;
2465        dec->imm = operand_cimmd(inst);
2466        break;
2467    case rv_codec_cs_sq:
2468        dec->rd = rv_ireg_zero;
2469        dec->rs1 = operand_crs1q(inst) + 8;
2470        dec->rs2 = operand_crs2q(inst) + 8;
2471        dec->imm = operand_cimmq(inst);
2472        break;
2473    case rv_codec_css_swsp:
2474        dec->rd = rv_ireg_zero;
2475        dec->rs1 = rv_ireg_sp;
2476        dec->rs2 = operand_crs2(inst);
2477        dec->imm = operand_cimmswsp(inst);
2478        break;
2479    case rv_codec_css_sdsp:
2480        dec->rd = rv_ireg_zero;
2481        dec->rs1 = rv_ireg_sp;
2482        dec->rs2 = operand_crs2(inst);
2483        dec->imm = operand_cimmsdsp(inst);
2484        break;
2485    case rv_codec_css_sqsp:
2486        dec->rd = rv_ireg_zero;
2487        dec->rs1 = rv_ireg_sp;
2488        dec->rs2 = operand_crs2(inst);
2489        dec->imm = operand_cimmsqsp(inst);
2490        break;
2491    };
2492}
2493
2494/* check constraint */
2495
2496static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
2497{
2498    int32_t imm = dec->imm;
2499    uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
2500    while (*c != rvc_end) {
2501        switch (*c) {
2502        case rvc_rd_eq_ra:
2503            if (!(rd == 1)) {
2504                return false;
2505            }
2506            break;
2507        case rvc_rd_eq_x0:
2508            if (!(rd == 0)) {
2509                return false;
2510            }
2511            break;
2512        case rvc_rs1_eq_x0:
2513            if (!(rs1 == 0)) {
2514                return false;
2515            }
2516            break;
2517        case rvc_rs2_eq_x0:
2518            if (!(rs2 == 0)) {
2519                return false;
2520            }
2521            break;
2522        case rvc_rs2_eq_rs1:
2523            if (!(rs2 == rs1)) {
2524                return false;
2525            }
2526            break;
2527        case rvc_rs1_eq_ra:
2528            if (!(rs1 == 1)) {
2529                return false;
2530            }
2531            break;
2532        case rvc_imm_eq_zero:
2533            if (!(imm == 0)) {
2534                return false;
2535            }
2536            break;
2537        case rvc_imm_eq_n1:
2538            if (!(imm == -1)) {
2539                return false;
2540            }
2541            break;
2542        case rvc_imm_eq_p1:
2543            if (!(imm == 1)) {
2544                return false;
2545            }
2546            break;
2547        case rvc_csr_eq_0x001:
2548            if (!(imm == 0x001)) {
2549                return false;
2550            }
2551            break;
2552        case rvc_csr_eq_0x002:
2553            if (!(imm == 0x002)) {
2554                return false;
2555            }
2556            break;
2557        case rvc_csr_eq_0x003:
2558            if (!(imm == 0x003)) {
2559                return false;
2560            }
2561            break;
2562        case rvc_csr_eq_0xc00:
2563            if (!(imm == 0xc00)) {
2564                return false;
2565            }
2566            break;
2567        case rvc_csr_eq_0xc01:
2568            if (!(imm == 0xc01)) {
2569                return false;
2570            }
2571            break;
2572        case rvc_csr_eq_0xc02:
2573            if (!(imm == 0xc02)) {
2574                return false;
2575            }
2576            break;
2577        case rvc_csr_eq_0xc80:
2578            if (!(imm == 0xc80)) {
2579                return false;
2580            }
2581            break;
2582        case rvc_csr_eq_0xc81:
2583            if (!(imm == 0xc81)) {
2584                return false;
2585            }
2586            break;
2587        case rvc_csr_eq_0xc82:
2588            if (!(imm == 0xc82)) {
2589                return false;
2590            }
2591            break;
2592        default: break;
2593        }
2594        c++;
2595    }
2596    return true;
2597}
2598
2599/* instruction length */
2600
2601static size_t inst_length(rv_inst inst)
2602{
2603    /* NOTE: supports maximum instruction size of 64-bits */
2604
2605    /* instruction length coding
2606     *
2607     *      aa - 16 bit aa != 11
2608     *   bbb11 - 32 bit bbb != 111
2609     *  011111 - 48 bit
2610     * 0111111 - 64 bit
2611     */
2612
2613    return (inst &      0b11) != 0b11      ? 2
2614         : (inst &   0b11100) != 0b11100   ? 4
2615         : (inst &  0b111111) == 0b011111  ? 6
2616         : (inst & 0b1111111) == 0b0111111 ? 8
2617         : 0;
2618}
2619
2620/* format instruction */
2621
2622static void append(char *s1, const char *s2, size_t n)
2623{
2624    size_t l1 = strlen(s1);
2625    if (n - l1 - 1 > 0) {
2626        strncat(s1, s2, n - l1);
2627    }
2628}
2629
2630static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
2631{
2632    char tmp[64];
2633    const char *fmt;
2634
2635    fmt = opcode_data[dec->op].format;
2636    while (*fmt) {
2637        switch (*fmt) {
2638        case 'O':
2639            append(buf, opcode_data[dec->op].name, buflen);
2640            break;
2641        case '(':
2642            append(buf, "(", buflen);
2643            break;
2644        case ',':
2645            append(buf, ",", buflen);
2646            break;
2647        case ')':
2648            append(buf, ")", buflen);
2649            break;
2650        case '0':
2651            append(buf, rv_ireg_name_sym[dec->rd], buflen);
2652            break;
2653        case '1':
2654            append(buf, rv_ireg_name_sym[dec->rs1], buflen);
2655            break;
2656        case '2':
2657            append(buf, rv_ireg_name_sym[dec->rs2], buflen);
2658            break;
2659        case '3':
2660            append(buf, rv_freg_name_sym[dec->rd], buflen);
2661            break;
2662        case '4':
2663            append(buf, rv_freg_name_sym[dec->rs1], buflen);
2664            break;
2665        case '5':
2666            append(buf, rv_freg_name_sym[dec->rs2], buflen);
2667            break;
2668        case '6':
2669            append(buf, rv_freg_name_sym[dec->rs3], buflen);
2670            break;
2671        case '7':
2672            snprintf(tmp, sizeof(tmp), "%d", dec->rs1);
2673            append(buf, tmp, buflen);
2674            break;
2675        case 'i':
2676            snprintf(tmp, sizeof(tmp), "%d", dec->imm);
2677            append(buf, tmp, buflen);
2678            break;
2679        case 'o':
2680            snprintf(tmp, sizeof(tmp), "%d", dec->imm);
2681            append(buf, tmp, buflen);
2682            while (strlen(buf) < tab * 2) {
2683                append(buf, " ", buflen);
2684            }
2685            snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
2686                dec->pc + dec->imm);
2687            append(buf, tmp, buflen);
2688            break;
2689        case 'c': {
2690            const char *name = csr_name(dec->imm & 0xfff);
2691            if (name) {
2692                append(buf, name, buflen);
2693            } else {
2694                snprintf(tmp, sizeof(tmp), "0x%03x", dec->imm & 0xfff);
2695                append(buf, tmp, buflen);
2696            }
2697            break;
2698        }
2699        case 'r':
2700            switch (dec->rm) {
2701            case rv_rm_rne:
2702                append(buf, "rne", buflen);
2703                break;
2704            case rv_rm_rtz:
2705                append(buf, "rtz", buflen);
2706                break;
2707            case rv_rm_rdn:
2708                append(buf, "rdn", buflen);
2709                break;
2710            case rv_rm_rup:
2711                append(buf, "rup", buflen);
2712                break;
2713            case rv_rm_rmm:
2714                append(buf, "rmm", buflen);
2715                break;
2716            case rv_rm_dyn:
2717                append(buf, "dyn", buflen);
2718                break;
2719            default:
2720                append(buf, "inv", buflen);
2721                break;
2722            }
2723            break;
2724        case 'p':
2725            if (dec->pred & rv_fence_i) {
2726                append(buf, "i", buflen);
2727            }
2728            if (dec->pred & rv_fence_o) {
2729                append(buf, "o", buflen);
2730            }
2731            if (dec->pred & rv_fence_r) {
2732                append(buf, "r", buflen);
2733            }
2734            if (dec->pred & rv_fence_w) {
2735                append(buf, "w", buflen);
2736            }
2737            break;
2738        case 's':
2739            if (dec->succ & rv_fence_i) {
2740                append(buf, "i", buflen);
2741            }
2742            if (dec->succ & rv_fence_o) {
2743                append(buf, "o", buflen);
2744            }
2745            if (dec->succ & rv_fence_r) {
2746                append(buf, "r", buflen);
2747            }
2748            if (dec->succ & rv_fence_w) {
2749                append(buf, "w", buflen);
2750            }
2751            break;
2752        case '\t':
2753            while (strlen(buf) < tab) {
2754                append(buf, " ", buflen);
2755            }
2756            break;
2757        case 'A':
2758            if (dec->aq) {
2759                append(buf, ".aq", buflen);
2760            }
2761            break;
2762        case 'R':
2763            if (dec->rl) {
2764                append(buf, ".rl", buflen);
2765            }
2766            break;
2767        default:
2768            break;
2769        }
2770        fmt++;
2771    }
2772}
2773
2774/* lift instruction to pseudo-instruction */
2775
2776static void decode_inst_lift_pseudo(rv_decode *dec)
2777{
2778    const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
2779    if (!comp_data) {
2780        return;
2781    }
2782    while (comp_data->constraints) {
2783        if (check_constraints(dec, comp_data->constraints)) {
2784            dec->op = comp_data->op;
2785            dec->codec = opcode_data[dec->op].codec;
2786            return;
2787        }
2788        comp_data++;
2789    }
2790}
2791
2792/* decompress instruction */
2793
2794static void decode_inst_decompress_rv32(rv_decode *dec)
2795{
2796    int decomp_op = opcode_data[dec->op].decomp_rv32;
2797    if (decomp_op != rv_op_illegal) {
2798        dec->op = decomp_op;
2799        dec->codec = opcode_data[decomp_op].codec;
2800    }
2801}
2802
2803static void decode_inst_decompress_rv64(rv_decode *dec)
2804{
2805    int decomp_op = opcode_data[dec->op].decomp_rv64;
2806    if (decomp_op != rv_op_illegal) {
2807        dec->op = decomp_op;
2808        dec->codec = opcode_data[decomp_op].codec;
2809    }
2810}
2811
2812static void decode_inst_decompress_rv128(rv_decode *dec)
2813{
2814    int decomp_op = opcode_data[dec->op].decomp_rv128;
2815    if (decomp_op != rv_op_illegal) {
2816        dec->op = decomp_op;
2817        dec->codec = opcode_data[decomp_op].codec;
2818    }
2819}
2820
2821static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
2822{
2823    switch (isa) {
2824    case rv32:
2825        decode_inst_decompress_rv32(dec);
2826        break;
2827    case rv64:
2828        decode_inst_decompress_rv64(dec);
2829        break;
2830    case rv128:
2831        decode_inst_decompress_rv128(dec);
2832        break;
2833    }
2834}
2835
2836/* disassemble instruction */
2837
2838static void
2839disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
2840{
2841    rv_decode dec = { 0 };
2842    dec.pc = pc;
2843    dec.inst = inst;
2844    decode_inst_opcode(&dec, isa);
2845    decode_inst_operands(&dec);
2846    decode_inst_decompress(&dec, isa);
2847    decode_inst_lift_pseudo(&dec);
2848    format_inst(buf, buflen, 16, &dec);
2849}
2850
2851#define INST_FMT_2 "%04" PRIx64 "              "
2852#define INST_FMT_4 "%08" PRIx64 "          "
2853#define INST_FMT_6 "%012" PRIx64 "      "
2854#define INST_FMT_8 "%016" PRIx64 "  "
2855
2856static int
2857print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
2858{
2859    char buf[128] = { 0 };
2860    bfd_byte packet[2];
2861    rv_inst inst = 0;
2862    size_t len = 2;
2863    bfd_vma n;
2864    int status;
2865
2866    /* Instructions are made of 2-byte packets in little-endian order */
2867    for (n = 0; n < len; n += 2) {
2868        status = (*info->read_memory_func)(memaddr + n, packet, 2, info);
2869        if (status != 0) {
2870            /* Don't fail just because we fell off the end.  */
2871            if (n > 0) {
2872                break;
2873            }
2874            (*info->memory_error_func)(status, memaddr, info);
2875            return status;
2876        }
2877        inst |= ((rv_inst) bfd_getl16(packet)) << (8 * n);
2878        if (n == 0) {
2879            len = inst_length(inst);
2880        }
2881    }
2882
2883    switch (len) {
2884    case 2:
2885        (*info->fprintf_func)(info->stream, INST_FMT_2, inst);
2886        break;
2887    case 4:
2888        (*info->fprintf_func)(info->stream, INST_FMT_4, inst);
2889        break;
2890    case 6:
2891        (*info->fprintf_func)(info->stream, INST_FMT_6, inst);
2892        break;
2893    default:
2894        (*info->fprintf_func)(info->stream, INST_FMT_8, inst);
2895        break;
2896    }
2897
2898    disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
2899    (*info->fprintf_func)(info->stream, "%s", buf);
2900
2901    return len;
2902}
2903
2904int print_insn_riscv32(bfd_vma memaddr, struct disassemble_info *info)
2905{
2906    return print_insn_riscv(memaddr, info, rv32);
2907}
2908
2909int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info)
2910{
2911    return print_insn_riscv(memaddr, info, rv64);
2912}
2913