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