semihosting: Create semihost_sys_poll_one
[qemu/rayw.git] / disas / riscv.c
blob7af6afc8fa8fabccdfcce7f14e40d81eec932487
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 0x0102: return "sedeleg";
1308 case 0x0103: return "sideleg";
1309 case 0x0104: return "sie";
1310 case 0x0105: return "stvec";
1311 case 0x0106: return "scounteren";
1312 case 0x0140: return "sscratch";
1313 case 0x0141: return "sepc";
1314 case 0x0142: return "scause";
1315 case 0x0143: return "stval";
1316 case 0x0144: return "sip";
1317 case 0x0180: return "satp";
1318 case 0x0200: return "hstatus";
1319 case 0x0202: return "hedeleg";
1320 case 0x0203: return "hideleg";
1321 case 0x0204: return "hie";
1322 case 0x0205: return "htvec";
1323 case 0x0240: return "hscratch";
1324 case 0x0241: return "hepc";
1325 case 0x0242: return "hcause";
1326 case 0x0243: return "hbadaddr";
1327 case 0x0244: return "hip";
1328 case 0x0300: return "mstatus";
1329 case 0x0301: return "misa";
1330 case 0x0302: return "medeleg";
1331 case 0x0303: return "mideleg";
1332 case 0x0304: return "mie";
1333 case 0x0305: return "mtvec";
1334 case 0x0306: return "mcounteren";
1335 case 0x0320: return "mucounteren";
1336 case 0x0321: return "mscounteren";
1337 case 0x0322: return "mhcounteren";
1338 case 0x0323: return "mhpmevent3";
1339 case 0x0324: return "mhpmevent4";
1340 case 0x0325: return "mhpmevent5";
1341 case 0x0326: return "mhpmevent6";
1342 case 0x0327: return "mhpmevent7";
1343 case 0x0328: return "mhpmevent8";
1344 case 0x0329: return "mhpmevent9";
1345 case 0x032a: return "mhpmevent10";
1346 case 0x032b: return "mhpmevent11";
1347 case 0x032c: return "mhpmevent12";
1348 case 0x032d: return "mhpmevent13";
1349 case 0x032e: return "mhpmevent14";
1350 case 0x032f: return "mhpmevent15";
1351 case 0x0330: return "mhpmevent16";
1352 case 0x0331: return "mhpmevent17";
1353 case 0x0332: return "mhpmevent18";
1354 case 0x0333: return "mhpmevent19";
1355 case 0x0334: return "mhpmevent20";
1356 case 0x0335: return "mhpmevent21";
1357 case 0x0336: return "mhpmevent22";
1358 case 0x0337: return "mhpmevent23";
1359 case 0x0338: return "mhpmevent24";
1360 case 0x0339: return "mhpmevent25";
1361 case 0x033a: return "mhpmevent26";
1362 case 0x033b: return "mhpmevent27";
1363 case 0x033c: return "mhpmevent28";
1364 case 0x033d: return "mhpmevent29";
1365 case 0x033e: return "mhpmevent30";
1366 case 0x033f: return "mhpmevent31";
1367 case 0x0340: return "mscratch";
1368 case 0x0341: return "mepc";
1369 case 0x0342: return "mcause";
1370 case 0x0343: return "mtval";
1371 case 0x0344: return "mip";
1372 case 0x0380: return "mbase";
1373 case 0x0381: return "mbound";
1374 case 0x0382: return "mibase";
1375 case 0x0383: return "mibound";
1376 case 0x0384: return "mdbase";
1377 case 0x0385: return "mdbound";
1378 case 0x03a0: return "pmpcfg3";
1379 case 0x03b0: return "pmpaddr0";
1380 case 0x03b1: return "pmpaddr1";
1381 case 0x03b2: return "pmpaddr2";
1382 case 0x03b3: return "pmpaddr3";
1383 case 0x03b4: return "pmpaddr4";
1384 case 0x03b5: return "pmpaddr5";
1385 case 0x03b6: return "pmpaddr6";
1386 case 0x03b7: return "pmpaddr7";
1387 case 0x03b8: return "pmpaddr8";
1388 case 0x03b9: return "pmpaddr9";
1389 case 0x03ba: return "pmpaddr10";
1390 case 0x03bb: return "pmpaddr11";
1391 case 0x03bc: return "pmpaddr12";
1392 case 0x03bd: return "pmpaddr14";
1393 case 0x03be: return "pmpaddr13";
1394 case 0x03bf: return "pmpaddr15";
1395 case 0x0780: return "mtohost";
1396 case 0x0781: return "mfromhost";
1397 case 0x0782: return "mreset";
1398 case 0x0783: return "mipi";
1399 case 0x0784: return "miobase";
1400 case 0x07a0: return "tselect";
1401 case 0x07a1: return "tdata1";
1402 case 0x07a2: return "tdata2";
1403 case 0x07a3: return "tdata3";
1404 case 0x07b0: return "dcsr";
1405 case 0x07b1: return "dpc";
1406 case 0x07b2: return "dscratch";
1407 case 0x0b00: return "mcycle";
1408 case 0x0b01: return "mtime";
1409 case 0x0b02: return "minstret";
1410 case 0x0b03: return "mhpmcounter3";
1411 case 0x0b04: return "mhpmcounter4";
1412 case 0x0b05: return "mhpmcounter5";
1413 case 0x0b06: return "mhpmcounter6";
1414 case 0x0b07: return "mhpmcounter7";
1415 case 0x0b08: return "mhpmcounter8";
1416 case 0x0b09: return "mhpmcounter9";
1417 case 0x0b0a: return "mhpmcounter10";
1418 case 0x0b0b: return "mhpmcounter11";
1419 case 0x0b0c: return "mhpmcounter12";
1420 case 0x0b0d: return "mhpmcounter13";
1421 case 0x0b0e: return "mhpmcounter14";
1422 case 0x0b0f: return "mhpmcounter15";
1423 case 0x0b10: return "mhpmcounter16";
1424 case 0x0b11: return "mhpmcounter17";
1425 case 0x0b12: return "mhpmcounter18";
1426 case 0x0b13: return "mhpmcounter19";
1427 case 0x0b14: return "mhpmcounter20";
1428 case 0x0b15: return "mhpmcounter21";
1429 case 0x0b16: return "mhpmcounter22";
1430 case 0x0b17: return "mhpmcounter23";
1431 case 0x0b18: return "mhpmcounter24";
1432 case 0x0b19: return "mhpmcounter25";
1433 case 0x0b1a: return "mhpmcounter26";
1434 case 0x0b1b: return "mhpmcounter27";
1435 case 0x0b1c: return "mhpmcounter28";
1436 case 0x0b1d: return "mhpmcounter29";
1437 case 0x0b1e: return "mhpmcounter30";
1438 case 0x0b1f: return "mhpmcounter31";
1439 case 0x0b80: return "mcycleh";
1440 case 0x0b81: return "mtimeh";
1441 case 0x0b82: return "minstreth";
1442 case 0x0b83: return "mhpmcounter3h";
1443 case 0x0b84: return "mhpmcounter4h";
1444 case 0x0b85: return "mhpmcounter5h";
1445 case 0x0b86: return "mhpmcounter6h";
1446 case 0x0b87: return "mhpmcounter7h";
1447 case 0x0b88: return "mhpmcounter8h";
1448 case 0x0b89: return "mhpmcounter9h";
1449 case 0x0b8a: return "mhpmcounter10h";
1450 case 0x0b8b: return "mhpmcounter11h";
1451 case 0x0b8c: return "mhpmcounter12h";
1452 case 0x0b8d: return "mhpmcounter13h";
1453 case 0x0b8e: return "mhpmcounter14h";
1454 case 0x0b8f: return "mhpmcounter15h";
1455 case 0x0b90: return "mhpmcounter16h";
1456 case 0x0b91: return "mhpmcounter17h";
1457 case 0x0b92: return "mhpmcounter18h";
1458 case 0x0b93: return "mhpmcounter19h";
1459 case 0x0b94: return "mhpmcounter20h";
1460 case 0x0b95: return "mhpmcounter21h";
1461 case 0x0b96: return "mhpmcounter22h";
1462 case 0x0b97: return "mhpmcounter23h";
1463 case 0x0b98: return "mhpmcounter24h";
1464 case 0x0b99: return "mhpmcounter25h";
1465 case 0x0b9a: return "mhpmcounter26h";
1466 case 0x0b9b: return "mhpmcounter27h";
1467 case 0x0b9c: return "mhpmcounter28h";
1468 case 0x0b9d: return "mhpmcounter29h";
1469 case 0x0b9e: return "mhpmcounter30h";
1470 case 0x0b9f: return "mhpmcounter31h";
1471 case 0x0c00: return "cycle";
1472 case 0x0c01: return "time";
1473 case 0x0c02: return "instret";
1474 case 0x0c80: return "cycleh";
1475 case 0x0c81: return "timeh";
1476 case 0x0c82: return "instreth";
1477 case 0x0d00: return "scycle";
1478 case 0x0d01: return "stime";
1479 case 0x0d02: return "sinstret";
1480 case 0x0d80: return "scycleh";
1481 case 0x0d81: return "stimeh";
1482 case 0x0d82: return "sinstreth";
1483 case 0x0e00: return "hcycle";
1484 case 0x0e01: return "htime";
1485 case 0x0e02: return "hinstret";
1486 case 0x0e80: return "hcycleh";
1487 case 0x0e81: return "htimeh";
1488 case 0x0e82: return "hinstreth";
1489 case 0x0f11: return "mvendorid";
1490 case 0x0f12: return "marchid";
1491 case 0x0f13: return "mimpid";
1492 case 0x0f14: return "mhartid";
1493 default: return NULL;
1497 /* decode opcode */
1499 static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
1501 rv_inst inst = dec->inst;
1502 rv_opcode op = rv_op_illegal;
1503 switch (((inst >> 0) & 0b11)) {
1504 case 0:
1505 switch (((inst >> 13) & 0b111)) {
1506 case 0: op = rv_op_c_addi4spn; break;
1507 case 1:
1508 if (isa == rv128) {
1509 op = rv_op_c_lq;
1510 } else {
1511 op = rv_op_c_fld;
1513 break;
1514 case 2: op = rv_op_c_lw; break;
1515 case 3:
1516 if (isa == rv32) {
1517 op = rv_op_c_flw;
1518 } else {
1519 op = rv_op_c_ld;
1521 break;
1522 case 5:
1523 if (isa == rv128) {
1524 op = rv_op_c_sq;
1525 } else {
1526 op = rv_op_c_fsd;
1528 break;
1529 case 6: op = rv_op_c_sw; break;
1530 case 7:
1531 if (isa == rv32) {
1532 op = rv_op_c_fsw;
1533 } else {
1534 op = rv_op_c_sd;
1536 break;
1538 break;
1539 case 1:
1540 switch (((inst >> 13) & 0b111)) {
1541 case 0:
1542 switch (((inst >> 2) & 0b11111111111)) {
1543 case 0: op = rv_op_c_nop; break;
1544 default: op = rv_op_c_addi; break;
1546 break;
1547 case 1:
1548 if (isa == rv32) {
1549 op = rv_op_c_jal;
1550 } else {
1551 op = rv_op_c_addiw;
1553 break;
1554 case 2: op = rv_op_c_li; break;
1555 case 3:
1556 switch (((inst >> 7) & 0b11111)) {
1557 case 2: op = rv_op_c_addi16sp; break;
1558 default: op = rv_op_c_lui; break;
1560 break;
1561 case 4:
1562 switch (((inst >> 10) & 0b11)) {
1563 case 0:
1564 op = rv_op_c_srli;
1565 break;
1566 case 1:
1567 op = rv_op_c_srai;
1568 break;
1569 case 2: op = rv_op_c_andi; break;
1570 case 3:
1571 switch (((inst >> 10) & 0b100) | ((inst >> 5) & 0b011)) {
1572 case 0: op = rv_op_c_sub; break;
1573 case 1: op = rv_op_c_xor; break;
1574 case 2: op = rv_op_c_or; break;
1575 case 3: op = rv_op_c_and; break;
1576 case 4: op = rv_op_c_subw; break;
1577 case 5: op = rv_op_c_addw; break;
1579 break;
1581 break;
1582 case 5: op = rv_op_c_j; break;
1583 case 6: op = rv_op_c_beqz; break;
1584 case 7: op = rv_op_c_bnez; break;
1586 break;
1587 case 2:
1588 switch (((inst >> 13) & 0b111)) {
1589 case 0:
1590 op = rv_op_c_slli;
1591 break;
1592 case 1:
1593 if (isa == rv128) {
1594 op = rv_op_c_lqsp;
1595 } else {
1596 op = rv_op_c_fldsp;
1598 break;
1599 case 2: op = rv_op_c_lwsp; break;
1600 case 3:
1601 if (isa == rv32) {
1602 op = rv_op_c_flwsp;
1603 } else {
1604 op = rv_op_c_ldsp;
1606 break;
1607 case 4:
1608 switch (((inst >> 12) & 0b1)) {
1609 case 0:
1610 switch (((inst >> 2) & 0b11111)) {
1611 case 0: op = rv_op_c_jr; break;
1612 default: op = rv_op_c_mv; break;
1614 break;
1615 case 1:
1616 switch (((inst >> 2) & 0b11111)) {
1617 case 0:
1618 switch (((inst >> 7) & 0b11111)) {
1619 case 0: op = rv_op_c_ebreak; break;
1620 default: op = rv_op_c_jalr; break;
1622 break;
1623 default: op = rv_op_c_add; break;
1625 break;
1627 break;
1628 case 5:
1629 if (isa == rv128) {
1630 op = rv_op_c_sqsp;
1631 } else {
1632 op = rv_op_c_fsdsp;
1634 break;
1635 case 6: op = rv_op_c_swsp; break;
1636 case 7:
1637 if (isa == rv32) {
1638 op = rv_op_c_fswsp;
1639 } else {
1640 op = rv_op_c_sdsp;
1642 break;
1644 break;
1645 case 3:
1646 switch (((inst >> 2) & 0b11111)) {
1647 case 0:
1648 switch (((inst >> 12) & 0b111)) {
1649 case 0: op = rv_op_lb; break;
1650 case 1: op = rv_op_lh; break;
1651 case 2: op = rv_op_lw; break;
1652 case 3: op = rv_op_ld; break;
1653 case 4: op = rv_op_lbu; break;
1654 case 5: op = rv_op_lhu; break;
1655 case 6: op = rv_op_lwu; break;
1656 case 7: op = rv_op_ldu; break;
1658 break;
1659 case 1:
1660 switch (((inst >> 12) & 0b111)) {
1661 case 2: op = rv_op_flw; break;
1662 case 3: op = rv_op_fld; break;
1663 case 4: op = rv_op_flq; break;
1665 break;
1666 case 3:
1667 switch (((inst >> 12) & 0b111)) {
1668 case 0: op = rv_op_fence; break;
1669 case 1: op = rv_op_fence_i; break;
1670 case 2: op = rv_op_lq; break;
1672 break;
1673 case 4:
1674 switch (((inst >> 12) & 0b111)) {
1675 case 0: op = rv_op_addi; break;
1676 case 1:
1677 switch (((inst >> 27) & 0b11111)) {
1678 case 0b00000: op = rv_op_slli; break;
1679 case 0b00001:
1680 switch (((inst >> 20) & 0b1111111)) {
1681 case 0b0001111: op = rv_op_zip; break;
1683 break;
1684 case 0b00010:
1685 switch (((inst >> 20) & 0b1111111)) {
1686 case 0b0000000: op = rv_op_sha256sum0; break;
1687 case 0b0000001: op = rv_op_sha256sum1; break;
1688 case 0b0000010: op = rv_op_sha256sig0; break;
1689 case 0b0000011: op = rv_op_sha256sig1; break;
1690 case 0b0000100: op = rv_op_sha512sum0; break;
1691 case 0b0000101: op = rv_op_sha512sum1; break;
1692 case 0b0000110: op = rv_op_sha512sig0; break;
1693 case 0b0000111: op = rv_op_sha512sig1; break;
1694 case 0b0001000: op = rv_op_sm3p0; break;
1695 case 0b0001001: op = rv_op_sm3p1; break;
1697 break;
1698 case 0b00101: op = rv_op_bseti; break;
1699 case 0b00110:
1700 switch (((inst >> 20) & 0b1111111)) {
1701 case 0b0000000: op = rv_op_aes64im; break;
1702 default:
1703 if (((inst >> 24) & 0b0111) == 0b001) {
1704 op = rv_op_aes64ks1i;
1706 break;
1708 break;
1709 case 0b01001: op = rv_op_bclri; break;
1710 case 0b01101: op = rv_op_binvi; break;
1711 case 0b01100:
1712 switch (((inst >> 20) & 0b1111111)) {
1713 case 0b0000000: op = rv_op_clz; break;
1714 case 0b0000001: op = rv_op_ctz; break;
1715 case 0b0000010: op = rv_op_cpop; break;
1716 /* 0b0000011 */
1717 case 0b0000100: op = rv_op_sext_b; break;
1718 case 0b0000101: op = rv_op_sext_h; break;
1720 break;
1722 break;
1723 case 2: op = rv_op_slti; break;
1724 case 3: op = rv_op_sltiu; break;
1725 case 4: op = rv_op_xori; break;
1726 case 5:
1727 switch (((inst >> 27) & 0b11111)) {
1728 case 0b00000: op = rv_op_srli; break;
1729 case 0b00001:
1730 switch (((inst >> 20) & 0b1111111)) {
1731 case 0b0001111: op = rv_op_unzip; break;
1733 break;
1734 case 0b00101: op = rv_op_orc_b; break;
1735 case 0b01000: op = rv_op_srai; break;
1736 case 0b01001: op = rv_op_bexti; break;
1737 case 0b01100: op = rv_op_rori; break;
1738 case 0b01101:
1739 switch ((inst >> 20) & 0b1111111) {
1740 case 0b0011000: op = rv_op_rev8; break;
1741 case 0b0111000: op = rv_op_rev8; break;
1742 case 0b0000111: op = rv_op_brev8; break;
1744 break;
1746 break;
1747 case 6: op = rv_op_ori; break;
1748 case 7: op = rv_op_andi; break;
1750 break;
1751 case 5: op = rv_op_auipc; break;
1752 case 6:
1753 switch (((inst >> 12) & 0b111)) {
1754 case 0: op = rv_op_addiw; break;
1755 case 1:
1756 switch (((inst >> 25) & 0b1111111)) {
1757 case 0: op = rv_op_slliw; break;
1758 case 4: op = rv_op_slli_uw; break;
1759 case 48:
1760 switch ((inst >> 20) & 0b11111) {
1761 case 0b00000: op = rv_op_clzw; break;
1762 case 0b00001: op = rv_op_ctzw; break;
1763 case 0b00010: op = rv_op_cpopw; break;
1765 break;
1767 break;
1768 case 5:
1769 switch (((inst >> 25) & 0b1111111)) {
1770 case 0: op = rv_op_srliw; break;
1771 case 32: op = rv_op_sraiw; break;
1772 case 48: op = rv_op_roriw; break;
1774 break;
1776 break;
1777 case 8:
1778 switch (((inst >> 12) & 0b111)) {
1779 case 0: op = rv_op_sb; break;
1780 case 1: op = rv_op_sh; break;
1781 case 2: op = rv_op_sw; break;
1782 case 3: op = rv_op_sd; break;
1783 case 4: op = rv_op_sq; break;
1785 break;
1786 case 9:
1787 switch (((inst >> 12) & 0b111)) {
1788 case 2: op = rv_op_fsw; break;
1789 case 3: op = rv_op_fsd; break;
1790 case 4: op = rv_op_fsq; break;
1792 break;
1793 case 11:
1794 switch (((inst >> 24) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
1795 case 2: op = rv_op_amoadd_w; break;
1796 case 3: op = rv_op_amoadd_d; break;
1797 case 4: op = rv_op_amoadd_q; break;
1798 case 10: op = rv_op_amoswap_w; break;
1799 case 11: op = rv_op_amoswap_d; break;
1800 case 12: op = rv_op_amoswap_q; break;
1801 case 18:
1802 switch (((inst >> 20) & 0b11111)) {
1803 case 0: op = rv_op_lr_w; break;
1805 break;
1806 case 19:
1807 switch (((inst >> 20) & 0b11111)) {
1808 case 0: op = rv_op_lr_d; break;
1810 break;
1811 case 20:
1812 switch (((inst >> 20) & 0b11111)) {
1813 case 0: op = rv_op_lr_q; break;
1815 break;
1816 case 26: op = rv_op_sc_w; break;
1817 case 27: op = rv_op_sc_d; break;
1818 case 28: op = rv_op_sc_q; break;
1819 case 34: op = rv_op_amoxor_w; break;
1820 case 35: op = rv_op_amoxor_d; break;
1821 case 36: op = rv_op_amoxor_q; break;
1822 case 66: op = rv_op_amoor_w; break;
1823 case 67: op = rv_op_amoor_d; break;
1824 case 68: op = rv_op_amoor_q; break;
1825 case 98: op = rv_op_amoand_w; break;
1826 case 99: op = rv_op_amoand_d; break;
1827 case 100: op = rv_op_amoand_q; break;
1828 case 130: op = rv_op_amomin_w; break;
1829 case 131: op = rv_op_amomin_d; break;
1830 case 132: op = rv_op_amomin_q; break;
1831 case 162: op = rv_op_amomax_w; break;
1832 case 163: op = rv_op_amomax_d; break;
1833 case 164: op = rv_op_amomax_q; break;
1834 case 194: op = rv_op_amominu_w; break;
1835 case 195: op = rv_op_amominu_d; break;
1836 case 196: op = rv_op_amominu_q; break;
1837 case 226: op = rv_op_amomaxu_w; break;
1838 case 227: op = rv_op_amomaxu_d; break;
1839 case 228: op = rv_op_amomaxu_q; break;
1841 break;
1842 case 12:
1843 switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1844 case 0: op = rv_op_add; break;
1845 case 1: op = rv_op_sll; break;
1846 case 2: op = rv_op_slt; break;
1847 case 3: op = rv_op_sltu; break;
1848 case 4: op = rv_op_xor; break;
1849 case 5: op = rv_op_srl; break;
1850 case 6: op = rv_op_or; break;
1851 case 7: op = rv_op_and; break;
1852 case 8: op = rv_op_mul; break;
1853 case 9: op = rv_op_mulh; break;
1854 case 10: op = rv_op_mulhsu; break;
1855 case 11: op = rv_op_mulhu; break;
1856 case 12: op = rv_op_div; break;
1857 case 13: op = rv_op_divu; break;
1858 case 14: op = rv_op_rem; break;
1859 case 15: op = rv_op_remu; break;
1860 case 36:
1861 switch ((inst >> 20) & 0b11111) {
1862 case 0: op = rv_op_zext_h; break;
1863 default: op = rv_op_pack; break;
1865 break;
1866 case 39: op = rv_op_packh; break;
1868 case 41: op = rv_op_clmul; break;
1869 case 42: op = rv_op_clmulr; break;
1870 case 43: op = rv_op_clmulh; break;
1871 case 44: op = rv_op_min; break;
1872 case 45: op = rv_op_minu; break;
1873 case 46: op = rv_op_max; break;
1874 case 47: op = rv_op_maxu; break;
1875 case 130: op = rv_op_sh1add; break;
1876 case 132: op = rv_op_sh2add; break;
1877 case 134: op = rv_op_sh3add; break;
1878 case 161: op = rv_op_bset; break;
1879 case 162: op = rv_op_xperm4; break;
1880 case 164: op = rv_op_xperm8; break;
1881 case 200: op = rv_op_aes64es; break;
1882 case 216: op = rv_op_aes64esm; break;
1883 case 232: op = rv_op_aes64ds; break;
1884 case 248: op = rv_op_aes64dsm; break;
1885 case 256: op = rv_op_sub; break;
1886 case 260: op = rv_op_xnor; break;
1887 case 261: op = rv_op_sra; break;
1888 case 262: op = rv_op_orn; break;
1889 case 263: op = rv_op_andn; break;
1890 case 289: op = rv_op_bclr; break;
1891 case 293: op = rv_op_bext; break;
1892 case 320: op = rv_op_sha512sum0r; break;
1893 case 328: op = rv_op_sha512sum1r; break;
1894 case 336: op = rv_op_sha512sig0l; break;
1895 case 344: op = rv_op_sha512sig1l; break;
1896 case 368: op = rv_op_sha512sig0h; break;
1897 case 376: op = rv_op_sha512sig1h; break;
1898 case 385: op = rv_op_rol; break;
1899 case 389: op = rv_op_ror; break;
1900 case 417: op = rv_op_binv; break;
1901 case 504: op = rv_op_aes64ks2; break;
1903 switch ((inst >> 25) & 0b0011111) {
1904 case 17: op = rv_op_aes32esi; break;
1905 case 19: op = rv_op_aes32esmi; break;
1906 case 21: op = rv_op_aes32dsi; break;
1907 case 23: op = rv_op_aes32dsmi; break;
1908 case 24: op = rv_op_sm4ed; break;
1909 case 26: op = rv_op_sm4ks; break;
1911 break;
1912 case 13: op = rv_op_lui; break;
1913 case 14:
1914 switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
1915 case 0: op = rv_op_addw; break;
1916 case 1: op = rv_op_sllw; break;
1917 case 5: op = rv_op_srlw; break;
1918 case 8: op = rv_op_mulw; break;
1919 case 12: op = rv_op_divw; break;
1920 case 13: op = rv_op_divuw; break;
1921 case 14: op = rv_op_remw; break;
1922 case 15: op = rv_op_remuw; break;
1923 case 32: op = rv_op_add_uw; break;
1924 case 36:
1925 switch ((inst >> 20) & 0b11111) {
1926 case 0: op = rv_op_zext_h; break;
1927 default: op = rv_op_packw; break;
1929 break;
1930 case 130: op = rv_op_sh1add_uw; break;
1931 case 132: op = rv_op_sh2add_uw; break;
1932 case 134: op = rv_op_sh3add_uw; break;
1933 case 256: op = rv_op_subw; break;
1934 case 261: op = rv_op_sraw; break;
1935 case 385: op = rv_op_rolw; break;
1936 case 389: op = rv_op_rorw; break;
1938 break;
1939 case 16:
1940 switch (((inst >> 25) & 0b11)) {
1941 case 0: op = rv_op_fmadd_s; break;
1942 case 1: op = rv_op_fmadd_d; break;
1943 case 3: op = rv_op_fmadd_q; break;
1945 break;
1946 case 17:
1947 switch (((inst >> 25) & 0b11)) {
1948 case 0: op = rv_op_fmsub_s; break;
1949 case 1: op = rv_op_fmsub_d; break;
1950 case 3: op = rv_op_fmsub_q; break;
1952 break;
1953 case 18:
1954 switch (((inst >> 25) & 0b11)) {
1955 case 0: op = rv_op_fnmsub_s; break;
1956 case 1: op = rv_op_fnmsub_d; break;
1957 case 3: op = rv_op_fnmsub_q; break;
1959 break;
1960 case 19:
1961 switch (((inst >> 25) & 0b11)) {
1962 case 0: op = rv_op_fnmadd_s; break;
1963 case 1: op = rv_op_fnmadd_d; break;
1964 case 3: op = rv_op_fnmadd_q; break;
1966 break;
1967 case 20:
1968 switch (((inst >> 25) & 0b1111111)) {
1969 case 0: op = rv_op_fadd_s; break;
1970 case 1: op = rv_op_fadd_d; break;
1971 case 3: op = rv_op_fadd_q; break;
1972 case 4: op = rv_op_fsub_s; break;
1973 case 5: op = rv_op_fsub_d; break;
1974 case 7: op = rv_op_fsub_q; break;
1975 case 8: op = rv_op_fmul_s; break;
1976 case 9: op = rv_op_fmul_d; break;
1977 case 11: op = rv_op_fmul_q; break;
1978 case 12: op = rv_op_fdiv_s; break;
1979 case 13: op = rv_op_fdiv_d; break;
1980 case 15: op = rv_op_fdiv_q; break;
1981 case 16:
1982 switch (((inst >> 12) & 0b111)) {
1983 case 0: op = rv_op_fsgnj_s; break;
1984 case 1: op = rv_op_fsgnjn_s; break;
1985 case 2: op = rv_op_fsgnjx_s; break;
1987 break;
1988 case 17:
1989 switch (((inst >> 12) & 0b111)) {
1990 case 0: op = rv_op_fsgnj_d; break;
1991 case 1: op = rv_op_fsgnjn_d; break;
1992 case 2: op = rv_op_fsgnjx_d; break;
1994 break;
1995 case 19:
1996 switch (((inst >> 12) & 0b111)) {
1997 case 0: op = rv_op_fsgnj_q; break;
1998 case 1: op = rv_op_fsgnjn_q; break;
1999 case 2: op = rv_op_fsgnjx_q; break;
2001 break;
2002 case 20:
2003 switch (((inst >> 12) & 0b111)) {
2004 case 0: op = rv_op_fmin_s; break;
2005 case 1: op = rv_op_fmax_s; break;
2007 break;
2008 case 21:
2009 switch (((inst >> 12) & 0b111)) {
2010 case 0: op = rv_op_fmin_d; break;
2011 case 1: op = rv_op_fmax_d; break;
2013 break;
2014 case 23:
2015 switch (((inst >> 12) & 0b111)) {
2016 case 0: op = rv_op_fmin_q; break;
2017 case 1: op = rv_op_fmax_q; break;
2019 break;
2020 case 32:
2021 switch (((inst >> 20) & 0b11111)) {
2022 case 1: op = rv_op_fcvt_s_d; break;
2023 case 3: op = rv_op_fcvt_s_q; break;
2025 break;
2026 case 33:
2027 switch (((inst >> 20) & 0b11111)) {
2028 case 0: op = rv_op_fcvt_d_s; break;
2029 case 3: op = rv_op_fcvt_d_q; break;
2031 break;
2032 case 35:
2033 switch (((inst >> 20) & 0b11111)) {
2034 case 0: op = rv_op_fcvt_q_s; break;
2035 case 1: op = rv_op_fcvt_q_d; break;
2037 break;
2038 case 44:
2039 switch (((inst >> 20) & 0b11111)) {
2040 case 0: op = rv_op_fsqrt_s; break;
2042 break;
2043 case 45:
2044 switch (((inst >> 20) & 0b11111)) {
2045 case 0: op = rv_op_fsqrt_d; break;
2047 break;
2048 case 47:
2049 switch (((inst >> 20) & 0b11111)) {
2050 case 0: op = rv_op_fsqrt_q; break;
2052 break;
2053 case 80:
2054 switch (((inst >> 12) & 0b111)) {
2055 case 0: op = rv_op_fle_s; break;
2056 case 1: op = rv_op_flt_s; break;
2057 case 2: op = rv_op_feq_s; break;
2059 break;
2060 case 81:
2061 switch (((inst >> 12) & 0b111)) {
2062 case 0: op = rv_op_fle_d; break;
2063 case 1: op = rv_op_flt_d; break;
2064 case 2: op = rv_op_feq_d; break;
2066 break;
2067 case 83:
2068 switch (((inst >> 12) & 0b111)) {
2069 case 0: op = rv_op_fle_q; break;
2070 case 1: op = rv_op_flt_q; break;
2071 case 2: op = rv_op_feq_q; break;
2073 break;
2074 case 96:
2075 switch (((inst >> 20) & 0b11111)) {
2076 case 0: op = rv_op_fcvt_w_s; break;
2077 case 1: op = rv_op_fcvt_wu_s; break;
2078 case 2: op = rv_op_fcvt_l_s; break;
2079 case 3: op = rv_op_fcvt_lu_s; break;
2081 break;
2082 case 97:
2083 switch (((inst >> 20) & 0b11111)) {
2084 case 0: op = rv_op_fcvt_w_d; break;
2085 case 1: op = rv_op_fcvt_wu_d; break;
2086 case 2: op = rv_op_fcvt_l_d; break;
2087 case 3: op = rv_op_fcvt_lu_d; break;
2089 break;
2090 case 99:
2091 switch (((inst >> 20) & 0b11111)) {
2092 case 0: op = rv_op_fcvt_w_q; break;
2093 case 1: op = rv_op_fcvt_wu_q; break;
2094 case 2: op = rv_op_fcvt_l_q; break;
2095 case 3: op = rv_op_fcvt_lu_q; break;
2097 break;
2098 case 104:
2099 switch (((inst >> 20) & 0b11111)) {
2100 case 0: op = rv_op_fcvt_s_w; break;
2101 case 1: op = rv_op_fcvt_s_wu; break;
2102 case 2: op = rv_op_fcvt_s_l; break;
2103 case 3: op = rv_op_fcvt_s_lu; break;
2105 break;
2106 case 105:
2107 switch (((inst >> 20) & 0b11111)) {
2108 case 0: op = rv_op_fcvt_d_w; break;
2109 case 1: op = rv_op_fcvt_d_wu; break;
2110 case 2: op = rv_op_fcvt_d_l; break;
2111 case 3: op = rv_op_fcvt_d_lu; break;
2113 break;
2114 case 107:
2115 switch (((inst >> 20) & 0b11111)) {
2116 case 0: op = rv_op_fcvt_q_w; break;
2117 case 1: op = rv_op_fcvt_q_wu; break;
2118 case 2: op = rv_op_fcvt_q_l; break;
2119 case 3: op = rv_op_fcvt_q_lu; break;
2121 break;
2122 case 112:
2123 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2124 case 0: op = rv_op_fmv_x_s; break;
2125 case 1: op = rv_op_fclass_s; break;
2127 break;
2128 case 113:
2129 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2130 case 0: op = rv_op_fmv_x_d; break;
2131 case 1: op = rv_op_fclass_d; break;
2133 break;
2134 case 115:
2135 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2136 case 0: op = rv_op_fmv_x_q; break;
2137 case 1: op = rv_op_fclass_q; break;
2139 break;
2140 case 120:
2141 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2142 case 0: op = rv_op_fmv_s_x; break;
2144 break;
2145 case 121:
2146 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2147 case 0: op = rv_op_fmv_d_x; break;
2149 break;
2150 case 123:
2151 switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
2152 case 0: op = rv_op_fmv_q_x; break;
2154 break;
2156 break;
2157 case 22:
2158 switch (((inst >> 12) & 0b111)) {
2159 case 0: op = rv_op_addid; break;
2160 case 1:
2161 switch (((inst >> 26) & 0b111111)) {
2162 case 0: op = rv_op_sllid; break;
2164 break;
2165 case 5:
2166 switch (((inst >> 26) & 0b111111)) {
2167 case 0: op = rv_op_srlid; break;
2168 case 16: op = rv_op_sraid; break;
2170 break;
2172 break;
2173 case 24:
2174 switch (((inst >> 12) & 0b111)) {
2175 case 0: op = rv_op_beq; break;
2176 case 1: op = rv_op_bne; break;
2177 case 4: op = rv_op_blt; break;
2178 case 5: op = rv_op_bge; break;
2179 case 6: op = rv_op_bltu; break;
2180 case 7: op = rv_op_bgeu; break;
2182 break;
2183 case 25:
2184 switch (((inst >> 12) & 0b111)) {
2185 case 0: op = rv_op_jalr; break;
2187 break;
2188 case 27: op = rv_op_jal; break;
2189 case 28:
2190 switch (((inst >> 12) & 0b111)) {
2191 case 0:
2192 switch (((inst >> 20) & 0b111111100000) | ((inst >> 7) & 0b000000011111)) {
2193 case 0:
2194 switch (((inst >> 15) & 0b1111111111)) {
2195 case 0: op = rv_op_ecall; break;
2196 case 32: op = rv_op_ebreak; break;
2197 case 64: op = rv_op_uret; break;
2199 break;
2200 case 256:
2201 switch (((inst >> 20) & 0b11111)) {
2202 case 2:
2203 switch (((inst >> 15) & 0b11111)) {
2204 case 0: op = rv_op_sret; break;
2206 break;
2207 case 4: op = rv_op_sfence_vm; break;
2208 case 5:
2209 switch (((inst >> 15) & 0b11111)) {
2210 case 0: op = rv_op_wfi; break;
2212 break;
2214 break;
2215 case 288: op = rv_op_sfence_vma; break;
2216 case 512:
2217 switch (((inst >> 15) & 0b1111111111)) {
2218 case 64: op = rv_op_hret; break;
2220 break;
2221 case 768:
2222 switch (((inst >> 15) & 0b1111111111)) {
2223 case 64: op = rv_op_mret; break;
2225 break;
2226 case 1952:
2227 switch (((inst >> 15) & 0b1111111111)) {
2228 case 576: op = rv_op_dret; break;
2230 break;
2232 break;
2233 case 1: op = rv_op_csrrw; break;
2234 case 2: op = rv_op_csrrs; break;
2235 case 3: op = rv_op_csrrc; break;
2236 case 5: op = rv_op_csrrwi; break;
2237 case 6: op = rv_op_csrrsi; break;
2238 case 7: op = rv_op_csrrci; break;
2240 break;
2241 case 30:
2242 switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
2243 case 0: op = rv_op_addd; break;
2244 case 1: op = rv_op_slld; break;
2245 case 5: op = rv_op_srld; break;
2246 case 8: op = rv_op_muld; break;
2247 case 12: op = rv_op_divd; break;
2248 case 13: op = rv_op_divud; break;
2249 case 14: op = rv_op_remd; break;
2250 case 15: op = rv_op_remud; break;
2251 case 256: op = rv_op_subd; break;
2252 case 261: op = rv_op_srad; break;
2254 break;
2256 break;
2258 dec->op = op;
2261 /* operand extractors */
2263 static uint32_t operand_rd(rv_inst inst)
2265 return (inst << 52) >> 59;
2268 static uint32_t operand_rs1(rv_inst inst)
2270 return (inst << 44) >> 59;
2273 static uint32_t operand_rs2(rv_inst inst)
2275 return (inst << 39) >> 59;
2278 static uint32_t operand_rs3(rv_inst inst)
2280 return (inst << 32) >> 59;
2283 static uint32_t operand_aq(rv_inst inst)
2285 return (inst << 37) >> 63;
2288 static uint32_t operand_rl(rv_inst inst)
2290 return (inst << 38) >> 63;
2293 static uint32_t operand_pred(rv_inst inst)
2295 return (inst << 36) >> 60;
2298 static uint32_t operand_succ(rv_inst inst)
2300 return (inst << 40) >> 60;
2303 static uint32_t operand_rm(rv_inst inst)
2305 return (inst << 49) >> 61;
2308 static uint32_t operand_shamt5(rv_inst inst)
2310 return (inst << 39) >> 59;
2313 static uint32_t operand_shamt6(rv_inst inst)
2315 return (inst << 38) >> 58;
2318 static uint32_t operand_shamt7(rv_inst inst)
2320 return (inst << 37) >> 57;
2323 static uint32_t operand_crdq(rv_inst inst)
2325 return (inst << 59) >> 61;
2328 static uint32_t operand_crs1q(rv_inst inst)
2330 return (inst << 54) >> 61;
2333 static uint32_t operand_crs1rdq(rv_inst inst)
2335 return (inst << 54) >> 61;
2338 static uint32_t operand_crs2q(rv_inst inst)
2340 return (inst << 59) >> 61;
2343 static uint32_t operand_crd(rv_inst inst)
2345 return (inst << 52) >> 59;
2348 static uint32_t operand_crs1(rv_inst inst)
2350 return (inst << 52) >> 59;
2353 static uint32_t operand_crs1rd(rv_inst inst)
2355 return (inst << 52) >> 59;
2358 static uint32_t operand_crs2(rv_inst inst)
2360 return (inst << 57) >> 59;
2363 static uint32_t operand_cimmsh5(rv_inst inst)
2365 return (inst << 57) >> 59;
2368 static uint32_t operand_csr12(rv_inst inst)
2370 return (inst << 32) >> 52;
2373 static int32_t operand_imm12(rv_inst inst)
2375 return ((int64_t)inst << 32) >> 52;
2378 static int32_t operand_imm20(rv_inst inst)
2380 return (((int64_t)inst << 32) >> 44) << 12;
2383 static int32_t operand_jimm20(rv_inst inst)
2385 return (((int64_t)inst << 32) >> 63) << 20 |
2386 ((inst << 33) >> 54) << 1 |
2387 ((inst << 43) >> 63) << 11 |
2388 ((inst << 44) >> 56) << 12;
2391 static int32_t operand_simm12(rv_inst inst)
2393 return (((int64_t)inst << 32) >> 57) << 5 |
2394 (inst << 52) >> 59;
2397 static int32_t operand_sbimm12(rv_inst inst)
2399 return (((int64_t)inst << 32) >> 63) << 12 |
2400 ((inst << 33) >> 58) << 5 |
2401 ((inst << 52) >> 60) << 1 |
2402 ((inst << 56) >> 63) << 11;
2405 static uint32_t operand_cimmsh6(rv_inst inst)
2407 return ((inst << 51) >> 63) << 5 |
2408 (inst << 57) >> 59;
2411 static int32_t operand_cimmi(rv_inst inst)
2413 return (((int64_t)inst << 51) >> 63) << 5 |
2414 (inst << 57) >> 59;
2417 static int32_t operand_cimmui(rv_inst inst)
2419 return (((int64_t)inst << 51) >> 63) << 17 |
2420 ((inst << 57) >> 59) << 12;
2423 static uint32_t operand_cimmlwsp(rv_inst inst)
2425 return ((inst << 51) >> 63) << 5 |
2426 ((inst << 57) >> 61) << 2 |
2427 ((inst << 60) >> 62) << 6;
2430 static uint32_t operand_cimmldsp(rv_inst inst)
2432 return ((inst << 51) >> 63) << 5 |
2433 ((inst << 57) >> 62) << 3 |
2434 ((inst << 59) >> 61) << 6;
2437 static uint32_t operand_cimmlqsp(rv_inst inst)
2439 return ((inst << 51) >> 63) << 5 |
2440 ((inst << 57) >> 63) << 4 |
2441 ((inst << 58) >> 60) << 6;
2444 static int32_t operand_cimm16sp(rv_inst inst)
2446 return (((int64_t)inst << 51) >> 63) << 9 |
2447 ((inst << 57) >> 63) << 4 |
2448 ((inst << 58) >> 63) << 6 |
2449 ((inst << 59) >> 62) << 7 |
2450 ((inst << 61) >> 63) << 5;
2453 static int32_t operand_cimmj(rv_inst inst)
2455 return (((int64_t)inst << 51) >> 63) << 11 |
2456 ((inst << 52) >> 63) << 4 |
2457 ((inst << 53) >> 62) << 8 |
2458 ((inst << 55) >> 63) << 10 |
2459 ((inst << 56) >> 63) << 6 |
2460 ((inst << 57) >> 63) << 7 |
2461 ((inst << 58) >> 61) << 1 |
2462 ((inst << 61) >> 63) << 5;
2465 static int32_t operand_cimmb(rv_inst inst)
2467 return (((int64_t)inst << 51) >> 63) << 8 |
2468 ((inst << 52) >> 62) << 3 |
2469 ((inst << 57) >> 62) << 6 |
2470 ((inst << 59) >> 62) << 1 |
2471 ((inst << 61) >> 63) << 5;
2474 static uint32_t operand_cimmswsp(rv_inst inst)
2476 return ((inst << 51) >> 60) << 2 |
2477 ((inst << 55) >> 62) << 6;
2480 static uint32_t operand_cimmsdsp(rv_inst inst)
2482 return ((inst << 51) >> 61) << 3 |
2483 ((inst << 54) >> 61) << 6;
2486 static uint32_t operand_cimmsqsp(rv_inst inst)
2488 return ((inst << 51) >> 62) << 4 |
2489 ((inst << 53) >> 60) << 6;
2492 static uint32_t operand_cimm4spn(rv_inst inst)
2494 return ((inst << 51) >> 62) << 4 |
2495 ((inst << 53) >> 60) << 6 |
2496 ((inst << 57) >> 63) << 2 |
2497 ((inst << 58) >> 63) << 3;
2500 static uint32_t operand_cimmw(rv_inst inst)
2502 return ((inst << 51) >> 61) << 3 |
2503 ((inst << 57) >> 63) << 2 |
2504 ((inst << 58) >> 63) << 6;
2507 static uint32_t operand_cimmd(rv_inst inst)
2509 return ((inst << 51) >> 61) << 3 |
2510 ((inst << 57) >> 62) << 6;
2513 static uint32_t operand_cimmq(rv_inst inst)
2515 return ((inst << 51) >> 62) << 4 |
2516 ((inst << 53) >> 63) << 8 |
2517 ((inst << 57) >> 62) << 6;
2520 static uint32_t operand_bs(rv_inst inst)
2522 return (inst << 32) >> 62;
2525 static uint32_t operand_rnum(rv_inst inst)
2527 return (inst << 40) >> 60;
2530 /* decode operands */
2532 static void decode_inst_operands(rv_decode *dec)
2534 rv_inst inst = dec->inst;
2535 dec->codec = opcode_data[dec->op].codec;
2536 switch (dec->codec) {
2537 case rv_codec_none:
2538 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2539 dec->imm = 0;
2540 break;
2541 case rv_codec_u:
2542 dec->rd = operand_rd(inst);
2543 dec->rs1 = dec->rs2 = rv_ireg_zero;
2544 dec->imm = operand_imm20(inst);
2545 break;
2546 case rv_codec_uj:
2547 dec->rd = operand_rd(inst);
2548 dec->rs1 = dec->rs2 = rv_ireg_zero;
2549 dec->imm = operand_jimm20(inst);
2550 break;
2551 case rv_codec_i:
2552 dec->rd = operand_rd(inst);
2553 dec->rs1 = operand_rs1(inst);
2554 dec->rs2 = rv_ireg_zero;
2555 dec->imm = operand_imm12(inst);
2556 break;
2557 case rv_codec_i_sh5:
2558 dec->rd = operand_rd(inst);
2559 dec->rs1 = operand_rs1(inst);
2560 dec->rs2 = rv_ireg_zero;
2561 dec->imm = operand_shamt5(inst);
2562 break;
2563 case rv_codec_i_sh6:
2564 dec->rd = operand_rd(inst);
2565 dec->rs1 = operand_rs1(inst);
2566 dec->rs2 = rv_ireg_zero;
2567 dec->imm = operand_shamt6(inst);
2568 break;
2569 case rv_codec_i_sh7:
2570 dec->rd = operand_rd(inst);
2571 dec->rs1 = operand_rs1(inst);
2572 dec->rs2 = rv_ireg_zero;
2573 dec->imm = operand_shamt7(inst);
2574 break;
2575 case rv_codec_i_csr:
2576 dec->rd = operand_rd(inst);
2577 dec->rs1 = operand_rs1(inst);
2578 dec->rs2 = rv_ireg_zero;
2579 dec->imm = operand_csr12(inst);
2580 break;
2581 case rv_codec_s:
2582 dec->rd = rv_ireg_zero;
2583 dec->rs1 = operand_rs1(inst);
2584 dec->rs2 = operand_rs2(inst);
2585 dec->imm = operand_simm12(inst);
2586 break;
2587 case rv_codec_sb:
2588 dec->rd = rv_ireg_zero;
2589 dec->rs1 = operand_rs1(inst);
2590 dec->rs2 = operand_rs2(inst);
2591 dec->imm = operand_sbimm12(inst);
2592 break;
2593 case rv_codec_r:
2594 dec->rd = operand_rd(inst);
2595 dec->rs1 = operand_rs1(inst);
2596 dec->rs2 = operand_rs2(inst);
2597 dec->imm = 0;
2598 break;
2599 case rv_codec_r_m:
2600 dec->rd = operand_rd(inst);
2601 dec->rs1 = operand_rs1(inst);
2602 dec->rs2 = operand_rs2(inst);
2603 dec->imm = 0;
2604 dec->rm = operand_rm(inst);
2605 break;
2606 case rv_codec_r4_m:
2607 dec->rd = operand_rd(inst);
2608 dec->rs1 = operand_rs1(inst);
2609 dec->rs2 = operand_rs2(inst);
2610 dec->rs3 = operand_rs3(inst);
2611 dec->imm = 0;
2612 dec->rm = operand_rm(inst);
2613 break;
2614 case rv_codec_r_a:
2615 dec->rd = operand_rd(inst);
2616 dec->rs1 = operand_rs1(inst);
2617 dec->rs2 = operand_rs2(inst);
2618 dec->imm = 0;
2619 dec->aq = operand_aq(inst);
2620 dec->rl = operand_rl(inst);
2621 break;
2622 case rv_codec_r_l:
2623 dec->rd = operand_rd(inst);
2624 dec->rs1 = operand_rs1(inst);
2625 dec->rs2 = rv_ireg_zero;
2626 dec->imm = 0;
2627 dec->aq = operand_aq(inst);
2628 dec->rl = operand_rl(inst);
2629 break;
2630 case rv_codec_r_f:
2631 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2632 dec->pred = operand_pred(inst);
2633 dec->succ = operand_succ(inst);
2634 dec->imm = 0;
2635 break;
2636 case rv_codec_cb:
2637 dec->rd = rv_ireg_zero;
2638 dec->rs1 = operand_crs1q(inst) + 8;
2639 dec->rs2 = rv_ireg_zero;
2640 dec->imm = operand_cimmb(inst);
2641 break;
2642 case rv_codec_cb_imm:
2643 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2644 dec->rs2 = rv_ireg_zero;
2645 dec->imm = operand_cimmi(inst);
2646 break;
2647 case rv_codec_cb_sh5:
2648 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2649 dec->rs2 = rv_ireg_zero;
2650 dec->imm = operand_cimmsh5(inst);
2651 break;
2652 case rv_codec_cb_sh6:
2653 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2654 dec->rs2 = rv_ireg_zero;
2655 dec->imm = operand_cimmsh6(inst);
2656 break;
2657 case rv_codec_ci:
2658 dec->rd = dec->rs1 = operand_crs1rd(inst);
2659 dec->rs2 = rv_ireg_zero;
2660 dec->imm = operand_cimmi(inst);
2661 break;
2662 case rv_codec_ci_sh5:
2663 dec->rd = dec->rs1 = operand_crs1rd(inst);
2664 dec->rs2 = rv_ireg_zero;
2665 dec->imm = operand_cimmsh5(inst);
2666 break;
2667 case rv_codec_ci_sh6:
2668 dec->rd = dec->rs1 = operand_crs1rd(inst);
2669 dec->rs2 = rv_ireg_zero;
2670 dec->imm = operand_cimmsh6(inst);
2671 break;
2672 case rv_codec_ci_16sp:
2673 dec->rd = rv_ireg_sp;
2674 dec->rs1 = rv_ireg_sp;
2675 dec->rs2 = rv_ireg_zero;
2676 dec->imm = operand_cimm16sp(inst);
2677 break;
2678 case rv_codec_ci_lwsp:
2679 dec->rd = operand_crd(inst);
2680 dec->rs1 = rv_ireg_sp;
2681 dec->rs2 = rv_ireg_zero;
2682 dec->imm = operand_cimmlwsp(inst);
2683 break;
2684 case rv_codec_ci_ldsp:
2685 dec->rd = operand_crd(inst);
2686 dec->rs1 = rv_ireg_sp;
2687 dec->rs2 = rv_ireg_zero;
2688 dec->imm = operand_cimmldsp(inst);
2689 break;
2690 case rv_codec_ci_lqsp:
2691 dec->rd = operand_crd(inst);
2692 dec->rs1 = rv_ireg_sp;
2693 dec->rs2 = rv_ireg_zero;
2694 dec->imm = operand_cimmlqsp(inst);
2695 break;
2696 case rv_codec_ci_li:
2697 dec->rd = operand_crd(inst);
2698 dec->rs1 = rv_ireg_zero;
2699 dec->rs2 = rv_ireg_zero;
2700 dec->imm = operand_cimmi(inst);
2701 break;
2702 case rv_codec_ci_lui:
2703 dec->rd = operand_crd(inst);
2704 dec->rs1 = rv_ireg_zero;
2705 dec->rs2 = rv_ireg_zero;
2706 dec->imm = operand_cimmui(inst);
2707 break;
2708 case rv_codec_ci_none:
2709 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2710 dec->imm = 0;
2711 break;
2712 case rv_codec_ciw_4spn:
2713 dec->rd = operand_crdq(inst) + 8;
2714 dec->rs1 = rv_ireg_sp;
2715 dec->rs2 = rv_ireg_zero;
2716 dec->imm = operand_cimm4spn(inst);
2717 break;
2718 case rv_codec_cj:
2719 dec->rd = dec->rs1 = dec->rs2 = rv_ireg_zero;
2720 dec->imm = operand_cimmj(inst);
2721 break;
2722 case rv_codec_cj_jal:
2723 dec->rd = rv_ireg_ra;
2724 dec->rs1 = dec->rs2 = rv_ireg_zero;
2725 dec->imm = operand_cimmj(inst);
2726 break;
2727 case rv_codec_cl_lw:
2728 dec->rd = operand_crdq(inst) + 8;
2729 dec->rs1 = operand_crs1q(inst) + 8;
2730 dec->rs2 = rv_ireg_zero;
2731 dec->imm = operand_cimmw(inst);
2732 break;
2733 case rv_codec_cl_ld:
2734 dec->rd = operand_crdq(inst) + 8;
2735 dec->rs1 = operand_crs1q(inst) + 8;
2736 dec->rs2 = rv_ireg_zero;
2737 dec->imm = operand_cimmd(inst);
2738 break;
2739 case rv_codec_cl_lq:
2740 dec->rd = operand_crdq(inst) + 8;
2741 dec->rs1 = operand_crs1q(inst) + 8;
2742 dec->rs2 = rv_ireg_zero;
2743 dec->imm = operand_cimmq(inst);
2744 break;
2745 case rv_codec_cr:
2746 dec->rd = dec->rs1 = operand_crs1rd(inst);
2747 dec->rs2 = operand_crs2(inst);
2748 dec->imm = 0;
2749 break;
2750 case rv_codec_cr_mv:
2751 dec->rd = operand_crd(inst);
2752 dec->rs1 = operand_crs2(inst);
2753 dec->rs2 = rv_ireg_zero;
2754 dec->imm = 0;
2755 break;
2756 case rv_codec_cr_jalr:
2757 dec->rd = rv_ireg_ra;
2758 dec->rs1 = operand_crs1(inst);
2759 dec->rs2 = rv_ireg_zero;
2760 dec->imm = 0;
2761 break;
2762 case rv_codec_cr_jr:
2763 dec->rd = rv_ireg_zero;
2764 dec->rs1 = operand_crs1(inst);
2765 dec->rs2 = rv_ireg_zero;
2766 dec->imm = 0;
2767 break;
2768 case rv_codec_cs:
2769 dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
2770 dec->rs2 = operand_crs2q(inst) + 8;
2771 dec->imm = 0;
2772 break;
2773 case rv_codec_cs_sw:
2774 dec->rd = rv_ireg_zero;
2775 dec->rs1 = operand_crs1q(inst) + 8;
2776 dec->rs2 = operand_crs2q(inst) + 8;
2777 dec->imm = operand_cimmw(inst);
2778 break;
2779 case rv_codec_cs_sd:
2780 dec->rd = rv_ireg_zero;
2781 dec->rs1 = operand_crs1q(inst) + 8;
2782 dec->rs2 = operand_crs2q(inst) + 8;
2783 dec->imm = operand_cimmd(inst);
2784 break;
2785 case rv_codec_cs_sq:
2786 dec->rd = rv_ireg_zero;
2787 dec->rs1 = operand_crs1q(inst) + 8;
2788 dec->rs2 = operand_crs2q(inst) + 8;
2789 dec->imm = operand_cimmq(inst);
2790 break;
2791 case rv_codec_css_swsp:
2792 dec->rd = rv_ireg_zero;
2793 dec->rs1 = rv_ireg_sp;
2794 dec->rs2 = operand_crs2(inst);
2795 dec->imm = operand_cimmswsp(inst);
2796 break;
2797 case rv_codec_css_sdsp:
2798 dec->rd = rv_ireg_zero;
2799 dec->rs1 = rv_ireg_sp;
2800 dec->rs2 = operand_crs2(inst);
2801 dec->imm = operand_cimmsdsp(inst);
2802 break;
2803 case rv_codec_css_sqsp:
2804 dec->rd = rv_ireg_zero;
2805 dec->rs1 = rv_ireg_sp;
2806 dec->rs2 = operand_crs2(inst);
2807 dec->imm = operand_cimmsqsp(inst);
2808 break;
2809 case rv_codec_k_bs:
2810 dec->rs1 = operand_rs1(inst);
2811 dec->rs2 = operand_rs2(inst);
2812 dec->bs = operand_bs(inst);
2813 break;
2814 case rv_codec_k_rnum:
2815 dec->rd = operand_rd(inst);
2816 dec->rs1 = operand_rs1(inst);
2817 dec->rnum = operand_rnum(inst);
2818 break;
2822 /* check constraint */
2824 static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
2826 int32_t imm = dec->imm;
2827 uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
2828 while (*c != rvc_end) {
2829 switch (*c) {
2830 case rvc_rd_eq_ra:
2831 if (!(rd == 1)) {
2832 return false;
2834 break;
2835 case rvc_rd_eq_x0:
2836 if (!(rd == 0)) {
2837 return false;
2839 break;
2840 case rvc_rs1_eq_x0:
2841 if (!(rs1 == 0)) {
2842 return false;
2844 break;
2845 case rvc_rs2_eq_x0:
2846 if (!(rs2 == 0)) {
2847 return false;
2849 break;
2850 case rvc_rs2_eq_rs1:
2851 if (!(rs2 == rs1)) {
2852 return false;
2854 break;
2855 case rvc_rs1_eq_ra:
2856 if (!(rs1 == 1)) {
2857 return false;
2859 break;
2860 case rvc_imm_eq_zero:
2861 if (!(imm == 0)) {
2862 return false;
2864 break;
2865 case rvc_imm_eq_n1:
2866 if (!(imm == -1)) {
2867 return false;
2869 break;
2870 case rvc_imm_eq_p1:
2871 if (!(imm == 1)) {
2872 return false;
2874 break;
2875 case rvc_csr_eq_0x001:
2876 if (!(imm == 0x001)) {
2877 return false;
2879 break;
2880 case rvc_csr_eq_0x002:
2881 if (!(imm == 0x002)) {
2882 return false;
2884 break;
2885 case rvc_csr_eq_0x003:
2886 if (!(imm == 0x003)) {
2887 return false;
2889 break;
2890 case rvc_csr_eq_0xc00:
2891 if (!(imm == 0xc00)) {
2892 return false;
2894 break;
2895 case rvc_csr_eq_0xc01:
2896 if (!(imm == 0xc01)) {
2897 return false;
2899 break;
2900 case rvc_csr_eq_0xc02:
2901 if (!(imm == 0xc02)) {
2902 return false;
2904 break;
2905 case rvc_csr_eq_0xc80:
2906 if (!(imm == 0xc80)) {
2907 return false;
2909 break;
2910 case rvc_csr_eq_0xc81:
2911 if (!(imm == 0xc81)) {
2912 return false;
2914 break;
2915 case rvc_csr_eq_0xc82:
2916 if (!(imm == 0xc82)) {
2917 return false;
2919 break;
2920 default: break;
2922 c++;
2924 return true;
2927 /* instruction length */
2929 static size_t inst_length(rv_inst inst)
2931 /* NOTE: supports maximum instruction size of 64-bits */
2933 /* instruction length coding
2935 * aa - 16 bit aa != 11
2936 * bbb11 - 32 bit bbb != 111
2937 * 011111 - 48 bit
2938 * 0111111 - 64 bit
2941 return (inst & 0b11) != 0b11 ? 2
2942 : (inst & 0b11100) != 0b11100 ? 4
2943 : (inst & 0b111111) == 0b011111 ? 6
2944 : (inst & 0b1111111) == 0b0111111 ? 8
2945 : 0;
2948 /* format instruction */
2950 static void append(char *s1, const char *s2, size_t n)
2952 size_t l1 = strlen(s1);
2953 if (n - l1 - 1 > 0) {
2954 strncat(s1, s2, n - l1);
2958 static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
2960 char tmp[64];
2961 const char *fmt;
2963 fmt = opcode_data[dec->op].format;
2964 while (*fmt) {
2965 switch (*fmt) {
2966 case 'O':
2967 append(buf, opcode_data[dec->op].name, buflen);
2968 break;
2969 case '(':
2970 append(buf, "(", buflen);
2971 break;
2972 case ',':
2973 append(buf, ",", buflen);
2974 break;
2975 case ')':
2976 append(buf, ")", buflen);
2977 break;
2978 case 'b':
2979 snprintf(tmp, sizeof(tmp), "%d", dec->bs);
2980 append(buf, tmp, buflen);
2981 break;
2982 case 'n':
2983 snprintf(tmp, sizeof(tmp), "%d", dec->rnum);
2984 append(buf, tmp, buflen);
2985 break;
2986 case '0':
2987 append(buf, rv_ireg_name_sym[dec->rd], buflen);
2988 break;
2989 case '1':
2990 append(buf, rv_ireg_name_sym[dec->rs1], buflen);
2991 break;
2992 case '2':
2993 append(buf, rv_ireg_name_sym[dec->rs2], buflen);
2994 break;
2995 case '3':
2996 append(buf, rv_freg_name_sym[dec->rd], buflen);
2997 break;
2998 case '4':
2999 append(buf, rv_freg_name_sym[dec->rs1], buflen);
3000 break;
3001 case '5':
3002 append(buf, rv_freg_name_sym[dec->rs2], buflen);
3003 break;
3004 case '6':
3005 append(buf, rv_freg_name_sym[dec->rs3], buflen);
3006 break;
3007 case '7':
3008 snprintf(tmp, sizeof(tmp), "%d", dec->rs1);
3009 append(buf, tmp, buflen);
3010 break;
3011 case 'i':
3012 snprintf(tmp, sizeof(tmp), "%d", dec->imm);
3013 append(buf, tmp, buflen);
3014 break;
3015 case 'o':
3016 snprintf(tmp, sizeof(tmp), "%d", dec->imm);
3017 append(buf, tmp, buflen);
3018 while (strlen(buf) < tab * 2) {
3019 append(buf, " ", buflen);
3021 snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
3022 dec->pc + dec->imm);
3023 append(buf, tmp, buflen);
3024 break;
3025 case 'c': {
3026 const char *name = csr_name(dec->imm & 0xfff);
3027 if (name) {
3028 append(buf, name, buflen);
3029 } else {
3030 snprintf(tmp, sizeof(tmp), "0x%03x", dec->imm & 0xfff);
3031 append(buf, tmp, buflen);
3033 break;
3035 case 'r':
3036 switch (dec->rm) {
3037 case rv_rm_rne:
3038 append(buf, "rne", buflen);
3039 break;
3040 case rv_rm_rtz:
3041 append(buf, "rtz", buflen);
3042 break;
3043 case rv_rm_rdn:
3044 append(buf, "rdn", buflen);
3045 break;
3046 case rv_rm_rup:
3047 append(buf, "rup", buflen);
3048 break;
3049 case rv_rm_rmm:
3050 append(buf, "rmm", buflen);
3051 break;
3052 case rv_rm_dyn:
3053 append(buf, "dyn", buflen);
3054 break;
3055 default:
3056 append(buf, "inv", buflen);
3057 break;
3059 break;
3060 case 'p':
3061 if (dec->pred & rv_fence_i) {
3062 append(buf, "i", buflen);
3064 if (dec->pred & rv_fence_o) {
3065 append(buf, "o", buflen);
3067 if (dec->pred & rv_fence_r) {
3068 append(buf, "r", buflen);
3070 if (dec->pred & rv_fence_w) {
3071 append(buf, "w", buflen);
3073 break;
3074 case 's':
3075 if (dec->succ & rv_fence_i) {
3076 append(buf, "i", buflen);
3078 if (dec->succ & rv_fence_o) {
3079 append(buf, "o", buflen);
3081 if (dec->succ & rv_fence_r) {
3082 append(buf, "r", buflen);
3084 if (dec->succ & rv_fence_w) {
3085 append(buf, "w", buflen);
3087 break;
3088 case '\t':
3089 while (strlen(buf) < tab) {
3090 append(buf, " ", buflen);
3092 break;
3093 case 'A':
3094 if (dec->aq) {
3095 append(buf, ".aq", buflen);
3097 break;
3098 case 'R':
3099 if (dec->rl) {
3100 append(buf, ".rl", buflen);
3102 break;
3103 default:
3104 break;
3106 fmt++;
3110 /* lift instruction to pseudo-instruction */
3112 static void decode_inst_lift_pseudo(rv_decode *dec)
3114 const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
3115 if (!comp_data) {
3116 return;
3118 while (comp_data->constraints) {
3119 if (check_constraints(dec, comp_data->constraints)) {
3120 dec->op = comp_data->op;
3121 dec->codec = opcode_data[dec->op].codec;
3122 return;
3124 comp_data++;
3128 /* decompress instruction */
3130 static void decode_inst_decompress_rv32(rv_decode *dec)
3132 int decomp_op = opcode_data[dec->op].decomp_rv32;
3133 if (decomp_op != rv_op_illegal) {
3134 if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3135 && dec->imm == 0) {
3136 dec->op = rv_op_illegal;
3137 } else {
3138 dec->op = decomp_op;
3139 dec->codec = opcode_data[decomp_op].codec;
3144 static void decode_inst_decompress_rv64(rv_decode *dec)
3146 int decomp_op = opcode_data[dec->op].decomp_rv64;
3147 if (decomp_op != rv_op_illegal) {
3148 if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3149 && dec->imm == 0) {
3150 dec->op = rv_op_illegal;
3151 } else {
3152 dec->op = decomp_op;
3153 dec->codec = opcode_data[decomp_op].codec;
3158 static void decode_inst_decompress_rv128(rv_decode *dec)
3160 int decomp_op = opcode_data[dec->op].decomp_rv128;
3161 if (decomp_op != rv_op_illegal) {
3162 if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
3163 && dec->imm == 0) {
3164 dec->op = rv_op_illegal;
3165 } else {
3166 dec->op = decomp_op;
3167 dec->codec = opcode_data[decomp_op].codec;
3172 static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
3174 switch (isa) {
3175 case rv32:
3176 decode_inst_decompress_rv32(dec);
3177 break;
3178 case rv64:
3179 decode_inst_decompress_rv64(dec);
3180 break;
3181 case rv128:
3182 decode_inst_decompress_rv128(dec);
3183 break;
3187 /* disassemble instruction */
3189 static void
3190 disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
3192 rv_decode dec = { 0 };
3193 dec.pc = pc;
3194 dec.inst = inst;
3195 decode_inst_opcode(&dec, isa);
3196 decode_inst_operands(&dec);
3197 decode_inst_decompress(&dec, isa);
3198 decode_inst_lift_pseudo(&dec);
3199 format_inst(buf, buflen, 16, &dec);
3202 #define INST_FMT_2 "%04" PRIx64 " "
3203 #define INST_FMT_4 "%08" PRIx64 " "
3204 #define INST_FMT_6 "%012" PRIx64 " "
3205 #define INST_FMT_8 "%016" PRIx64 " "
3207 static int
3208 print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
3210 char buf[128] = { 0 };
3211 bfd_byte packet[2];
3212 rv_inst inst = 0;
3213 size_t len = 2;
3214 bfd_vma n;
3215 int status;
3217 /* Instructions are made of 2-byte packets in little-endian order */
3218 for (n = 0; n < len; n += 2) {
3219 status = (*info->read_memory_func)(memaddr + n, packet, 2, info);
3220 if (status != 0) {
3221 /* Don't fail just because we fell off the end. */
3222 if (n > 0) {
3223 break;
3225 (*info->memory_error_func)(status, memaddr, info);
3226 return status;
3228 inst |= ((rv_inst) bfd_getl16(packet)) << (8 * n);
3229 if (n == 0) {
3230 len = inst_length(inst);
3234 switch (len) {
3235 case 2:
3236 (*info->fprintf_func)(info->stream, INST_FMT_2, inst);
3237 break;
3238 case 4:
3239 (*info->fprintf_func)(info->stream, INST_FMT_4, inst);
3240 break;
3241 case 6:
3242 (*info->fprintf_func)(info->stream, INST_FMT_6, inst);
3243 break;
3244 default:
3245 (*info->fprintf_func)(info->stream, INST_FMT_8, inst);
3246 break;
3249 disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
3250 (*info->fprintf_func)(info->stream, "%s", buf);
3252 return len;
3255 int print_insn_riscv32(bfd_vma memaddr, struct disassemble_info *info)
3257 return print_insn_riscv(memaddr, info, rv32);
3260 int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info)
3262 return print_insn_riscv(memaddr, info, rv64);
3265 int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
3267 return print_insn_riscv(memaddr, info, rv128);