xref: /qemu/disas/riscv.c (revision b88651cb)
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 
26 typedef uint64_t rv_inst;
27 typedef uint16_t rv_opcode;
28 
29 /* enums */
30 
31 typedef enum {
32     rv32,
33     rv64,
34     rv128
35 } rv_isa;
36 
37 typedef 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 
46 typedef 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 
53 typedef 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 
88 typedef 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 
110 typedef 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 
163 typedef 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 
567 typedef 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 
586 typedef struct {
587     const int op;
588     const rvc_constraint *constraints;
589 } rv_comp_data;
590 
591 enum {
592     rvcd_imm_nz = 0x1
593 };
594 
595 typedef 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 
608 static const char rv_ireg_name_sym[32][5] = {
609     "zero", "ra",   "sp",   "gp",   "tp",   "t0",   "t1",   "t2",
610     "s0",   "s1",   "a0",   "a1",   "a2",   "a3",   "a4",   "a5",
611     "a6",   "a7",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
612     "s8",   "s9",   "s10",  "s11",  "t3",   "t4",   "t5",   "t6",
613 };
614 
615 static const char rv_freg_name_sym[32][5] = {
616     "ft0",  "ft1",  "ft2",  "ft3",  "ft4",  "ft5",  "ft6",  "ft7",
617     "fs0",  "fs1",  "fa0",  "fa1",  "fa2",  "fa3",  "fa4",  "fa5",
618     "fa6",  "fa7",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7",
619     "fs8",  "fs9",  "fs10", "fs11", "ft8",  "ft9",  "ft10", "ft11",
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 
664 static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
665 static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, rvc_end };
666 static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, rvc_imm_eq_zero, rvc_end };
667 static const rvc_constraint rvcc_mv[] = { rvc_imm_eq_zero, rvc_end };
668 static const rvc_constraint rvcc_not[] = { rvc_imm_eq_n1, rvc_end };
669 static const rvc_constraint rvcc_neg[] = { rvc_rs1_eq_x0, rvc_end };
670 static const rvc_constraint rvcc_negw[] = { rvc_rs1_eq_x0, rvc_end };
671 static const rvc_constraint rvcc_sext_w[] = { rvc_imm_eq_zero, rvc_end };
672 static const rvc_constraint rvcc_seqz[] = { rvc_imm_eq_p1, rvc_end };
673 static const rvc_constraint rvcc_snez[] = { rvc_rs1_eq_x0, rvc_end };
674 static const rvc_constraint rvcc_sltz[] = { rvc_rs2_eq_x0, rvc_end };
675 static const rvc_constraint rvcc_sgtz[] = { rvc_rs1_eq_x0, rvc_end };
676 static const rvc_constraint rvcc_fmv_s[] = { rvc_rs2_eq_rs1, rvc_end };
677 static const rvc_constraint rvcc_fabs_s[] = { rvc_rs2_eq_rs1, rvc_end };
678 static const rvc_constraint rvcc_fneg_s[] = { rvc_rs2_eq_rs1, rvc_end };
679 static const rvc_constraint rvcc_fmv_d[] = { rvc_rs2_eq_rs1, rvc_end };
680 static const rvc_constraint rvcc_fabs_d[] = { rvc_rs2_eq_rs1, rvc_end };
681 static const rvc_constraint rvcc_fneg_d[] = { rvc_rs2_eq_rs1, rvc_end };
682 static const rvc_constraint rvcc_fmv_q[] = { rvc_rs2_eq_rs1, rvc_end };
683 static const rvc_constraint rvcc_fabs_q[] = { rvc_rs2_eq_rs1, rvc_end };
684 static const rvc_constraint rvcc_fneg_q[] = { rvc_rs2_eq_rs1, rvc_end };
685 static const rvc_constraint rvcc_beqz[] = { rvc_rs2_eq_x0, rvc_end };
686 static const rvc_constraint rvcc_bnez[] = { rvc_rs2_eq_x0, rvc_end };
687 static const rvc_constraint rvcc_blez[] = { rvc_rs1_eq_x0, rvc_end };
688 static const rvc_constraint rvcc_bgez[] = { rvc_rs2_eq_x0, rvc_end };
689 static const rvc_constraint rvcc_bltz[] = { rvc_rs2_eq_x0, rvc_end };
690 static const rvc_constraint rvcc_bgtz[] = { rvc_rs1_eq_x0, rvc_end };
691 static const rvc_constraint rvcc_ble[] = { rvc_end };
692 static const rvc_constraint rvcc_bleu[] = { rvc_end };
693 static const rvc_constraint rvcc_bgt[] = { rvc_end };
694 static const rvc_constraint rvcc_bgtu[] = { rvc_end };
695 static const rvc_constraint rvcc_j[] = { rvc_rd_eq_x0, rvc_end };
696 static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, rvc_end };
697 static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, rvc_end };
698 static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00, rvc_end };
699 static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, rvc_end };
700 static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
701 static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
702 static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
703 static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0,
704                                                   rvc_csr_eq_0xc82, rvc_end };
705 static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
706 static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
707 static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
708 static const rvc_constraint rvcc_fscsr[] = { rvc_csr_eq_0x003, rvc_end };
709 static const rvc_constraint rvcc_fsrm[] = { rvc_csr_eq_0x002, rvc_end };
710 static const rvc_constraint rvcc_fsflags[] = { rvc_csr_eq_0x001, rvc_end };
711 static const rvc_constraint rvcc_fsrmi[] = { rvc_csr_eq_0x002, rvc_end };
712 static const rvc_constraint rvcc_fsflagsi[] = { rvc_csr_eq_0x001, rvc_end };
713 
714 /* pseudo-instruction metadata */
715 
716 static 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 
722 static const rv_comp_data rvcp_jalr[] = {
723     { rv_op_ret, rvcc_ret },
724     { rv_op_jr, rvcc_jr },
725     { rv_op_jalr, rvcc_jalr },
726     { rv_op_illegal, NULL }
727 };
728 
729 static const rv_comp_data rvcp_beq[] = {
730     { rv_op_beqz, rvcc_beqz },
731     { rv_op_illegal, NULL }
732 };
733 
734 static const rv_comp_data rvcp_bne[] = {
735     { rv_op_bnez, rvcc_bnez },
736     { rv_op_illegal, NULL }
737 };
738 
739 static const rv_comp_data rvcp_blt[] = {
740     { rv_op_bltz, rvcc_bltz },
741     { rv_op_bgtz, rvcc_bgtz },
742     { rv_op_bgt, rvcc_bgt },
743     { rv_op_illegal, NULL }
744 };
745 
746 static const rv_comp_data rvcp_bge[] = {
747     { rv_op_blez, rvcc_blez },
748     { rv_op_bgez, rvcc_bgez },
749     { rv_op_ble, rvcc_ble },
750     { rv_op_illegal, NULL }
751 };
752 
753 static const rv_comp_data rvcp_bltu[] = {
754     { rv_op_bgtu, rvcc_bgtu },
755     { rv_op_illegal, NULL }
756 };
757 
758 static const rv_comp_data rvcp_bgeu[] = {
759     { rv_op_bleu, rvcc_bleu },
760     { rv_op_illegal, NULL }
761 };
762 
763 static const rv_comp_data rvcp_addi[] = {
764     { rv_op_nop, rvcc_nop },
765     { rv_op_mv, rvcc_mv },
766     { rv_op_illegal, NULL }
767 };
768 
769 static const rv_comp_data rvcp_sltiu[] = {
770     { rv_op_seqz, rvcc_seqz },
771     { rv_op_illegal, NULL }
772 };
773 
774 static const rv_comp_data rvcp_xori[] = {
775     { rv_op_not, rvcc_not },
776     { rv_op_illegal, NULL }
777 };
778 
779 static const rv_comp_data rvcp_sub[] = {
780     { rv_op_neg, rvcc_neg },
781     { rv_op_illegal, NULL }
782 };
783 
784 static const rv_comp_data rvcp_slt[] = {
785     { rv_op_sltz, rvcc_sltz },
786     { rv_op_sgtz, rvcc_sgtz },
787     { rv_op_illegal, NULL }
788 };
789 
790 static const rv_comp_data rvcp_sltu[] = {
791     { rv_op_snez, rvcc_snez },
792     { rv_op_illegal, NULL }
793 };
794 
795 static const rv_comp_data rvcp_addiw[] = {
796     { rv_op_sext_w, rvcc_sext_w },
797     { rv_op_illegal, NULL }
798 };
799 
800 static const rv_comp_data rvcp_subw[] = {
801     { rv_op_negw, rvcc_negw },
802     { rv_op_illegal, NULL }
803 };
804 
805 static const rv_comp_data rvcp_csrrw[] = {
806     { rv_op_fscsr, rvcc_fscsr },
807     { rv_op_fsrm, rvcc_fsrm },
808     { rv_op_fsflags, rvcc_fsflags },
809     { rv_op_illegal, NULL }
810 };
811 
812 
813 static const rv_comp_data rvcp_csrrs[] = {
814     { rv_op_rdcycle, rvcc_rdcycle },
815     { rv_op_rdtime, rvcc_rdtime },
816     { rv_op_rdinstret, rvcc_rdinstret },
817     { rv_op_rdcycleh, rvcc_rdcycleh },
818     { rv_op_rdtimeh, rvcc_rdtimeh },
819     { rv_op_rdinstreth, rvcc_rdinstreth },
820     { rv_op_frcsr, rvcc_frcsr },
821     { rv_op_frrm, rvcc_frrm },
822     { rv_op_frflags, rvcc_frflags },
823     { rv_op_illegal, NULL }
824 };
825 
826 static const rv_comp_data rvcp_csrrwi[] = {
827     { rv_op_fsrmi, rvcc_fsrmi },
828     { rv_op_fsflagsi, rvcc_fsflagsi },
829     { rv_op_illegal, NULL }
830 };
831 
832 static const rv_comp_data rvcp_fsgnj_s[] = {
833     { rv_op_fmv_s, rvcc_fmv_s },
834     { rv_op_illegal, NULL }
835 };
836 
837 static const rv_comp_data rvcp_fsgnjn_s[] = {
838     { rv_op_fneg_s, rvcc_fneg_s },
839     { rv_op_illegal, NULL }
840 };
841 
842 static const rv_comp_data rvcp_fsgnjx_s[] = {
843     { rv_op_fabs_s, rvcc_fabs_s },
844     { rv_op_illegal, NULL }
845 };
846 
847 static const rv_comp_data rvcp_fsgnj_d[] = {
848     { rv_op_fmv_d, rvcc_fmv_d },
849     { rv_op_illegal, NULL }
850 };
851 
852 static const rv_comp_data rvcp_fsgnjn_d[] = {
853     { rv_op_fneg_d, rvcc_fneg_d },
854     { rv_op_illegal, NULL }
855 };
856 
857 static const rv_comp_data rvcp_fsgnjx_d[] = {
858     { rv_op_fabs_d, rvcc_fabs_d },
859     { rv_op_illegal, NULL }
860 };
861 
862 static const rv_comp_data rvcp_fsgnj_q[] = {
863     { rv_op_fmv_q, rvcc_fmv_q },
864     { rv_op_illegal, NULL }
865 };
866 
867 static const rv_comp_data rvcp_fsgnjn_q[] = {
868     { rv_op_fneg_q, rvcc_fneg_q },
869     { rv_op_illegal, NULL }
870 };
871 
872 static 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 
879 const rv_opcode_data opcode_data[] = {
880     { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
881     { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
882     { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
883     { "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
884     { "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
885     { "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
886     { "bne", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bne, 0, 0, 0 },
887     { "blt", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_blt, 0, 0, 0 },
888     { "bge", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bge, 0, 0, 0 },
889     { "bltu", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bltu, 0, 0, 0 },
890     { "bgeu", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_bgeu, 0, 0, 0 },
891     { "lb", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
892     { "lh", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
893     { "lw", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
894     { "lbu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
895     { "lhu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
896     { "sb", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
897     { "sh", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
898     { "sw", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
899     { "addi", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_addi, 0, 0, 0 },
900     { "slti", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
901     { "sltiu", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_sltiu, 0, 0, 0 },
902     { "xori", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_xori, 0, 0, 0 },
903     { "ori", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
904     { "andi", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
905     { "slli", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
906     { "srli", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
907     { "srai", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
908     { "add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
909     { "sub", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_sub, 0, 0, 0 },
910     { "sll", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
911     { "slt", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_slt, 0, 0, 0 },
912     { "sltu", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_sltu, 0, 0, 0 },
913     { "xor", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
914     { "srl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
915     { "sra", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
916     { "or", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
917     { "and", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
918     { "fence", rv_codec_r_f, rv_fmt_pred_succ, NULL, 0, 0, 0 },
919     { "fence.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
920     { "lwu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
921     { "ld", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
922     { "sd", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
923     { "addiw", rv_codec_i, rv_fmt_rd_rs1_imm, rvcp_addiw, 0, 0, 0 },
924     { "slliw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
925     { "srliw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
926     { "sraiw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
927     { "addw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
928     { "subw", rv_codec_r, rv_fmt_rd_rs1_rs2, rvcp_subw, 0, 0, 0 },
929     { "sllw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
930     { "srlw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
931     { "sraw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
932     { "ldu", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
933     { "lq", rv_codec_i, rv_fmt_rd_offset_rs1, NULL, 0, 0, 0 },
934     { "sq", rv_codec_s, rv_fmt_rs2_offset_rs1, NULL, 0, 0, 0 },
935     { "addid", rv_codec_i, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
936     { "sllid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
937     { "srlid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
938     { "sraid", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
939     { "addd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
940     { "subd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
941     { "slld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
942     { "srld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
943     { "srad", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
944     { "mul", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
945     { "mulh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
946     { "mulhsu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
947     { "mulhu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
948     { "div", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
949     { "divu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
950     { "rem", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
951     { "remu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
952     { "mulw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
953     { "divw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
954     { "divuw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
955     { "remw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
956     { "remuw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
957     { "muld", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
958     { "divd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
959     { "divud", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
960     { "remd", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
961     { "remud", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
962     { "lr.w", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
963     { "sc.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
964     { "amoswap.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
965     { "amoadd.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
966     { "amoxor.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
967     { "amoor.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
968     { "amoand.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
969     { "amomin.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
970     { "amomax.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
971     { "amominu.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
972     { "amomaxu.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
973     { "lr.d", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
974     { "sc.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
975     { "amoswap.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
976     { "amoadd.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
977     { "amoxor.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
978     { "amoor.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
979     { "amoand.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
980     { "amomin.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
981     { "amomax.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
982     { "amominu.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
983     { "amomaxu.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
984     { "lr.q", rv_codec_r_l, rv_fmt_aqrl_rd_rs1, NULL, 0, 0, 0 },
985     { "sc.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
986     { "amoswap.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
987     { "amoadd.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
988     { "amoxor.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
989     { "amoor.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
990     { "amoand.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
991     { "amomin.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
992     { "amomax.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
993     { "amominu.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
994     { "amomaxu.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
995     { "ecall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
996     { "ebreak", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
997     { "uret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
998     { "sret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
999     { "hret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1000     { "mret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1001     { "dret", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1002     { "sfence.vm", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
1003     { "sfence.vma", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 },
1004     { "wfi", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
1005     { "csrrw", rv_codec_i_csr, rv_fmt_rd_csr_rs1, rvcp_csrrw, 0, 0, 0 },
1006     { "csrrs", rv_codec_i_csr, rv_fmt_rd_csr_rs1, rvcp_csrrs, 0, 0, 0 },
1007     { "csrrc", rv_codec_i_csr, rv_fmt_rd_csr_rs1, NULL, 0, 0, 0 },
1008     { "csrrwi", rv_codec_i_csr, rv_fmt_rd_csr_zimm, rvcp_csrrwi, 0, 0, 0 },
1009     { "csrrsi", rv_codec_i_csr, rv_fmt_rd_csr_zimm, NULL, 0, 0, 0 },
1010     { "csrrci", rv_codec_i_csr, rv_fmt_rd_csr_zimm, NULL, 0, 0, 0 },
1011     { "flw", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
1012     { "fsw", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
1013     { "fmadd.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1014     { "fmsub.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1015     { "fnmsub.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1016     { "fnmadd.s", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1017     { "fadd.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1018     { "fsub.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1019     { "fmul.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1020     { "fdiv.s", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1021     { "fsgnj.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_s, 0, 0, 0 },
1022     { "fsgnjn.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_s, 0, 0, 0 },
1023     { "fsgnjx.s", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_s, 0, 0, 0 },
1024     { "fmin.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1025     { "fmax.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1026     { "fsqrt.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1027     { "fle.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1028     { "flt.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1029     { "feq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1030     { "fcvt.w.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1031     { "fcvt.wu.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1032     { "fcvt.s.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1033     { "fcvt.s.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1034     { "fmv.x.s", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1035     { "fclass.s", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1036     { "fmv.s.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1037     { "fcvt.l.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1038     { "fcvt.lu.s", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1039     { "fcvt.s.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1040     { "fcvt.s.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1041     { "fld", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
1042     { "fsd", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
1043     { "fmadd.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1044     { "fmsub.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1045     { "fnmsub.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1046     { "fnmadd.d", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1047     { "fadd.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1048     { "fsub.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1049     { "fmul.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1050     { "fdiv.d", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1051     { "fsgnj.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_d, 0, 0, 0 },
1052     { "fsgnjn.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_d, 0, 0, 0 },
1053     { "fsgnjx.d", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_d, 0, 0, 0 },
1054     { "fmin.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1055     { "fmax.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1056     { "fcvt.s.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1057     { "fcvt.d.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1058     { "fsqrt.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1059     { "fle.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1060     { "flt.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1061     { "feq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1062     { "fcvt.w.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1063     { "fcvt.wu.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1064     { "fcvt.d.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1065     { "fcvt.d.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1066     { "fclass.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1067     { "fcvt.l.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1068     { "fcvt.lu.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1069     { "fmv.x.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1070     { "fcvt.d.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1071     { "fcvt.d.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1072     { "fmv.d.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1073     { "flq", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
1074     { "fsq", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
1075     { "fmadd.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1076     { "fmsub.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1077     { "fnmsub.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1078     { "fnmadd.q", rv_codec_r4_m, rv_fmt_rm_frd_frs1_frs2_frs3, NULL, 0, 0, 0 },
1079     { "fadd.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1080     { "fsub.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1081     { "fmul.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1082     { "fdiv.q", rv_codec_r_m, rv_fmt_rm_frd_frs1_frs2, NULL, 0, 0, 0 },
1083     { "fsgnj.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnj_q, 0, 0, 0 },
1084     { "fsgnjn.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjn_q, 0, 0, 0 },
1085     { "fsgnjx.q", rv_codec_r, rv_fmt_frd_frs1_frs2, rvcp_fsgnjx_q, 0, 0, 0 },
1086     { "fmin.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1087     { "fmax.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
1088     { "fcvt.s.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1089     { "fcvt.q.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1090     { "fcvt.d.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1091     { "fcvt.q.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1092     { "fsqrt.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
1093     { "fle.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1094     { "flt.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1095     { "feq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
1096     { "fcvt.w.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1097     { "fcvt.wu.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1098     { "fcvt.q.w", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1099     { "fcvt.q.wu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1100     { "fclass.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1101     { "fcvt.l.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1102     { "fcvt.lu.q", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
1103     { "fcvt.q.l", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1104     { "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
1105     { "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
1106     { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1107     { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
1108       rv_op_addi, rv_op_addi, rvcd_imm_nz },
1109     { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
1110     { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
1111     { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
1112     { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
1113     { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
1114     { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
1115     { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1116     { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi,
1117       rv_op_addi, rvcd_imm_nz },
1118     { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
1119     { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1120     { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
1121       rv_op_addi, rv_op_addi, rvcd_imm_nz },
1122     { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
1123       rv_op_lui, rvcd_imm_nz },
1124     { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
1125       rv_op_srli, rv_op_srli, rvcd_imm_nz },
1126     { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai,
1127       rv_op_srai, rv_op_srai, rvcd_imm_nz },
1128     { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi,
1129       rv_op_andi, rv_op_andi },
1130     { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
1131     { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
1132     { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
1133     { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and, rv_op_and },
1134     { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw, rv_op_subw },
1135     { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw, rv_op_addw },
1136     { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
1137     { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
1138     { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
1139     { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli,
1140       rv_op_slli, rv_op_slli, rvcd_imm_nz },
1141     { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
1142     { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
1143     { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
1144     { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
1145     { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1146     { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak, rv_op_ebreak, rv_op_ebreak },
1147     { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
1148     { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add, rv_op_add },
1149     { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, rv_op_fsd },
1150     { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
1151     { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
1152     { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
1153     { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
1154     { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw, rv_op_addiw },
1155     { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
1156     { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
1157     { "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
1158     { "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
1159     { "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
1160     { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
1161     { "nop", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
1162     { "mv", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1163     { "not", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1164     { "neg", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1165     { "negw", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1166     { "sext.w", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1167     { "seqz", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1168     { "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1169     { "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1170     { "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
1171     { "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1172     { "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1173     { "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1174     { "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1175     { "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1176     { "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1177     { "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1178     { "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1179     { "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1180     { "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1181     { "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1182     { "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
1183     { "bgez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1184     { "bltz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
1185     { "bgtz", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
1186     { "ble", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1187     { "bleu", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1188     { "bgt", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1189     { "bgtu", rv_codec_sb, rv_fmt_rs2_rs1_offset, NULL, 0, 0, 0 },
1190     { "j", rv_codec_uj, rv_fmt_offset, NULL, 0, 0, 0 },
1191     { "ret", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
1192     { "jr", rv_codec_i, rv_fmt_rs1, NULL, 0, 0, 0 },
1193     { "rdcycle", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1194     { "rdtime", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1195     { "rdinstret", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1196     { "rdcycleh", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1197     { "rdtimeh", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1198     { "rdinstreth", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1199     { "frcsr", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1200     { "frrm", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1201     { "frflags", rv_codec_i_csr, rv_fmt_rd, NULL, 0, 0, 0 },
1202     { "fscsr", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1203     { "fsrm", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1204     { "fsflags", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1205     { "fsrmi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 },
1206     { "fsflagsi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 },
1207     { "bseti", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1208     { "bclri", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1209     { "binvi", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1210     { "bexti", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1211     { "rori", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1212     { "clz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1213     { "ctz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1214     { "cpop", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1215     { "sext.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1216     { "sext.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1217     { "xnor", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1218     { "orn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1219     { "andn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1220     { "rol", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1221     { "ror", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1222     { "sh1add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1223     { "sh2add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1224     { "sh3add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1225     { "sh1add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1226     { "sh2add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1227     { "sh3add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1228     { "clmul", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1229     { "clmulr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1230     { "clmulh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1231     { "min", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1232     { "minu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1233     { "max", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1234     { "maxu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1235     { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1236     { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1237     { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1238     { "slli.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1239     { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1240     { "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1241     { "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1242     { "rev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1243     { "zext.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1244     { "roriw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
1245     { "orc.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1246     { "bset", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1247     { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1248     { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1249     { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1250     { "aes32esmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1251     { "aes32esi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1252     { "aes32dsmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1253     { "aes32dsi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1254     { "aes64ks1i", rv_codec_k_rnum,  rv_fmt_rd_rs1_rnum, NULL, 0, 0, 0 },
1255     { "aes64ks2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1256     { "aes64im", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1257     { "aes64esm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1258     { "aes64es", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1259     { "aes64dsm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1260     { "aes64ds", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1261     { "sha256sig0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1262     { "sha256sig1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1263     { "sha256sum0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1264     { "sha256sum1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1265     { "sha512sig0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1266     { "sha512sig1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1267     { "sha512sum0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1268     { "sha512sum1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1269     { "sha512sum0r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1270     { "sha512sum1r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1271     { "sha512sig0l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1272     { "sha512sig0h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1273     { "sha512sig1l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1274     { "sha512sig1h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1275     { "sm3p0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1276     { "sm3p1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
1277     { "sm4ed", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1278     { "sm4ks", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
1279     { "brev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1280     { "pack", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1281     { "packh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1282     { "packw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1283     { "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1284     { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
1285     { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
1286     { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }
1287 };
1288 
1289 /* CSR names */
1290 
1291 static 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 
1499 static 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 
2263 static uint32_t operand_rd(rv_inst inst)
2264 {
2265     return (inst << 52) >> 59;
2266 }
2267 
2268 static uint32_t operand_rs1(rv_inst inst)
2269 {
2270     return (inst << 44) >> 59;
2271 }
2272 
2273 static uint32_t operand_rs2(rv_inst inst)
2274 {
2275     return (inst << 39) >> 59;
2276 }
2277 
2278 static uint32_t operand_rs3(rv_inst inst)
2279 {
2280     return (inst << 32) >> 59;
2281 }
2282 
2283 static uint32_t operand_aq(rv_inst inst)
2284 {
2285     return (inst << 37) >> 63;
2286 }
2287 
2288 static uint32_t operand_rl(rv_inst inst)
2289 {
2290     return (inst << 38) >> 63;
2291 }
2292 
2293 static uint32_t operand_pred(rv_inst inst)
2294 {
2295     return (inst << 36) >> 60;
2296 }
2297 
2298 static uint32_t operand_succ(rv_inst inst)
2299 {
2300     return (inst << 40) >> 60;
2301 }
2302 
2303 static uint32_t operand_rm(rv_inst inst)
2304 {
2305     return (inst << 49) >> 61;
2306 }
2307 
2308 static uint32_t operand_shamt5(rv_inst inst)
2309 {
2310     return (inst << 39) >> 59;
2311 }
2312 
2313 static uint32_t operand_shamt6(rv_inst inst)
2314 {
2315     return (inst << 38) >> 58;
2316 }
2317 
2318 static uint32_t operand_shamt7(rv_inst inst)
2319 {
2320     return (inst << 37) >> 57;
2321 }
2322 
2323 static uint32_t operand_crdq(rv_inst inst)
2324 {
2325     return (inst << 59) >> 61;
2326 }
2327 
2328 static uint32_t operand_crs1q(rv_inst inst)
2329 {
2330     return (inst << 54) >> 61;
2331 }
2332 
2333 static uint32_t operand_crs1rdq(rv_inst inst)
2334 {
2335     return (inst << 54) >> 61;
2336 }
2337 
2338 static uint32_t operand_crs2q(rv_inst inst)
2339 {
2340     return (inst << 59) >> 61;
2341 }
2342 
2343 static uint32_t operand_crd(rv_inst inst)
2344 {
2345     return (inst << 52) >> 59;
2346 }
2347 
2348 static uint32_t operand_crs1(rv_inst inst)
2349 {
2350     return (inst << 52) >> 59;
2351 }
2352 
2353 static uint32_t operand_crs1rd(rv_inst inst)
2354 {
2355     return (inst << 52) >> 59;
2356 }
2357 
2358 static uint32_t operand_crs2(rv_inst inst)
2359 {
2360     return (inst << 57) >> 59;
2361 }
2362 
2363 static uint32_t operand_cimmsh5(rv_inst inst)
2364 {
2365     return (inst << 57) >> 59;
2366 }
2367 
2368 static uint32_t operand_csr12(rv_inst inst)
2369 {
2370     return (inst << 32) >> 52;
2371 }
2372 
2373 static int32_t operand_imm12(rv_inst inst)
2374 {
2375     return ((int64_t)inst << 32) >> 52;
2376 }
2377 
2378 static int32_t operand_imm20(rv_inst inst)
2379 {
2380     return (((int64_t)inst << 32) >> 44) << 12;
2381 }
2382 
2383 static 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 
2391 static int32_t operand_simm12(rv_inst inst)
2392 {
2393     return (((int64_t)inst << 32) >> 57) << 5 |
2394         (inst << 52) >> 59;
2395 }
2396 
2397 static 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 
2405 static uint32_t operand_cimmsh6(rv_inst inst)
2406 {
2407     return ((inst << 51) >> 63) << 5 |
2408         (inst << 57) >> 59;
2409 }
2410 
2411 static int32_t operand_cimmi(rv_inst inst)
2412 {
2413     return (((int64_t)inst << 51) >> 63) << 5 |
2414         (inst << 57) >> 59;
2415 }
2416 
2417 static int32_t operand_cimmui(rv_inst inst)
2418 {
2419     return (((int64_t)inst << 51) >> 63) << 17 |
2420         ((inst << 57) >> 59) << 12;
2421 }
2422 
2423 static 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 
2430 static 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 
2437 static 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 
2444 static 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 
2453 static 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 
2465 static 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 
2474 static uint32_t operand_cimmswsp(rv_inst inst)
2475 {
2476     return ((inst << 51) >> 60) << 2 |
2477         ((inst << 55) >> 62) << 6;
2478 }
2479 
2480 static uint32_t operand_cimmsdsp(rv_inst inst)
2481 {
2482     return ((inst << 51) >> 61) << 3 |
2483         ((inst << 54) >> 61) << 6;
2484 }
2485 
2486 static uint32_t operand_cimmsqsp(rv_inst inst)
2487 {
2488     return ((inst << 51) >> 62) << 4 |
2489         ((inst << 53) >> 60) << 6;
2490 }
2491 
2492 static 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 
2500 static 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 
2507 static uint32_t operand_cimmd(rv_inst inst)
2508 {
2509     return ((inst << 51) >> 61) << 3 |
2510         ((inst << 57) >> 62) << 6;
2511 }
2512 
2513 static 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 
2520 static uint32_t operand_bs(rv_inst inst)
2521 {
2522     return (inst << 32) >> 62;
2523 }
2524 
2525 static uint32_t operand_rnum(rv_inst inst)
2526 {
2527     return (inst << 40) >> 60;
2528 }
2529 
2530 /* decode operands */
2531 
2532 static 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 
2824 static 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 
2929 static 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 
2950 static 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 
2958 static 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 
3112 static 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 
3130 static 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 
3144 static 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 
3158 static 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 
3172 static 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 
3189 static void
3190 disasm_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 
3207 static int
3208 print_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 
3255 int print_insn_riscv32(bfd_vma memaddr, struct disassemble_info *info)
3256 {
3257     return print_insn_riscv(memaddr, info, rv32);
3258 }
3259 
3260 int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info)
3261 {
3262     return print_insn_riscv(memaddr, info, rv64);
3263 }
3264 
3265 int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
3266 {
3267     return print_insn_riscv(memaddr, info, rv128);
3268 }
3269