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