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