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