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