Merge tag 'pull-la-20220808' of https://gitlab.com/rth7680/qemu into staging
[qemu.git] / disas / riscv.c
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
3094 int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
3095 {
3096 return print_insn_riscv(memaddr, info, rv128);
3097 }