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