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