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