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