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