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