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