xref: /openbmc/qemu/disas/riscv.c (revision 513eb437)
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 0x0104: return "sie";
1308     case 0x0105: return "stvec";
1309     case 0x0106: return "scounteren";
1310     case 0x0140: return "sscratch";
1311     case 0x0141: return "sepc";
1312     case 0x0142: return "scause";
1313     case 0x0143: return "stval";
1314     case 0x0144: return "sip";
1315     case 0x0180: return "satp";
1316     case 0x0200: return "hstatus";
1317     case 0x0202: return "hedeleg";
1318     case 0x0203: return "hideleg";
1319     case 0x0204: return "hie";
1320     case 0x0205: return "htvec";
1321     case 0x0240: return "hscratch";
1322     case 0x0241: return "hepc";
1323     case 0x0242: return "hcause";
1324     case 0x0243: return "hbadaddr";
1325     case 0x0244: return "hip";
1326     case 0x0300: return "mstatus";
1327     case 0x0301: return "misa";
1328     case 0x0302: return "medeleg";
1329     case 0x0303: return "mideleg";
1330     case 0x0304: return "mie";
1331     case 0x0305: return "mtvec";
1332     case 0x0306: return "mcounteren";
1333     case 0x0320: return "mucounteren";
1334     case 0x0321: return "mscounteren";
1335     case 0x0322: return "mhcounteren";
1336     case 0x0323: return "mhpmevent3";
1337     case 0x0324: return "mhpmevent4";
1338     case 0x0325: return "mhpmevent5";
1339     case 0x0326: return "mhpmevent6";
1340     case 0x0327: return "mhpmevent7";
1341     case 0x0328: return "mhpmevent8";
1342     case 0x0329: return "mhpmevent9";
1343     case 0x032a: return "mhpmevent10";
1344     case 0x032b: return "mhpmevent11";
1345     case 0x032c: return "mhpmevent12";
1346     case 0x032d: return "mhpmevent13";
1347     case 0x032e: return "mhpmevent14";
1348     case 0x032f: return "mhpmevent15";
1349     case 0x0330: return "mhpmevent16";
1350     case 0x0331: return "mhpmevent17";
1351     case 0x0332: return "mhpmevent18";
1352     case 0x0333: return "mhpmevent19";
1353     case 0x0334: return "mhpmevent20";
1354     case 0x0335: return "mhpmevent21";
1355     case 0x0336: return "mhpmevent22";
1356     case 0x0337: return "mhpmevent23";
1357     case 0x0338: return "mhpmevent24";
1358     case 0x0339: return "mhpmevent25";
1359     case 0x033a: return "mhpmevent26";
1360     case 0x033b: return "mhpmevent27";
1361     case 0x033c: return "mhpmevent28";
1362     case 0x033d: return "mhpmevent29";
1363     case 0x033e: return "mhpmevent30";
1364     case 0x033f: return "mhpmevent31";
1365     case 0x0340: return "mscratch";
1366     case 0x0341: return "mepc";
1367     case 0x0342: return "mcause";
1368     case 0x0343: return "mtval";
1369     case 0x0344: return "mip";
1370     case 0x0380: return "mbase";
1371     case 0x0381: return "mbound";
1372     case 0x0382: return "mibase";
1373     case 0x0383: return "mibound";
1374     case 0x0384: return "mdbase";
1375     case 0x0385: return "mdbound";
1376     case 0x03a0: return "pmpcfg3";
1377     case 0x03b0: return "pmpaddr0";
1378     case 0x03b1: return "pmpaddr1";
1379     case 0x03b2: return "pmpaddr2";
1380     case 0x03b3: return "pmpaddr3";
1381     case 0x03b4: return "pmpaddr4";
1382     case 0x03b5: return "pmpaddr5";
1383     case 0x03b6: return "pmpaddr6";
1384     case 0x03b7: return "pmpaddr7";
1385     case 0x03b8: return "pmpaddr8";
1386     case 0x03b9: return "pmpaddr9";
1387     case 0x03ba: return "pmpaddr10";
1388     case 0x03bb: return "pmpaddr11";
1389     case 0x03bc: return "pmpaddr12";
1390     case 0x03bd: return "pmpaddr14";
1391     case 0x03be: return "pmpaddr13";
1392     case 0x03bf: return "pmpaddr15";
1393     case 0x0780: return "mtohost";
1394     case 0x0781: return "mfromhost";
1395     case 0x0782: return "mreset";
1396     case 0x0783: return "mipi";
1397     case 0x0784: return "miobase";
1398     case 0x07a0: return "tselect";
1399     case 0x07a1: return "tdata1";
1400     case 0x07a2: return "tdata2";
1401     case 0x07a3: return "tdata3";
1402     case 0x07b0: return "dcsr";
1403     case 0x07b1: return "dpc";
1404     case 0x07b2: return "dscratch";
1405     case 0x0b00: return "mcycle";
1406     case 0x0b01: return "mtime";
1407     case 0x0b02: return "minstret";
1408     case 0x0b03: return "mhpmcounter3";
1409     case 0x0b04: return "mhpmcounter4";
1410     case 0x0b05: return "mhpmcounter5";
1411     case 0x0b06: return "mhpmcounter6";
1412     case 0x0b07: return "mhpmcounter7";
1413     case 0x0b08: return "mhpmcounter8";
1414     case 0x0b09: return "mhpmcounter9";
1415     case 0x0b0a: return "mhpmcounter10";
1416     case 0x0b0b: return "mhpmcounter11";
1417     case 0x0b0c: return "mhpmcounter12";
1418     case 0x0b0d: return "mhpmcounter13";
1419     case 0x0b0e: return "mhpmcounter14";
1420     case 0x0b0f: return "mhpmcounter15";
1421     case 0x0b10: return "mhpmcounter16";
1422     case 0x0b11: return "mhpmcounter17";
1423     case 0x0b12: return "mhpmcounter18";
1424     case 0x0b13: return "mhpmcounter19";
1425     case 0x0b14: return "mhpmcounter20";
1426     case 0x0b15: return "mhpmcounter21";
1427     case 0x0b16: return "mhpmcounter22";
1428     case 0x0b17: return "mhpmcounter23";
1429     case 0x0b18: return "mhpmcounter24";
1430     case 0x0b19: return "mhpmcounter25";
1431     case 0x0b1a: return "mhpmcounter26";
1432     case 0x0b1b: return "mhpmcounter27";
1433     case 0x0b1c: return "mhpmcounter28";
1434     case 0x0b1d: return "mhpmcounter29";
1435     case 0x0b1e: return "mhpmcounter30";
1436     case 0x0b1f: return "mhpmcounter31";
1437     case 0x0b80: return "mcycleh";
1438     case 0x0b81: return "mtimeh";
1439     case 0x0b82: return "minstreth";
1440     case 0x0b83: return "mhpmcounter3h";
1441     case 0x0b84: return "mhpmcounter4h";
1442     case 0x0b85: return "mhpmcounter5h";
1443     case 0x0b86: return "mhpmcounter6h";
1444     case 0x0b87: return "mhpmcounter7h";
1445     case 0x0b88: return "mhpmcounter8h";
1446     case 0x0b89: return "mhpmcounter9h";
1447     case 0x0b8a: return "mhpmcounter10h";
1448     case 0x0b8b: return "mhpmcounter11h";
1449     case 0x0b8c: return "mhpmcounter12h";
1450     case 0x0b8d: return "mhpmcounter13h";
1451     case 0x0b8e: return "mhpmcounter14h";
1452     case 0x0b8f: return "mhpmcounter15h";
1453     case 0x0b90: return "mhpmcounter16h";
1454     case 0x0b91: return "mhpmcounter17h";
1455     case 0x0b92: return "mhpmcounter18h";
1456     case 0x0b93: return "mhpmcounter19h";
1457     case 0x0b94: return "mhpmcounter20h";
1458     case 0x0b95: return "mhpmcounter21h";
1459     case 0x0b96: return "mhpmcounter22h";
1460     case 0x0b97: return "mhpmcounter23h";
1461     case 0x0b98: return "mhpmcounter24h";
1462     case 0x0b99: return "mhpmcounter25h";
1463     case 0x0b9a: return "mhpmcounter26h";
1464     case 0x0b9b: return "mhpmcounter27h";
1465     case 0x0b9c: return "mhpmcounter28h";
1466     case 0x0b9d: return "mhpmcounter29h";
1467     case 0x0b9e: return "mhpmcounter30h";
1468     case 0x0b9f: return "mhpmcounter31h";
1469     case 0x0c00: return "cycle";
1470     case 0x0c01: return "time";
1471     case 0x0c02: return "instret";
1472     case 0x0c80: return "cycleh";
1473     case 0x0c81: return "timeh";
1474     case 0x0c82: return "instreth";
1475     case 0x0d00: return "scycle";
1476     case 0x0d01: return "stime";
1477     case 0x0d02: return "sinstret";
1478     case 0x0d80: return "scycleh";
1479     case 0x0d81: return "stimeh";
1480     case 0x0d82: return "sinstreth";
1481     case 0x0e00: return "hcycle";
1482     case 0x0e01: return "htime";
1483     case 0x0e02: return "hinstret";
1484     case 0x0e80: return "hcycleh";
1485     case 0x0e81: return "htimeh";
1486     case 0x0e82: return "hinstreth";
1487     case 0x0f11: return "mvendorid";
1488     case 0x0f12: return "marchid";
1489     case 0x0f13: return "mimpid";
1490     case 0x0f14: return "mhartid";
1491     default: return NULL;
1492     }
1493 }
1494 
1495 /* decode opcode */
1496 
1497 static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
1498 {
1499     rv_inst inst = dec->inst;
1500     rv_opcode op = rv_op_illegal;
1501     switch (((inst >> 0) & 0b11)) {
1502     case 0:
1503         switch (((inst >> 13) & 0b111)) {
1504         case 0: op = rv_op_c_addi4spn; break;
1505         case 1:
1506             if (isa == rv128) {
1507                 op = rv_op_c_lq;
1508             } else {
1509                 op = rv_op_c_fld;
1510             }
1511             break;
1512         case 2: op = rv_op_c_lw; break;
1513         case 3:
1514             if (isa == rv32) {
1515                 op = rv_op_c_flw;
1516             } else {
1517                 op = rv_op_c_ld;
1518             }
1519             break;
1520         case 5:
1521             if (isa == rv128) {
1522                 op = rv_op_c_sq;
1523             } else {
1524                 op = rv_op_c_fsd;
1525             }
1526             break;
1527         case 6: op = rv_op_c_sw; break;
1528         case 7:
1529             if (isa == rv32) {
1530                 op = rv_op_c_fsw;
1531             } else {
1532                 op = rv_op_c_sd;
1533             }
1534             break;
1535         }
1536         break;
1537     case 1:
1538         switch (((inst >> 13) & 0b111)) {
1539         case 0:
1540             switch (((inst >> 2) & 0b11111111111)) {
1541             case 0: op = rv_op_c_nop; break;
1542             default: op = rv_op_c_addi; break;
1543             }
1544             break;
1545         case 1:
1546             if (isa == rv32) {
1547                 op = rv_op_c_jal;
1548             } else {
1549                 op = rv_op_c_addiw;
1550             }
1551             break;
1552         case 2: op = rv_op_c_li; break;
1553         case 3:
1554             switch (((inst >> 7) & 0b11111)) {
1555             case 2: op = rv_op_c_addi16sp; break;
1556             default: op = rv_op_c_lui; break;
1557             }
1558             break;
1559         case 4:
1560             switch (((inst >> 10) & 0b11)) {
1561             case 0:
1562                 op = rv_op_c_srli;
1563                 break;
1564             case 1:
1565                 op = rv_op_c_srai;
1566                 break;
1567             case 2: op = rv_op_c_andi; break;
1568             case 3:
1569                 switch (((inst >> 10) & 0b100) | ((inst >> 5) & 0b011)) {
1570                 case 0: op = rv_op_c_sub; break;
1571                 case 1: op = rv_op_c_xor; break;
1572                 case 2: op = rv_op_c_or; break;
1573                 case 3: op = rv_op_c_and; break;
1574                 case 4: op = rv_op_c_subw; break;
1575                 case 5: op = rv_op_c_addw; break;
1576                 }
1577                 break;
1578             }
1579             break;
1580         case 5: op = rv_op_c_j; break;
1581         case 6: op = rv_op_c_beqz; break;
1582         case 7: op = rv_op_c_bnez; break;
1583         }
1584         break;
1585     case 2:
1586         switch (((inst >> 13) & 0b111)) {
1587         case 0:
1588             op = rv_op_c_slli;
1589             break;
1590         case 1:
1591             if (isa == rv128) {
1592                 op = rv_op_c_lqsp;
1593             } else {
1594                 op = rv_op_c_fldsp;
1595             }
1596             break;
1597         case 2: op = rv_op_c_lwsp; break;
1598         case 3:
1599             if (isa == rv32) {
1600                 op = rv_op_c_flwsp;
1601             } else {
1602                 op = rv_op_c_ldsp;
1603             }
1604             break;
1605         case 4:
1606             switch (((inst >> 12) & 0b1)) {
1607             case 0:
1608                 switch (((inst >> 2) & 0b11111)) {
1609                 case 0: op = rv_op_c_jr; break;
1610                 default: op = rv_op_c_mv; break;
1611                 }
1612                 break;
1613             case 1:
1614                 switch (((inst >> 2) & 0b11111)) {
1615                 case 0:
1616                     switch (((inst >> 7) & 0b11111)) {
1617                     case 0: op = rv_op_c_ebreak; break;
1618                     default: op = rv_op_c_jalr; break;
1619                     }
1620                     break;
1621                 default: op = rv_op_c_add; break;
1622                 }
1623                 break;
1624             }
1625             break;
1626         case 5:
1627             if (isa == rv128) {
1628                 op = rv_op_c_sqsp;
1629             } else {
1630                 op = rv_op_c_fsdsp;
1631             }
1632             break;
1633         case 6: op = rv_op_c_swsp; break;
1634         case 7:
1635             if (isa == rv32) {
1636                 op = rv_op_c_fswsp;
1637             } else {
1638                 op = rv_op_c_sdsp;
1639             }
1640             break;
1641         }
1642         break;
1643     case 3:
1644         switch (((inst >> 2) & 0b11111)) {
1645         case 0:
1646             switch (((inst >> 12) & 0b111)) {
1647             case 0: op = rv_op_lb; break;
1648             case 1: op = rv_op_lh; break;
1649             case 2: op = rv_op_lw; break;
1650             case 3: op = rv_op_ld; break;
1651             case 4: op = rv_op_lbu; break;
1652             case 5: op = rv_op_lhu; break;
1653             case 6: op = rv_op_lwu; break;
1654             case 7: op = rv_op_ldu; break;
1655             }
1656             break;
1657         case 1:
1658             switch (((inst >> 12) & 0b111)) {
1659             case 2: op = rv_op_flw; break;
1660             case 3: op = rv_op_fld; break;
1661             case 4: op = rv_op_flq; break;
1662             }
1663             break;
1664         case 3:
1665             switch (((inst >> 12) & 0b111)) {
1666             case 0: op = rv_op_fence; break;
1667             case 1: op = rv_op_fence_i; break;
1668             case 2: op = rv_op_lq; break;
1669             }
1670             break;
1671         case 4:
1672             switch (((inst >> 12) & 0b111)) {
1673             case 0: op = rv_op_addi; break;
1674             case 1:
1675                 switch (((inst >> 27) & 0b11111)) {
1676                 case 0b00000: op = rv_op_slli; break;
1677                 case 0b00001:
1678                     switch (((inst >> 20) & 0b1111111)) {
1679                     case 0b0001111: op = rv_op_zip; break;
1680                     }
1681                     break;
1682                 case 0b00010:
1683                     switch (((inst >> 20) & 0b1111111)) {
1684                     case 0b0000000: op = rv_op_sha256sum0; break;
1685                     case 0b0000001: op = rv_op_sha256sum1; break;
1686                     case 0b0000010: op = rv_op_sha256sig0; break;
1687                     case 0b0000011: op = rv_op_sha256sig1; break;
1688                     case 0b0000100: op = rv_op_sha512sum0; break;
1689                     case 0b0000101: op = rv_op_sha512sum1; break;
1690                     case 0b0000110: op = rv_op_sha512sig0; break;
1691                     case 0b0000111: op = rv_op_sha512sig1; break;
1692                     case 0b0001000: op = rv_op_sm3p0; break;
1693                     case 0b0001001: op = rv_op_sm3p1; break;
1694                     }
1695                     break;
1696                 case 0b00101: op = rv_op_bseti; break;
1697                 case 0b00110:
1698                     switch (((inst >> 20) & 0b1111111)) {
1699                     case 0b0000000: op = rv_op_aes64im; break;
1700                     default:
1701                         if (((inst >> 24) & 0b0111) == 0b001) {
1702                             op = rv_op_aes64ks1i;
1703                         }
1704                         break;
1705                      }
1706                      break;
1707                 case 0b01001: op = rv_op_bclri; break;
1708                 case 0b01101: op = rv_op_binvi; break;
1709                 case 0b01100:
1710                     switch (((inst >> 20) & 0b1111111)) {
1711                     case 0b0000000: op = rv_op_clz; break;
1712                     case 0b0000001: op = rv_op_ctz; break;
1713                     case 0b0000010: op = rv_op_cpop; break;
1714                       /* 0b0000011 */
1715                     case 0b0000100: op = rv_op_sext_b; break;
1716                     case 0b0000101: op = rv_op_sext_h; break;
1717                     }
1718                     break;
1719                 }
1720                 break;
1721             case 2: op = rv_op_slti; break;
1722             case 3: op = rv_op_sltiu; break;
1723             case 4: op = rv_op_xori; break;
1724             case 5:
1725                 switch (((inst >> 27) & 0b11111)) {
1726                 case 0b00000: op = rv_op_srli; break;
1727                 case 0b00001:
1728                     switch (((inst >> 20) & 0b1111111)) {
1729                     case 0b0001111: op = rv_op_unzip; break;
1730                     }
1731                     break;
1732                 case 0b00101: op = rv_op_orc_b; break;
1733                 case 0b01000: op = rv_op_srai; break;
1734                 case 0b01001: op = rv_op_bexti; break;
1735                 case 0b01100: op = rv_op_rori; break;
1736                 case 0b01101:
1737                     switch ((inst >> 20) & 0b1111111) {
1738                     case 0b0011000: op = rv_op_rev8; break;
1739                     case 0b0111000: op = rv_op_rev8; break;
1740                     case 0b0000111: op = rv_op_brev8; break;
1741                     }
1742                     break;
1743                 }
1744                 break;
1745             case 6: op = rv_op_ori; break;
1746             case 7: op = rv_op_andi; break;
1747             }
1748             break;
1749         case 5: op = rv_op_auipc; break;
1750         case 6:
1751             switch (((inst >> 12) & 0b111)) {
1752             case 0: op = rv_op_addiw; break;
1753             case 1:
1754                 switch (((inst >> 25) & 0b1111111)) {
1755                 case 0: op = rv_op_slliw; break;
1756                 case 4: op = rv_op_slli_uw; break;
1757                 case 48:
1758                     switch ((inst >> 20) & 0b11111) {
1759                     case 0b00000: op = rv_op_clzw; break;
1760                     case 0b00001: op = rv_op_ctzw; break;
1761                     case 0b00010: op = rv_op_cpopw; break;
1762                     }
1763                     break;
1764                 }
1765                 break;
1766             case 5:
1767                 switch (((inst >> 25) & 0b1111111)) {
1768                 case 0: op = rv_op_srliw; break;
1769                 case 32: op = rv_op_sraiw; break;
1770                 case 48: op = rv_op_roriw; break;
1771                 }
1772                 break;
1773             }
1774             break;
1775         case 8:
1776             switch (((inst >> 12) & 0b111)) {
1777             case 0: op = rv_op_sb; break;
1778             case 1: op = rv_op_sh; break;
1779             case 2: op = rv_op_sw; break;
1780             case 3: op = rv_op_sd; break;
1781             case 4: op = rv_op_sq; break;
1782             }
1783             break;
1784         case 9:
1785             switch (((inst >> 12) & 0b111)) {
1786             case 2: op = rv_op_fsw; break;
1787             case 3: op = rv_op_fsd; break;
1788             case 4: op = rv_op_fsq; break;
1789             }
1790             break;
1791         case 11:
1792             switch (((inst >> 24) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1793             case 2: op = rv_op_amoadd_w; break;
1794             case 3: op = rv_op_amoadd_d; break;
1795             case 4: op = rv_op_amoadd_q; break;
1796             case 10: op = rv_op_amoswap_w; break;
1797             case 11: op = rv_op_amoswap_d; break;
1798             case 12: op = rv_op_amoswap_q; break;
1799             case 18:
1800                 switch (((inst >> 20) & 0b11111)) {
1801                 case 0: op = rv_op_lr_w; break;
1802                 }
1803                 break;
1804             case 19:
1805                 switch (((inst >> 20) & 0b11111)) {
1806                 case 0: op = rv_op_lr_d; break;
1807                 }
1808                 break;
1809             case 20:
1810                 switch (((inst >> 20) & 0b11111)) {
1811                 case 0: op = rv_op_lr_q; break;
1812                 }
1813                 break;
1814             case 26: op = rv_op_sc_w; break;
1815             case 27: op = rv_op_sc_d; break;
1816             case 28: op = rv_op_sc_q; break;
1817             case 34: op = rv_op_amoxor_w; break;
1818             case 35: op = rv_op_amoxor_d; break;
1819             case 36: op = rv_op_amoxor_q; break;
1820             case 66: op = rv_op_amoor_w; break;
1821             case 67: op = rv_op_amoor_d; break;
1822             case 68: op = rv_op_amoor_q; break;
1823             case 98: op = rv_op_amoand_w; break;
1824             case 99: op = rv_op_amoand_d; break;
1825             case 100: op = rv_op_amoand_q; break;
1826             case 130: op = rv_op_amomin_w; break;
1827             case 131: op = rv_op_amomin_d; break;
1828             case 132: op = rv_op_amomin_q; break;
1829             case 162: op = rv_op_amomax_w; break;
1830             case 163: op = rv_op_amomax_d; break;
1831             case 164: op = rv_op_amomax_q; break;
1832             case 194: op = rv_op_amominu_w; break;
1833             case 195: op = rv_op_amominu_d; break;
1834             case 196: op = rv_op_amominu_q; break;
1835             case 226: op = rv_op_amomaxu_w; break;
1836             case 227: op = rv_op_amomaxu_d; break;
1837             case 228: op = rv_op_amomaxu_q; break;
1838             }
1839             break;
1840         case 12:
1841             switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1842             case 0: op = rv_op_add; break;
1843             case 1: op = rv_op_sll; break;
1844             case 2: op = rv_op_slt; break;
1845             case 3: op = rv_op_sltu; break;
1846             case 4: op = rv_op_xor; break;
1847             case 5: op = rv_op_srl; break;
1848             case 6: op = rv_op_or; break;
1849             case 7: op = rv_op_and; break;
1850             case 8: op = rv_op_mul; break;
1851             case 9: op = rv_op_mulh; break;
1852             case 10: op = rv_op_mulhsu; break;
1853             case 11: op = rv_op_mulhu; break;
1854             case 12: op = rv_op_div; break;
1855             case 13: op = rv_op_divu; break;
1856             case 14: op = rv_op_rem; break;
1857             case 15: op = rv_op_remu; break;
1858             case 36:
1859                 switch ((inst >> 20) & 0b11111) {
1860                 case 0: op = rv_op_zext_h; break;
1861                 default: op = rv_op_pack; break;
1862                 }
1863                 break;
1864             case 39: op = rv_op_packh; break;
1865 
1866             case 41: op = rv_op_clmul; break;
1867             case 42: op = rv_op_clmulr; break;
1868             case 43: op = rv_op_clmulh; break;
1869             case 44: op = rv_op_min; break;
1870             case 45: op = rv_op_minu; break;
1871             case 46: op = rv_op_max; break;
1872             case 47: op = rv_op_maxu; break;
1873             case 130: op = rv_op_sh1add; break;
1874             case 132: op = rv_op_sh2add; break;
1875             case 134: op = rv_op_sh3add; break;
1876             case 161: op = rv_op_bset; break;
1877             case 162: op = rv_op_xperm4; break;
1878             case 164: op = rv_op_xperm8; break;
1879             case 200: op = rv_op_aes64es; break;
1880             case 216: op = rv_op_aes64esm; break;
1881             case 232: op = rv_op_aes64ds; break;
1882             case 248: op = rv_op_aes64dsm; break;
1883             case 256: op = rv_op_sub; break;
1884             case 260: op = rv_op_xnor; break;
1885             case 261: op = rv_op_sra; break;
1886             case 262: op = rv_op_orn; break;
1887             case 263: op = rv_op_andn; break;
1888             case 289: op = rv_op_bclr; break;
1889             case 293: op = rv_op_bext; break;
1890             case 320: op = rv_op_sha512sum0r; break;
1891             case 328: op = rv_op_sha512sum1r; break;
1892             case 336: op = rv_op_sha512sig0l; break;
1893             case 344: op = rv_op_sha512sig1l; break;
1894             case 368: op = rv_op_sha512sig0h; break;
1895             case 376: op = rv_op_sha512sig1h; break;
1896             case 385: op = rv_op_rol; break;
1897             case 389: op = rv_op_ror; break;
1898             case 417: op = rv_op_binv; break;
1899             case 504: op = rv_op_aes64ks2; break;
1900             }
1901             switch ((inst >> 25) & 0b0011111) {
1902             case 17: op = rv_op_aes32esi; break;
1903             case 19: op = rv_op_aes32esmi; break;
1904             case 21: op = rv_op_aes32dsi; break;
1905             case 23: op = rv_op_aes32dsmi; break;
1906             case 24: op = rv_op_sm4ed; break;
1907             case 26: op = rv_op_sm4ks; break;
1908             }
1909             break;
1910         case 13: op = rv_op_lui; break;
1911         case 14:
1912             switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1913             case 0: op = rv_op_addw; break;
1914             case 1: op = rv_op_sllw; break;
1915             case 5: op = rv_op_srlw; break;
1916             case 8: op = rv_op_mulw; break;
1917             case 12: op = rv_op_divw; break;
1918             case 13: op = rv_op_divuw; break;
1919             case 14: op = rv_op_remw; break;
1920             case 15: op = rv_op_remuw; break;
1921             case 32: op = rv_op_add_uw; break;
1922             case 36:
1923                 switch ((inst >> 20) & 0b11111) {
1924                 case 0: op = rv_op_zext_h; break;
1925                 default: op = rv_op_packw; break;
1926                 }
1927                 break;
1928             case 130: op = rv_op_sh1add_uw; break;
1929             case 132: op = rv_op_sh2add_uw; break;
1930             case 134: op = rv_op_sh3add_uw; break;
1931             case 256: op = rv_op_subw; break;
1932             case 261: op = rv_op_sraw; break;
1933             case 385: op = rv_op_rolw; break;
1934             case 389: op = rv_op_rorw; break;
1935             }
1936             break;
1937         case 16:
1938             switch (((inst >> 25) & 0b11)) {
1939             case 0: op = rv_op_fmadd_s; break;
1940             case 1: op = rv_op_fmadd_d; break;
1941             case 3: op = rv_op_fmadd_q; break;
1942             }
1943             break;
1944         case 17:
1945             switch (((inst >> 25) & 0b11)) {
1946             case 0: op = rv_op_fmsub_s; break;
1947             case 1: op = rv_op_fmsub_d; break;
1948             case 3: op = rv_op_fmsub_q; break;
1949             }
1950             break;
1951         case 18:
1952             switch (((inst >> 25) & 0b11)) {
1953             case 0: op = rv_op_fnmsub_s; break;
1954             case 1: op = rv_op_fnmsub_d; break;
1955             case 3: op = rv_op_fnmsub_q; break;
1956             }
1957             break;
1958         case 19:
1959             switch (((inst >> 25) & 0b11)) {
1960             case 0: op = rv_op_fnmadd_s; break;
1961             case 1: op = rv_op_fnmadd_d; break;
1962             case 3: op = rv_op_fnmadd_q; break;
1963             }
1964             break;
1965         case 20:
1966             switch (((inst >> 25) & 0b1111111)) {
1967             case 0: op = rv_op_fadd_s; break;
1968             case 1: op = rv_op_fadd_d; break;
1969             case 3: op = rv_op_fadd_q; break;
1970             case 4: op = rv_op_fsub_s; break;
1971             case 5: op = rv_op_fsub_d; break;
1972             case 7: op = rv_op_fsub_q; break;
1973             case 8: op = rv_op_fmul_s; break;
1974             case 9: op = rv_op_fmul_d; break;
1975             case 11: op = rv_op_fmul_q; break;
1976             case 12: op = rv_op_fdiv_s; break;
1977             case 13: op = rv_op_fdiv_d; break;
1978             case 15: op = rv_op_fdiv_q; break;
1979             case 16:
1980                 switch (((inst >> 12) & 0b111)) {
1981                 case 0: op = rv_op_fsgnj_s; break;
1982                 case 1: op = rv_op_fsgnjn_s; break;
1983                 case 2: op = rv_op_fsgnjx_s; break;
1984                 }
1985                 break;
1986             case 17:
1987                 switch (((inst >> 12) & 0b111)) {
1988                 case 0: op = rv_op_fsgnj_d; break;
1989                 case 1: op = rv_op_fsgnjn_d; break;
1990                 case 2: op = rv_op_fsgnjx_d; break;
1991                 }
1992                 break;
1993             case 19:
1994                 switch (((inst >> 12) & 0b111)) {
1995                 case 0: op = rv_op_fsgnj_q; break;
1996                 case 1: op = rv_op_fsgnjn_q; break;
1997                 case 2: op = rv_op_fsgnjx_q; break;
1998                 }
1999                 break;
2000             case 20:
2001                 switch (((inst >> 12) & 0b111)) {
2002                 case 0: op = rv_op_fmin_s; break;
2003                 case 1: op = rv_op_fmax_s; break;
2004                 }
2005                 break;
2006             case 21:
2007                 switch (((inst >> 12) & 0b111)) {
2008                 case 0: op = rv_op_fmin_d; break;
2009                 case 1: op = rv_op_fmax_d; break;
2010                 }
2011                 break;
2012             case 23:
2013                 switch (((inst >> 12) & 0b111)) {
2014                 case 0: op = rv_op_fmin_q; break;
2015                 case 1: op = rv_op_fmax_q; break;
2016                 }
2017                 break;
2018             case 32:
2019                 switch (((inst >> 20) & 0b11111)) {
2020                 case 1: op = rv_op_fcvt_s_d; break;
2021                 case 3: op = rv_op_fcvt_s_q; break;
2022                 }
2023                 break;
2024             case 33:
2025                 switch (((inst >> 20) & 0b11111)) {
2026                 case 0: op = rv_op_fcvt_d_s; break;
2027                 case 3: op = rv_op_fcvt_d_q; break;
2028                 }
2029                 break;
2030             case 35:
2031                 switch (((inst >> 20) & 0b11111)) {
2032                 case 0: op = rv_op_fcvt_q_s; break;
2033                 case 1: op = rv_op_fcvt_q_d; break;
2034                 }
2035                 break;
2036             case 44:
2037                 switch (((inst >> 20) & 0b11111)) {
2038                 case 0: op = rv_op_fsqrt_s; break;
2039                 }
2040                 break;
2041             case 45:
2042                 switch (((inst >> 20) & 0b11111)) {
2043                 case 0: op = rv_op_fsqrt_d; break;
2044                 }
2045                 break;
2046             case 47:
2047                 switch (((inst >> 20) & 0b11111)) {
2048                 case 0: op = rv_op_fsqrt_q; break;
2049                 }
2050                 break;
2051             case 80:
2052                 switch (((inst >> 12) & 0b111)) {
2053                 case 0: op = rv_op_fle_s; break;
2054                 case 1: op = rv_op_flt_s; break;
2055                 case 2: op = rv_op_feq_s; break;
2056                 }
2057                 break;
2058             case 81:
2059                 switch (((inst >> 12) & 0b111)) {
2060                 case 0: op = rv_op_fle_d; break;
2061                 case 1: op = rv_op_flt_d; break;
2062                 case 2: op = rv_op_feq_d; break;
2063                 }
2064                 break;
2065             case 83:
2066                 switch (((inst >> 12) & 0b111)) {
2067                 case 0: op = rv_op_fle_q; break;
2068                 case 1: op = rv_op_flt_q; break;
2069                 case 2: op = rv_op_feq_q; break;
2070                 }
2071                 break;
2072             case 96:
2073                 switch (((inst >> 20) & 0b11111)) {
2074                 case 0: op = rv_op_fcvt_w_s; break;
2075                 case 1: op = rv_op_fcvt_wu_s; break;
2076                 case 2: op = rv_op_fcvt_l_s; break;
2077                 case 3: op = rv_op_fcvt_lu_s; break;
2078                 }
2079                 break;
2080             case 97:
2081                 switch (((inst >> 20) & 0b11111)) {
2082                 case 0: op = rv_op_fcvt_w_d; break;
2083                 case 1: op = rv_op_fcvt_wu_d; break;
2084                 case 2: op = rv_op_fcvt_l_d; break;
2085                 case 3: op = rv_op_fcvt_lu_d; break;
2086                 }
2087                 break;
2088             case 99:
2089                 switch (((inst >> 20) & 0b11111)) {
2090                 case 0: op = rv_op_fcvt_w_q; break;
2091                 case 1: op = rv_op_fcvt_wu_q; break;
2092                 case 2: op = rv_op_fcvt_l_q; break;
2093                 case 3: op = rv_op_fcvt_lu_q; break;
2094                 }
2095                 break;
2096             case 104:
2097                 switch (((inst >> 20) & 0b11111)) {
2098                 case 0: op = rv_op_fcvt_s_w; break;
2099                 case 1: op = rv_op_fcvt_s_wu; break;
2100                 case 2: op = rv_op_fcvt_s_l; break;
2101                 case 3: op = rv_op_fcvt_s_lu; break;
2102                 }
2103                 break;
2104             case 105:
2105                 switch (((inst >> 20) & 0b11111)) {
2106                 case 0: op = rv_op_fcvt_d_w; break;
2107                 case 1: op = rv_op_fcvt_d_wu; break;
2108                 case 2: op = rv_op_fcvt_d_l; break;
2109                 case 3: op = rv_op_fcvt_d_lu; break;
2110                 }
2111                 break;
2112             case 107:
2113                 switch (((inst >> 20) & 0b11111)) {
2114                 case 0: op = rv_op_fcvt_q_w; break;
2115                 case 1: op = rv_op_fcvt_q_wu; break;
2116                 case 2: op = rv_op_fcvt_q_l; break;
2117                 case 3: op = rv_op_fcvt_q_lu; break;
2118                 }
2119                 break;
2120             case 112:
2121                 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2122                 case 0: op = rv_op_fmv_x_s; break;
2123                 case 1: op = rv_op_fclass_s; break;
2124                 }
2125                 break;
2126             case 113:
2127                 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2128                 case 0: op = rv_op_fmv_x_d; break;
2129                 case 1: op = rv_op_fclass_d; break;
2130                 }
2131                 break;
2132             case 115:
2133                 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2134                 case 0: op = rv_op_fmv_x_q; break;
2135                 case 1: op = rv_op_fclass_q; break;
2136                 }
2137                 break;
2138             case 120:
2139                 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2140                 case 0: op = rv_op_fmv_s_x; break;
2141                 }
2142                 break;
2143             case 121:
2144                 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2145                 case 0: op = rv_op_fmv_d_x; break;
2146                 }
2147                 break;
2148             case 123:
2149                 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2150                 case 0: op = rv_op_fmv_q_x; break;
2151                 }
2152                 break;
2153             }
2154             break;
2155         case 22:
2156             switch (((inst >> 12) & 0b111)) {
2157             case 0: op = rv_op_addid; break;
2158             case 1:
2159                 switch (((inst >> 26) & 0b111111)) {
2160                 case 0: op = rv_op_sllid; break;
2161                 }
2162                 break;
2163             case 5:
2164                 switch (((inst >> 26) & 0b111111)) {
2165                 case 0: op = rv_op_srlid; break;
2166                 case 16: op = rv_op_sraid; break;
2167                 }
2168                 break;
2169             }
2170             break;
2171         case 24:
2172             switch (((inst >> 12) & 0b111)) {
2173             case 0: op = rv_op_beq; break;
2174             case 1: op = rv_op_bne; break;
2175             case 4: op = rv_op_blt; break;
2176             case 5: op = rv_op_bge; break;
2177             case 6: op = rv_op_bltu; break;
2178             case 7: op = rv_op_bgeu; break;
2179             }
2180             break;
2181         case 25:
2182             switch (((inst >> 12) & 0b111)) {
2183             case 0: op = rv_op_jalr; break;
2184             }
2185             break;
2186         case 27: op = rv_op_jal; break;
2187         case 28:
2188             switch (((inst >> 12) & 0b111)) {
2189             case 0:
2190                 switch (((inst >> 20) & 0b111111100000) | ((inst >> 7) & 0b000000011111)) {
2191                 case 0:
2192                     switch (((inst >> 15) & 0b1111111111)) {
2193                     case 0: op = rv_op_ecall; break;
2194                     case 32: op = rv_op_ebreak; break;
2195                     case 64: op = rv_op_uret; break;
2196                     }
2197                     break;
2198                 case 256:
2199                     switch (((inst >> 20) & 0b11111)) {
2200                     case 2:
2201                         switch (((inst >> 15) & 0b11111)) {
2202                         case 0: op = rv_op_sret; break;
2203                         }
2204                         break;
2205                     case 4: op = rv_op_sfence_vm; break;
2206                     case 5:
2207                         switch (((inst >> 15) & 0b11111)) {
2208                         case 0: op = rv_op_wfi; break;
2209                         }
2210                         break;
2211                     }
2212                     break;
2213                 case 288: op = rv_op_sfence_vma; break;
2214                 case 512:
2215                     switch (((inst >> 15) & 0b1111111111)) {
2216                     case 64: op = rv_op_hret; break;
2217                     }
2218                     break;
2219                 case 768:
2220                     switch (((inst >> 15) & 0b1111111111)) {
2221                     case 64: op = rv_op_mret; break;
2222                     }
2223                     break;
2224                 case 1952:
2225                     switch (((inst >> 15) & 0b1111111111)) {
2226                     case 576: op = rv_op_dret; break;
2227                     }
2228                     break;
2229                 }
2230                 break;
2231             case 1: op = rv_op_csrrw; break;
2232             case 2: op = rv_op_csrrs; break;
2233             case 3: op = rv_op_csrrc; break;
2234             case 5: op = rv_op_csrrwi; break;
2235             case 6: op = rv_op_csrrsi; break;
2236             case 7: op = rv_op_csrrci; break;
2237             }
2238             break;
2239         case 30:
2240             switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
2241             case 0: op = rv_op_addd; break;
2242             case 1: op = rv_op_slld; break;
2243             case 5: op = rv_op_srld; break;
2244             case 8: op = rv_op_muld; break;
2245             case 12: op = rv_op_divd; break;
2246             case 13: op = rv_op_divud; break;
2247             case 14: op = rv_op_remd; break;
2248             case 15: op = rv_op_remud; break;
2249             case 256: op = rv_op_subd; break;
2250             case 261: op = rv_op_srad; break;
2251             }
2252             break;
2253         }
2254         break;
2255     }
2256     dec->op = op;
2257 }
2258 
2259 /* operand extractors */
2260 
2261 static uint32_t operand_rd(rv_inst inst)
2262 {
2263     return (inst << 52) >> 59;
2264 }
2265 
2266 static uint32_t operand_rs1(rv_inst inst)
2267 {
2268     return (inst << 44) >> 59;
2269 }
2270 
2271 static uint32_t operand_rs2(rv_inst inst)
2272 {
2273     return (inst << 39) >> 59;
2274 }
2275 
2276 static uint32_t operand_rs3(rv_inst inst)
2277 {
2278     return (inst << 32) >> 59;
2279 }
2280 
2281 static uint32_t operand_aq(rv_inst inst)
2282 {
2283     return (inst << 37) >> 63;
2284 }
2285 
2286 static uint32_t operand_rl(rv_inst inst)
2287 {
2288     return (inst << 38) >> 63;
2289 }
2290 
2291 static uint32_t operand_pred(rv_inst inst)
2292 {
2293     return (inst << 36) >> 60;
2294 }
2295 
2296 static uint32_t operand_succ(rv_inst inst)
2297 {
2298     return (inst << 40) >> 60;
2299 }
2300 
2301 static uint32_t operand_rm(rv_inst inst)
2302 {
2303     return (inst << 49) >> 61;
2304 }
2305 
2306 static uint32_t operand_shamt5(rv_inst inst)
2307 {
2308     return (inst << 39) >> 59;
2309 }
2310 
2311 static uint32_t operand_shamt6(rv_inst inst)
2312 {
2313     return (inst << 38) >> 58;
2314 }
2315 
2316 static uint32_t operand_shamt7(rv_inst inst)
2317 {
2318     return (inst << 37) >> 57;
2319 }
2320 
2321 static uint32_t operand_crdq(rv_inst inst)
2322 {
2323     return (inst << 59) >> 61;
2324 }
2325 
2326 static uint32_t operand_crs1q(rv_inst inst)
2327 {
2328     return (inst << 54) >> 61;
2329 }
2330 
2331 static uint32_t operand_crs1rdq(rv_inst inst)
2332 {
2333     return (inst << 54) >> 61;
2334 }
2335 
2336 static uint32_t operand_crs2q(rv_inst inst)
2337 {
2338     return (inst << 59) >> 61;
2339 }
2340 
2341 static uint32_t operand_crd(rv_inst inst)
2342 {
2343     return (inst << 52) >> 59;
2344 }
2345 
2346 static uint32_t operand_crs1(rv_inst inst)
2347 {
2348     return (inst << 52) >> 59;
2349 }
2350 
2351 static uint32_t operand_crs1rd(rv_inst inst)
2352 {
2353     return (inst << 52) >> 59;
2354 }
2355 
2356 static uint32_t operand_crs2(rv_inst inst)
2357 {
2358     return (inst << 57) >> 59;
2359 }
2360 
2361 static uint32_t operand_cimmsh5(rv_inst inst)
2362 {
2363     return (inst << 57) >> 59;
2364 }
2365 
2366 static uint32_t operand_csr12(rv_inst inst)
2367 {
2368     return (inst << 32) >> 52;
2369 }
2370 
2371 static int32_t operand_imm12(rv_inst inst)
2372 {
2373     return ((int64_t)inst << 32) >> 52;
2374 }
2375 
2376 static int32_t operand_imm20(rv_inst inst)
2377 {
2378     return (((int64_t)inst << 32) >> 44) << 12;
2379 }
2380 
2381 static int32_t operand_jimm20(rv_inst inst)
2382 {
2383     return (((int64_t)inst << 32) >> 63) << 20 |
2384         ((inst << 33) >> 54) << 1 |
2385         ((inst << 43) >> 63) << 11 |
2386         ((inst << 44) >> 56) << 12;
2387 }
2388 
2389 static int32_t operand_simm12(rv_inst inst)
2390 {
2391     return (((int64_t)inst << 32) >> 57) << 5 |
2392         (inst << 52) >> 59;
2393 }
2394 
2395 static int32_t operand_sbimm12(rv_inst inst)
2396 {
2397     return (((int64_t)inst << 32) >> 63) << 12 |
2398         ((inst << 33) >> 58) << 5 |
2399         ((inst << 52) >> 60) << 1 |
2400         ((inst << 56) >> 63) << 11;
2401 }
2402 
2403 static uint32_t operand_cimmshl6(rv_inst inst, rv_isa isa)
2404 {
2405     int imm = ((inst << 51) >> 63) << 5 |
2406         (inst << 57) >> 59;
2407     if (isa == rv128) {
2408         imm = imm ? imm : 64;
2409     }
2410     return imm;
2411 }
2412 
2413 static uint32_t operand_cimmshr6(rv_inst inst, rv_isa isa)
2414 {
2415     int imm = ((inst << 51) >> 63) << 5 |
2416         (inst << 57) >> 59;
2417     if (isa == rv128) {
2418         imm = imm | (imm & 32) << 1;
2419         imm = imm ? imm : 64;
2420     }
2421     return imm;
2422 }
2423 
2424 static int32_t operand_cimmi(rv_inst inst)
2425 {
2426     return (((int64_t)inst << 51) >> 63) << 5 |
2427         (inst << 57) >> 59;
2428 }
2429 
2430 static int32_t operand_cimmui(rv_inst inst)
2431 {
2432     return (((int64_t)inst << 51) >> 63) << 17 |
2433         ((inst << 57) >> 59) << 12;
2434 }
2435 
2436 static uint32_t operand_cimmlwsp(rv_inst inst)
2437 {
2438     return ((inst << 51) >> 63) << 5 |
2439         ((inst << 57) >> 61) << 2 |
2440         ((inst << 60) >> 62) << 6;
2441 }
2442 
2443 static uint32_t operand_cimmldsp(rv_inst inst)
2444 {
2445     return ((inst << 51) >> 63) << 5 |
2446         ((inst << 57) >> 62) << 3 |
2447         ((inst << 59) >> 61) << 6;
2448 }
2449 
2450 static uint32_t operand_cimmlqsp(rv_inst inst)
2451 {
2452     return ((inst << 51) >> 63) << 5 |
2453         ((inst << 57) >> 63) << 4 |
2454         ((inst << 58) >> 60) << 6;
2455 }
2456 
2457 static int32_t operand_cimm16sp(rv_inst inst)
2458 {
2459     return (((int64_t)inst << 51) >> 63) << 9 |
2460         ((inst << 57) >> 63) << 4 |
2461         ((inst << 58) >> 63) << 6 |
2462         ((inst << 59) >> 62) << 7 |
2463         ((inst << 61) >> 63) << 5;
2464 }
2465 
2466 static int32_t operand_cimmj(rv_inst inst)
2467 {
2468     return (((int64_t)inst << 51) >> 63) << 11 |
2469         ((inst << 52) >> 63) << 4 |
2470         ((inst << 53) >> 62) << 8 |
2471         ((inst << 55) >> 63) << 10 |
2472         ((inst << 56) >> 63) << 6 |
2473         ((inst << 57) >> 63) << 7 |
2474         ((inst << 58) >> 61) << 1 |
2475         ((inst << 61) >> 63) << 5;
2476 }
2477 
2478 static int32_t operand_cimmb(rv_inst inst)
2479 {
2480     return (((int64_t)inst << 51) >> 63) << 8 |
2481         ((inst << 52) >> 62) << 3 |
2482         ((inst << 57) >> 62) << 6 |
2483         ((inst << 59) >> 62) << 1 |
2484         ((inst << 61) >> 63) << 5;
2485 }
2486 
2487 static uint32_t operand_cimmswsp(rv_inst inst)
2488 {
2489     return ((inst << 51) >> 60) << 2 |
2490         ((inst << 55) >> 62) << 6;
2491 }
2492 
2493 static uint32_t operand_cimmsdsp(rv_inst inst)
2494 {
2495     return ((inst << 51) >> 61) << 3 |
2496         ((inst << 54) >> 61) << 6;
2497 }
2498 
2499 static uint32_t operand_cimmsqsp(rv_inst inst)
2500 {
2501     return ((inst << 51) >> 62) << 4 |
2502         ((inst << 53) >> 60) << 6;
2503 }
2504 
2505 static uint32_t operand_cimm4spn(rv_inst inst)
2506 {
2507     return ((inst << 51) >> 62) << 4 |
2508         ((inst << 53) >> 60) << 6 |
2509         ((inst << 57) >> 63) << 2 |
2510         ((inst << 58) >> 63) << 3;
2511 }
2512 
2513 static uint32_t operand_cimmw(rv_inst inst)
2514 {
2515     return ((inst << 51) >> 61) << 3 |
2516         ((inst << 57) >> 63) << 2 |
2517         ((inst << 58) >> 63) << 6;
2518 }
2519 
2520 static uint32_t operand_cimmd(rv_inst inst)
2521 {
2522     return ((inst << 51) >> 61) << 3 |
2523         ((inst << 57) >> 62) << 6;
2524 }
2525 
2526 static uint32_t operand_cimmq(rv_inst inst)
2527 {
2528     return ((inst << 51) >> 62) << 4 |
2529         ((inst << 53) >> 63) << 8 |
2530         ((inst << 57) >> 62) << 6;
2531 }
2532 
2533 static uint32_t operand_bs(rv_inst inst)
2534 {
2535     return (inst << 32) >> 62;
2536 }
2537 
2538 static uint32_t operand_rnum(rv_inst inst)
2539 {
2540     return (inst << 40) >> 60;
2541 }
2542 
2543 /* decode operands */
2544 
2545 static void decode_inst_operands(rv_decode *dec, rv_isa isa)
2546 {
2547     rv_inst inst = dec->inst;
2548     dec->codec = opcode_data[dec->op].codec;
2549     switch (dec->codec) {
2550     case rv_codec_none:
2551         dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2552         dec->imm = 0;
2553         break;
2554     case rv_codec_u:
2555         dec->rd = operand_rd(inst);
2556         dec->rs1 = dec->rs2 = rv_ireg_zero;
2557         dec->imm = operand_imm20(inst);
2558         break;
2559     case rv_codec_uj:
2560         dec->rd = operand_rd(inst);
2561         dec->rs1 = dec->rs2 = rv_ireg_zero;
2562         dec->imm = operand_jimm20(inst);
2563         break;
2564     case rv_codec_i:
2565         dec->rd = operand_rd(inst);
2566         dec->rs1 = operand_rs1(inst);
2567         dec->rs2 = rv_ireg_zero;
2568         dec->imm = operand_imm12(inst);
2569         break;
2570     case rv_codec_i_sh5:
2571         dec->rd = operand_rd(inst);
2572         dec->rs1 = operand_rs1(inst);
2573         dec->rs2 = rv_ireg_zero;
2574         dec->imm = operand_shamt5(inst);
2575         break;
2576     case rv_codec_i_sh6:
2577         dec->rd = operand_rd(inst);
2578         dec->rs1 = operand_rs1(inst);
2579         dec->rs2 = rv_ireg_zero;
2580         dec->imm = operand_shamt6(inst);
2581         break;
2582     case rv_codec_i_sh7:
2583         dec->rd = operand_rd(inst);
2584         dec->rs1 = operand_rs1(inst);
2585         dec->rs2 = rv_ireg_zero;
2586         dec->imm = operand_shamt7(inst);
2587         break;
2588     case rv_codec_i_csr:
2589         dec->rd = operand_rd(inst);
2590         dec->rs1 = operand_rs1(inst);
2591         dec->rs2 = rv_ireg_zero;
2592         dec->imm = operand_csr12(inst);
2593         break;
2594     case rv_codec_s:
2595         dec->rd = rv_ireg_zero;
2596         dec->rs1 = operand_rs1(inst);
2597         dec->rs2 = operand_rs2(inst);
2598         dec->imm = operand_simm12(inst);
2599         break;
2600     case rv_codec_sb:
2601         dec->rd = rv_ireg_zero;
2602         dec->rs1 = operand_rs1(inst);
2603         dec->rs2 = operand_rs2(inst);
2604         dec->imm = operand_sbimm12(inst);
2605         break;
2606     case rv_codec_r:
2607         dec->rd = operand_rd(inst);
2608         dec->rs1 = operand_rs1(inst);
2609         dec->rs2 = operand_rs2(inst);
2610         dec->imm = 0;
2611         break;
2612     case rv_codec_r_m:
2613         dec->rd = operand_rd(inst);
2614         dec->rs1 = operand_rs1(inst);
2615         dec->rs2 = operand_rs2(inst);
2616         dec->imm = 0;
2617         dec->rm = operand_rm(inst);
2618         break;
2619     case rv_codec_r4_m:
2620         dec->rd = operand_rd(inst);
2621         dec->rs1 = operand_rs1(inst);
2622         dec->rs2 = operand_rs2(inst);
2623         dec->rs3 = operand_rs3(inst);
2624         dec->imm = 0;
2625         dec->rm = operand_rm(inst);
2626         break;
2627     case rv_codec_r_a:
2628         dec->rd = operand_rd(inst);
2629         dec->rs1 = operand_rs1(inst);
2630         dec->rs2 = operand_rs2(inst);
2631         dec->imm = 0;
2632         dec->aq = operand_aq(inst);
2633         dec->rl = operand_rl(inst);
2634         break;
2635     case rv_codec_r_l:
2636         dec->rd = operand_rd(inst);
2637         dec->rs1 = operand_rs1(inst);
2638         dec->rs2 = rv_ireg_zero;
2639         dec->imm = 0;
2640         dec->aq = operand_aq(inst);
2641         dec->rl = operand_rl(inst);
2642         break;
2643     case rv_codec_r_f:
2644         dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2645         dec->pred = operand_pred(inst);
2646         dec->succ = operand_succ(inst);
2647         dec->imm = 0;
2648         break;
2649     case rv_codec_cb:
2650         dec->rd = rv_ireg_zero;
2651         dec->rs1 = operand_crs1q(inst) + 8;
2652         dec->rs2 = rv_ireg_zero;
2653         dec->imm = operand_cimmb(inst);
2654         break;
2655     case rv_codec_cb_imm:
2656         dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2657         dec->rs2 = rv_ireg_zero;
2658         dec->imm = operand_cimmi(inst);
2659         break;
2660     case rv_codec_cb_sh5:
2661         dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2662         dec->rs2 = rv_ireg_zero;
2663         dec->imm = operand_cimmsh5(inst);
2664         break;
2665     case rv_codec_cb_sh6:
2666         dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2667         dec->rs2 = rv_ireg_zero;
2668         dec->imm = operand_cimmshr6(inst, isa);
2669         break;
2670     case rv_codec_ci:
2671         dec->rd = dec->rs1 = operand_crs1rd(inst);
2672         dec->rs2 = rv_ireg_zero;
2673         dec->imm = operand_cimmi(inst);
2674         break;
2675     case rv_codec_ci_sh5:
2676         dec->rd = dec->rs1 = operand_crs1rd(inst);
2677         dec->rs2 = rv_ireg_zero;
2678         dec->imm = operand_cimmsh5(inst);
2679         break;
2680     case rv_codec_ci_sh6:
2681         dec->rd = dec->rs1 = operand_crs1rd(inst);
2682         dec->rs2 = rv_ireg_zero;
2683         dec->imm = operand_cimmshl6(inst, isa);
2684         break;
2685     case rv_codec_ci_16sp:
2686         dec->rd = rv_ireg_sp;
2687         dec->rs1 = rv_ireg_sp;
2688         dec->rs2 = rv_ireg_zero;
2689         dec->imm = operand_cimm16sp(inst);
2690         break;
2691     case rv_codec_ci_lwsp:
2692         dec->rd = operand_crd(inst);
2693         dec->rs1 = rv_ireg_sp;
2694         dec->rs2 = rv_ireg_zero;
2695         dec->imm = operand_cimmlwsp(inst);
2696         break;
2697     case rv_codec_ci_ldsp:
2698         dec->rd = operand_crd(inst);
2699         dec->rs1 = rv_ireg_sp;
2700         dec->rs2 = rv_ireg_zero;
2701         dec->imm = operand_cimmldsp(inst);
2702         break;
2703     case rv_codec_ci_lqsp:
2704         dec->rd = operand_crd(inst);
2705         dec->rs1 = rv_ireg_sp;
2706         dec->rs2 = rv_ireg_zero;
2707         dec->imm = operand_cimmlqsp(inst);
2708         break;
2709     case rv_codec_ci_li:
2710         dec->rd = operand_crd(inst);
2711         dec->rs1 = rv_ireg_zero;
2712         dec->rs2 = rv_ireg_zero;
2713         dec->imm = operand_cimmi(inst);
2714         break;
2715     case rv_codec_ci_lui:
2716         dec->rd = operand_crd(inst);
2717         dec->rs1 = rv_ireg_zero;
2718         dec->rs2 = rv_ireg_zero;
2719         dec->imm = operand_cimmui(inst);
2720         break;
2721     case rv_codec_ci_none:
2722         dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2723         dec->imm = 0;
2724         break;
2725     case rv_codec_ciw_4spn:
2726         dec->rd = operand_crdq(inst) + 8;
2727         dec->rs1 = rv_ireg_sp;
2728         dec->rs2 = rv_ireg_zero;
2729         dec->imm = operand_cimm4spn(inst);
2730         break;
2731     case rv_codec_cj:
2732         dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2733         dec->imm = operand_cimmj(inst);
2734         break;
2735     case rv_codec_cj_jal:
2736         dec->rd = rv_ireg_ra;
2737         dec->rs1 = dec->rs2 = rv_ireg_zero;
2738         dec->imm = operand_cimmj(inst);
2739         break;
2740     case rv_codec_cl_lw:
2741         dec->rd = operand_crdq(inst) + 8;
2742         dec->rs1 = operand_crs1q(inst) + 8;
2743         dec->rs2 = rv_ireg_zero;
2744         dec->imm = operand_cimmw(inst);
2745         break;
2746     case rv_codec_cl_ld:
2747         dec->rd = operand_crdq(inst) + 8;
2748         dec->rs1 = operand_crs1q(inst) + 8;
2749         dec->rs2 = rv_ireg_zero;
2750         dec->imm = operand_cimmd(inst);
2751         break;
2752     case rv_codec_cl_lq:
2753         dec->rd = operand_crdq(inst) + 8;
2754         dec->rs1 = operand_crs1q(inst) + 8;
2755         dec->rs2 = rv_ireg_zero;
2756         dec->imm = operand_cimmq(inst);
2757         break;
2758     case rv_codec_cr:
2759         dec->rd = dec->rs1 = operand_crs1rd(inst);
2760         dec->rs2 = operand_crs2(inst);
2761         dec->imm = 0;
2762         break;
2763     case rv_codec_cr_mv:
2764         dec->rd = operand_crd(inst);
2765         dec->rs1 = operand_crs2(inst);
2766         dec->rs2 = rv_ireg_zero;
2767         dec->imm = 0;
2768         break;
2769     case rv_codec_cr_jalr:
2770         dec->rd = rv_ireg_ra;
2771         dec->rs1 = operand_crs1(inst);
2772         dec->rs2 = rv_ireg_zero;
2773         dec->imm = 0;
2774         break;
2775     case rv_codec_cr_jr:
2776         dec->rd = rv_ireg_zero;
2777         dec->rs1 = operand_crs1(inst);
2778         dec->rs2 = rv_ireg_zero;
2779         dec->imm = 0;
2780         break;
2781     case rv_codec_cs:
2782         dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2783         dec->rs2 = operand_crs2q(inst) + 8;
2784         dec->imm = 0;
2785         break;
2786     case rv_codec_cs_sw:
2787         dec->rd = rv_ireg_zero;
2788         dec->rs1 = operand_crs1q(inst) + 8;
2789         dec->rs2 = operand_crs2q(inst) + 8;
2790         dec->imm = operand_cimmw(inst);
2791         break;
2792     case rv_codec_cs_sd:
2793         dec->rd = rv_ireg_zero;
2794         dec->rs1 = operand_crs1q(inst) + 8;
2795         dec->rs2 = operand_crs2q(inst) + 8;
2796         dec->imm = operand_cimmd(inst);
2797         break;
2798     case rv_codec_cs_sq:
2799         dec->rd = rv_ireg_zero;
2800         dec->rs1 = operand_crs1q(inst) + 8;
2801         dec->rs2 = operand_crs2q(inst) + 8;
2802         dec->imm = operand_cimmq(inst);
2803         break;
2804     case rv_codec_css_swsp:
2805         dec->rd = rv_ireg_zero;
2806         dec->rs1 = rv_ireg_sp;
2807         dec->rs2 = operand_crs2(inst);
2808         dec->imm = operand_cimmswsp(inst);
2809         break;
2810     case rv_codec_css_sdsp:
2811         dec->rd = rv_ireg_zero;
2812         dec->rs1 = rv_ireg_sp;
2813         dec->rs2 = operand_crs2(inst);
2814         dec->imm = operand_cimmsdsp(inst);
2815         break;
2816     case rv_codec_css_sqsp:
2817         dec->rd = rv_ireg_zero;
2818         dec->rs1 = rv_ireg_sp;
2819         dec->rs2 = operand_crs2(inst);
2820         dec->imm = operand_cimmsqsp(inst);
2821         break;
2822     case rv_codec_k_bs:
2823         dec->rs1 = operand_rs1(inst);
2824         dec->rs2 = operand_rs2(inst);
2825         dec->bs = operand_bs(inst);
2826         break;
2827     case rv_codec_k_rnum:
2828         dec->rd = operand_rd(inst);
2829         dec->rs1 = operand_rs1(inst);
2830         dec->rnum = operand_rnum(inst);
2831         break;
2832     };
2833 }
2834 
2835 /* check constraint */
2836 
2837 static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
2838 {
2839     int32_t imm = dec->imm;
2840     uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
2841     while (*c != rvc_end) {
2842         switch (*c) {
2843         case rvc_rd_eq_ra:
2844             if (!(rd == 1)) {
2845                 return false;
2846             }
2847             break;
2848         case rvc_rd_eq_x0:
2849             if (!(rd == 0)) {
2850                 return false;
2851             }
2852             break;
2853         case rvc_rs1_eq_x0:
2854             if (!(rs1 == 0)) {
2855                 return false;
2856             }
2857             break;
2858         case rvc_rs2_eq_x0:
2859             if (!(rs2 == 0)) {
2860                 return false;
2861             }
2862             break;
2863         case rvc_rs2_eq_rs1:
2864             if (!(rs2 == rs1)) {
2865                 return false;
2866             }
2867             break;
2868         case rvc_rs1_eq_ra:
2869             if (!(rs1 == 1)) {
2870                 return false;
2871             }
2872             break;
2873         case rvc_imm_eq_zero:
2874             if (!(imm == 0)) {
2875                 return false;
2876             }
2877             break;
2878         case rvc_imm_eq_n1:
2879             if (!(imm == -1)) {
2880                 return false;
2881             }
2882             break;
2883         case rvc_imm_eq_p1:
2884             if (!(imm == 1)) {
2885                 return false;
2886             }
2887             break;
2888         case rvc_csr_eq_0x001:
2889             if (!(imm == 0x001)) {
2890                 return false;
2891             }
2892             break;
2893         case rvc_csr_eq_0x002:
2894             if (!(imm == 0x002)) {
2895                 return false;
2896             }
2897             break;
2898         case rvc_csr_eq_0x003:
2899             if (!(imm == 0x003)) {
2900                 return false;
2901             }
2902             break;
2903         case rvc_csr_eq_0xc00:
2904             if (!(imm == 0xc00)) {
2905                 return false;
2906             }
2907             break;
2908         case rvc_csr_eq_0xc01:
2909             if (!(imm == 0xc01)) {
2910                 return false;
2911             }
2912             break;
2913         case rvc_csr_eq_0xc02:
2914             if (!(imm == 0xc02)) {
2915                 return false;
2916             }
2917             break;
2918         case rvc_csr_eq_0xc80:
2919             if (!(imm == 0xc80)) {
2920                 return false;
2921             }
2922             break;
2923         case rvc_csr_eq_0xc81:
2924             if (!(imm == 0xc81)) {
2925                 return false;
2926             }
2927             break;
2928         case rvc_csr_eq_0xc82:
2929             if (!(imm == 0xc82)) {
2930                 return false;
2931             }
2932             break;
2933         default: break;
2934         }
2935         c++;
2936     }
2937     return true;
2938 }
2939 
2940 /* instruction length */
2941 
2942 static size_t inst_length(rv_inst inst)
2943 {
2944     /* NOTE: supports maximum instruction size of 64-bits */
2945 
2946     /* instruction length coding
2947      *
2948      *      aa - 16 bit aa != 11
2949      *   bbb11 - 32 bit bbb != 111
2950      *  011111 - 48 bit
2951      * 0111111 - 64 bit
2952      */
2953 
2954     return (inst &      0b11) != 0b11      ? 2
2955          : (inst &   0b11100) != 0b11100   ? 4
2956          : (inst &  0b111111) == 0b011111  ? 6
2957          : (inst & 0b1111111) == 0b0111111 ? 8
2958          : 0;
2959 }
2960 
2961 /* format instruction */
2962 
2963 static void append(char *s1, const char *s2, size_t n)
2964 {
2965     size_t l1 = strlen(s1);
2966     if (n - l1 - 1 > 0) {
2967         strncat(s1, s2, n - l1);
2968     }
2969 }
2970 
2971 static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
2972 {
2973     char tmp[64];
2974     const char *fmt;
2975 
2976     fmt = opcode_data[dec->op].format;
2977     while (*fmt) {
2978         switch (*fmt) {
2979         case 'O':
2980             append(buf, opcode_data[dec->op].name, buflen);
2981             break;
2982         case '(':
2983             append(buf, "(", buflen);
2984             break;
2985         case ',':
2986             append(buf, ",", buflen);
2987             break;
2988         case ')':
2989             append(buf, ")", buflen);
2990             break;
2991         case 'b':
2992             snprintf(tmp, sizeof(tmp), "%d", dec->bs);
2993             append(buf, tmp, buflen);
2994             break;
2995         case 'n':
2996             snprintf(tmp, sizeof(tmp), "%d", dec->rnum);
2997             append(buf, tmp, buflen);
2998             break;
2999         case '0':
3000             append(buf, rv_ireg_name_sym[dec->rd], buflen);
3001             break;
3002         case '1':
3003             append(buf, rv_ireg_name_sym[dec->rs1], buflen);
3004             break;
3005         case '2':
3006             append(buf, rv_ireg_name_sym[dec->rs2], buflen);
3007             break;
3008         case '3':
3009             append(buf, rv_freg_name_sym[dec->rd], buflen);
3010             break;
3011         case '4':
3012             append(buf, rv_freg_name_sym[dec->rs1], buflen);
3013             break;
3014         case '5':
3015             append(buf, rv_freg_name_sym[dec->rs2], buflen);
3016             break;
3017         case '6':
3018             append(buf, rv_freg_name_sym[dec->rs3], buflen);
3019             break;
3020         case '7':
3021             snprintf(tmp, sizeof(tmp), "%d", dec->rs1);
3022             append(buf, tmp, buflen);
3023             break;
3024         case 'i':
3025             snprintf(tmp, sizeof(tmp), "%d", dec->imm);
3026             append(buf, tmp, buflen);
3027             break;
3028         case 'o':
3029             snprintf(tmp, sizeof(tmp), "%d", dec->imm);
3030             append(buf, tmp, buflen);
3031             while (strlen(buf) < tab * 2) {
3032                 append(buf, " ", buflen);
3033             }
3034             snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
3035                 dec->pc + dec->imm);
3036             append(buf, tmp, buflen);
3037             break;
3038         case 'c': {
3039             const char *name = csr_name(dec->imm & 0xfff);
3040             if (name) {
3041                 append(buf, name, buflen);
3042             } else {
3043                 snprintf(tmp, sizeof(tmp), "0x%03x", dec->imm & 0xfff);
3044                 append(buf, tmp, buflen);
3045             }
3046             break;
3047         }
3048         case 'r':
3049             switch (dec->rm) {
3050             case rv_rm_rne:
3051                 append(buf, "rne", buflen);
3052                 break;
3053             case rv_rm_rtz:
3054                 append(buf, "rtz", buflen);
3055                 break;
3056             case rv_rm_rdn:
3057                 append(buf, "rdn", buflen);
3058                 break;
3059             case rv_rm_rup:
3060                 append(buf, "rup", buflen);
3061                 break;
3062             case rv_rm_rmm:
3063                 append(buf, "rmm", buflen);
3064                 break;
3065             case rv_rm_dyn:
3066                 append(buf, "dyn", buflen);
3067                 break;
3068             default:
3069                 append(buf, "inv", buflen);
3070                 break;
3071             }
3072             break;
3073         case 'p':
3074             if (dec->pred & rv_fence_i) {
3075                 append(buf, "i", buflen);
3076             }
3077             if (dec->pred & rv_fence_o) {
3078                 append(buf, "o", buflen);
3079             }
3080             if (dec->pred & rv_fence_r) {
3081                 append(buf, "r", buflen);
3082             }
3083             if (dec->pred & rv_fence_w) {
3084                 append(buf, "w", buflen);
3085             }
3086             break;
3087         case 's':
3088             if (dec->succ & rv_fence_i) {
3089                 append(buf, "i", buflen);
3090             }
3091             if (dec->succ & rv_fence_o) {
3092                 append(buf, "o", buflen);
3093             }
3094             if (dec->succ & rv_fence_r) {
3095                 append(buf, "r", buflen);
3096             }
3097             if (dec->succ & rv_fence_w) {
3098                 append(buf, "w", buflen);
3099             }
3100             break;
3101         case '\t':
3102             while (strlen(buf) < tab) {
3103                 append(buf, " ", buflen);
3104             }
3105             break;
3106         case 'A':
3107             if (dec->aq) {
3108                 append(buf, ".aq", buflen);
3109             }
3110             break;
3111         case 'R':
3112             if (dec->rl) {
3113                 append(buf, ".rl", buflen);
3114             }
3115             break;
3116         default:
3117             break;
3118         }
3119         fmt++;
3120     }
3121 }
3122 
3123 /* lift instruction to pseudo-instruction */
3124 
3125 static void decode_inst_lift_pseudo(rv_decode *dec)
3126 {
3127     const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
3128     if (!comp_data) {
3129         return;
3130     }
3131     while (comp_data->constraints) {
3132         if (check_constraints(dec, comp_data->constraints)) {
3133             dec->op = comp_data->op;
3134             dec->codec = opcode_data[dec->op].codec;
3135             return;
3136         }
3137         comp_data++;
3138     }
3139 }
3140 
3141 /* decompress instruction */
3142 
3143 static void decode_inst_decompress_rv32(rv_decode *dec)
3144 {
3145     int decomp_op = opcode_data[dec->op].decomp_rv32;
3146     if (decomp_op != rv_op_illegal) {
3147         if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3148             && dec->imm == 0) {
3149             dec->op = rv_op_illegal;
3150         } else {
3151             dec->op = decomp_op;
3152             dec->codec = opcode_data[decomp_op].codec;
3153         }
3154     }
3155 }
3156 
3157 static void decode_inst_decompress_rv64(rv_decode *dec)
3158 {
3159     int decomp_op = opcode_data[dec->op].decomp_rv64;
3160     if (decomp_op != rv_op_illegal) {
3161         if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3162             && dec->imm == 0) {
3163             dec->op = rv_op_illegal;
3164         } else {
3165             dec->op = decomp_op;
3166             dec->codec = opcode_data[decomp_op].codec;
3167         }
3168     }
3169 }
3170 
3171 static void decode_inst_decompress_rv128(rv_decode *dec)
3172 {
3173     int decomp_op = opcode_data[dec->op].decomp_rv128;
3174     if (decomp_op != rv_op_illegal) {
3175         if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3176             && dec->imm == 0) {
3177             dec->op = rv_op_illegal;
3178         } else {
3179             dec->op = decomp_op;
3180             dec->codec = opcode_data[decomp_op].codec;
3181         }
3182     }
3183 }
3184 
3185 static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
3186 {
3187     switch (isa) {
3188     case rv32:
3189         decode_inst_decompress_rv32(dec);
3190         break;
3191     case rv64:
3192         decode_inst_decompress_rv64(dec);
3193         break;
3194     case rv128:
3195         decode_inst_decompress_rv128(dec);
3196         break;
3197     }
3198 }
3199 
3200 /* disassemble instruction */
3201 
3202 static void
3203 disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
3204 {
3205     rv_decode dec = { 0 };
3206     dec.pc = pc;
3207     dec.inst = inst;
3208     decode_inst_opcode(&dec, isa);
3209     decode_inst_operands(&dec, isa);
3210     decode_inst_decompress(&dec, isa);
3211     decode_inst_lift_pseudo(&dec);
3212     format_inst(buf, buflen, 16, &dec);
3213 }
3214 
3215 #define INST_FMT_2 "%04" PRIx64 "              "
3216 #define INST_FMT_4 "%08" PRIx64 "          "
3217 #define INST_FMT_6 "%012" PRIx64 "      "
3218 #define INST_FMT_8 "%016" PRIx64 "  "
3219 
3220 static int
3221 print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
3222 {
3223     char buf[128] = { 0 };
3224     bfd_byte packet[2];
3225     rv_inst inst = 0;
3226     size_t len = 2;
3227     bfd_vma n;
3228     int status;
3229 
3230     /* Instructions are made of 2-byte packets in little-endian order */
3231     for (n = 0; n < len; n += 2) {
3232         status = (*info->read_memory_func)(memaddr + n, packet, 2, info);
3233         if (status != 0) {
3234             /* Don't fail just because we fell off the end.  */
3235             if (n > 0) {
3236                 break;
3237             }
3238             (*info->memory_error_func)(status, memaddr, info);
3239             return status;
3240         }
3241         inst |= ((rv_inst) bfd_getl16(packet)) << (8 * n);
3242         if (n == 0) {
3243             len = inst_length(inst);
3244         }
3245     }
3246 
3247     switch (len) {
3248     case 2:
3249         (*info->fprintf_func)(info->stream, INST_FMT_2, inst);
3250         break;
3251     case 4:
3252         (*info->fprintf_func)(info->stream, INST_FMT_4, inst);
3253         break;
3254     case 6:
3255         (*info->fprintf_func)(info->stream, INST_FMT_6, inst);
3256         break;
3257     default:
3258         (*info->fprintf_func)(info->stream, INST_FMT_8, inst);
3259         break;
3260     }
3261 
3262     disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
3263     (*info->fprintf_func)(info->stream, "%s", buf);
3264 
3265     return len;
3266 }
3267 
3268 int print_insn_riscv32(bfd_vma memaddr, struct disassemble_info *info)
3269 {
3270     return print_insn_riscv(memaddr, info, rv32);
3271 }
3272 
3273 int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info)
3274 {
3275     return print_insn_riscv(memaddr, info, rv64);
3276 }
3277 
3278 int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
3279 {
3280     return print_insn_riscv(memaddr, info, rv128);
3281 }
3282