1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * QEMU LoongArch Disassembler 4 * 5 * Copyright (c) 2021 Loongson Technology Corporation Limited. 6 */ 7 8 #include "qemu/osdep.h" 9 #include "disas/dis-asm.h" 10 #include "qemu/bitops.h" 11 #include "cpu-csr.h" 12 13 typedef struct { 14 disassemble_info *info; 15 uint64_t pc; 16 uint32_t insn; 17 } DisasContext; 18 19 static inline int plus_1(DisasContext *ctx, int x) 20 { 21 return x + 1; 22 } 23 24 static inline int shl_2(DisasContext *ctx, int x) 25 { 26 return x << 2; 27 } 28 29 #define CSR_NAME(REG) \ 30 [LOONGARCH_CSR_##REG] = (#REG) 31 32 static const char * const csr_names[] = { 33 CSR_NAME(CRMD), 34 CSR_NAME(PRMD), 35 CSR_NAME(EUEN), 36 CSR_NAME(MISC), 37 CSR_NAME(ECFG), 38 CSR_NAME(ESTAT), 39 CSR_NAME(ERA), 40 CSR_NAME(BADV), 41 CSR_NAME(BADI), 42 CSR_NAME(EENTRY), 43 CSR_NAME(TLBIDX), 44 CSR_NAME(TLBEHI), 45 CSR_NAME(TLBELO0), 46 CSR_NAME(TLBELO1), 47 CSR_NAME(ASID), 48 CSR_NAME(PGDL), 49 CSR_NAME(PGDH), 50 CSR_NAME(PGD), 51 CSR_NAME(PWCL), 52 CSR_NAME(PWCH), 53 CSR_NAME(STLBPS), 54 CSR_NAME(RVACFG), 55 CSR_NAME(CPUID), 56 CSR_NAME(PRCFG1), 57 CSR_NAME(PRCFG2), 58 CSR_NAME(PRCFG3), 59 CSR_NAME(SAVE(0)), 60 CSR_NAME(SAVE(1)), 61 CSR_NAME(SAVE(2)), 62 CSR_NAME(SAVE(3)), 63 CSR_NAME(SAVE(4)), 64 CSR_NAME(SAVE(5)), 65 CSR_NAME(SAVE(6)), 66 CSR_NAME(SAVE(7)), 67 CSR_NAME(SAVE(8)), 68 CSR_NAME(SAVE(9)), 69 CSR_NAME(SAVE(10)), 70 CSR_NAME(SAVE(11)), 71 CSR_NAME(SAVE(12)), 72 CSR_NAME(SAVE(13)), 73 CSR_NAME(SAVE(14)), 74 CSR_NAME(SAVE(15)), 75 CSR_NAME(TID), 76 CSR_NAME(TCFG), 77 CSR_NAME(TVAL), 78 CSR_NAME(CNTC), 79 CSR_NAME(TICLR), 80 CSR_NAME(LLBCTL), 81 CSR_NAME(IMPCTL1), 82 CSR_NAME(IMPCTL2), 83 CSR_NAME(TLBRENTRY), 84 CSR_NAME(TLBRBADV), 85 CSR_NAME(TLBRERA), 86 CSR_NAME(TLBRSAVE), 87 CSR_NAME(TLBRELO0), 88 CSR_NAME(TLBRELO1), 89 CSR_NAME(TLBREHI), 90 CSR_NAME(TLBRPRMD), 91 CSR_NAME(MERRCTL), 92 CSR_NAME(MERRINFO1), 93 CSR_NAME(MERRINFO2), 94 CSR_NAME(MERRENTRY), 95 CSR_NAME(MERRERA), 96 CSR_NAME(MERRSAVE), 97 CSR_NAME(CTAG), 98 CSR_NAME(DMW(0)), 99 CSR_NAME(DMW(1)), 100 CSR_NAME(DMW(2)), 101 CSR_NAME(DMW(3)), 102 CSR_NAME(DBG), 103 CSR_NAME(DERA), 104 CSR_NAME(DSAVE), 105 }; 106 107 static const char *get_csr_name(unsigned num) 108 { 109 return ((num < ARRAY_SIZE(csr_names)) && (csr_names[num] != NULL)) ? 110 csr_names[num] : "Undefined CSR"; 111 } 112 113 #define output(C, INSN, FMT, ...) \ 114 { \ 115 (C)->info->fprintf_func((C)->info->stream, "%08x %-9s\t" FMT, \ 116 (C)->insn, INSN, ##__VA_ARGS__); \ 117 } 118 119 #include "decode-insns.c.inc" 120 121 int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) 122 { 123 bfd_byte buffer[4]; 124 uint32_t insn; 125 int status; 126 127 status = (*info->read_memory_func)(memaddr, buffer, 4, info); 128 if (status != 0) { 129 (*info->memory_error_func)(status, memaddr, info); 130 return -1; 131 } 132 insn = bfd_getl32(buffer); 133 DisasContext ctx = { 134 .info = info, 135 .pc = memaddr, 136 .insn = insn 137 }; 138 139 if (!decode(&ctx, insn)) { 140 output(&ctx, "illegal", ""); 141 } 142 return 4; 143 } 144 145 static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic) 146 { 147 output(ctx, mnemonic, "r%d, %d", a->rd, a->imm); 148 } 149 150 static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic) 151 { 152 output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk); 153 } 154 155 static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic) 156 { 157 output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm); 158 } 159 160 static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a, 161 const char *mnemonic) 162 { 163 output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa); 164 } 165 166 static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic) 167 { 168 output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj); 169 } 170 171 static void output_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a, 172 const char *mnemonic) 173 { 174 output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->ms, a->ls); 175 } 176 177 static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a, 178 const char *mnemonic) 179 { 180 output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm); 181 } 182 183 static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic) 184 { 185 output(ctx, mnemonic, "%d", a->imm); 186 } 187 188 static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a, 189 const char *mnemonic) 190 { 191 output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk); 192 } 193 194 static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic) 195 { 196 output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj); 197 } 198 199 static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic) 200 { 201 output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk); 202 } 203 204 static void output_ffff(DisasContext *ctx, arg_ffff *a, const char *mnemonic) 205 { 206 output(ctx, mnemonic, "f%d, f%d, f%d, f%d", a->fd, a->fj, a->fk, a->fa); 207 } 208 209 static void output_fffc(DisasContext *ctx, arg_fffc *a, const char *mnemonic) 210 { 211 output(ctx, mnemonic, "f%d, f%d, f%d, %d", a->fd, a->fj, a->fk, a->ca); 212 } 213 214 static void output_fr(DisasContext *ctx, arg_fr *a, const char *mnemonic) 215 { 216 output(ctx, mnemonic, "f%d, r%d", a->fd, a->rj); 217 } 218 219 static void output_rf(DisasContext *ctx, arg_rf *a, const char *mnemonic) 220 { 221 output(ctx, mnemonic, "r%d, f%d", a->rd, a->fj); 222 } 223 224 static void output_fcsrd_r(DisasContext *ctx, arg_fcsrd_r *a, 225 const char *mnemonic) 226 { 227 output(ctx, mnemonic, "fcsr%d, r%d", a->fcsrd, a->rj); 228 } 229 230 static void output_r_fcsrs(DisasContext *ctx, arg_r_fcsrs *a, 231 const char *mnemonic) 232 { 233 output(ctx, mnemonic, "r%d, fcsr%d", a->rd, a->fcsrs); 234 } 235 236 static void output_cf(DisasContext *ctx, arg_cf *a, const char *mnemonic) 237 { 238 output(ctx, mnemonic, "fcc%d, f%d", a->cd, a->fj); 239 } 240 241 static void output_fc(DisasContext *ctx, arg_fc *a, const char *mnemonic) 242 { 243 output(ctx, mnemonic, "f%d, fcc%d", a->fd, a->cj); 244 } 245 246 static void output_cr(DisasContext *ctx, arg_cr *a, const char *mnemonic) 247 { 248 output(ctx, mnemonic, "fcc%d, r%d", a->cd, a->rj); 249 } 250 251 static void output_rc(DisasContext *ctx, arg_rc *a, const char *mnemonic) 252 { 253 output(ctx, mnemonic, "r%d, fcc%d", a->rd, a->cj); 254 } 255 256 static void output_frr(DisasContext *ctx, arg_frr *a, const char *mnemonic) 257 { 258 output(ctx, mnemonic, "f%d, r%d, r%d", a->fd, a->rj, a->rk); 259 } 260 261 static void output_fr_i(DisasContext *ctx, arg_fr_i *a, const char *mnemonic) 262 { 263 output(ctx, mnemonic, "f%d, r%d, %d", a->fd, a->rj, a->imm); 264 } 265 266 static void output_r_offs(DisasContext *ctx, arg_r_offs *a, 267 const char *mnemonic) 268 { 269 output(ctx, mnemonic, "r%d, %d # 0x%" PRIx64, a->rj, a->offs, 270 ctx->pc + a->offs); 271 } 272 273 static void output_c_offs(DisasContext *ctx, arg_c_offs *a, 274 const char *mnemonic) 275 { 276 output(ctx, mnemonic, "fcc%d, %d # 0x%" PRIx64, a->cj, a->offs, 277 ctx->pc + a->offs); 278 } 279 280 static void output_offs(DisasContext *ctx, arg_offs *a, 281 const char *mnemonic) 282 { 283 output(ctx, mnemonic, "%d # 0x%" PRIx64, a->offs, ctx->pc + a->offs); 284 } 285 286 static void output_rr_offs(DisasContext *ctx, arg_rr_offs *a, 287 const char *mnemonic) 288 { 289 output(ctx, mnemonic, "r%d, r%d, %d # 0x%" PRIx64, a->rj, 290 a->rd, a->offs, ctx->pc + a->offs); 291 } 292 293 static void output_r_csr(DisasContext *ctx, arg_r_csr *a, 294 const char *mnemonic) 295 { 296 output(ctx, mnemonic, "r%d, %d # %s", a->rd, a->csr, get_csr_name(a->csr)); 297 } 298 299 static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a, 300 const char *mnemonic) 301 { 302 output(ctx, mnemonic, "r%d, r%d, %d # %s", 303 a->rd, a->rj, a->csr, get_csr_name(a->csr)); 304 } 305 306 static void output_empty(DisasContext *ctx, arg_empty *a, 307 const char *mnemonic) 308 { 309 output(ctx, mnemonic, ""); 310 } 311 312 static void output_i_rr(DisasContext *ctx, arg_i_rr *a, const char *mnemonic) 313 { 314 output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk); 315 } 316 317 static void output_cop_r_i(DisasContext *ctx, arg_cop_r_i *a, 318 const char *mnemonic) 319 { 320 output(ctx, mnemonic, "%d, r%d, %d", a->cop, a->rj, a->imm); 321 } 322 323 static void output_j_i(DisasContext *ctx, arg_j_i *a, const char *mnemonic) 324 { 325 output(ctx, mnemonic, "r%d, %d", a->rj, a->imm); 326 } 327 328 #define INSN(insn, type) \ 329 static bool trans_##insn(DisasContext *ctx, arg_##type * a) \ 330 { \ 331 output_##type(ctx, a, #insn); \ 332 return true; \ 333 } 334 335 INSN(clo_w, rr) 336 INSN(clz_w, rr) 337 INSN(cto_w, rr) 338 INSN(ctz_w, rr) 339 INSN(clo_d, rr) 340 INSN(clz_d, rr) 341 INSN(cto_d, rr) 342 INSN(ctz_d, rr) 343 INSN(revb_2h, rr) 344 INSN(revb_4h, rr) 345 INSN(revb_2w, rr) 346 INSN(revb_d, rr) 347 INSN(revh_2w, rr) 348 INSN(revh_d, rr) 349 INSN(bitrev_4b, rr) 350 INSN(bitrev_8b, rr) 351 INSN(bitrev_w, rr) 352 INSN(bitrev_d, rr) 353 INSN(ext_w_h, rr) 354 INSN(ext_w_b, rr) 355 INSN(rdtimel_w, rr) 356 INSN(rdtimeh_w, rr) 357 INSN(rdtime_d, rr) 358 INSN(cpucfg, rr) 359 INSN(asrtle_d, rr_jk) 360 INSN(asrtgt_d, rr_jk) 361 INSN(alsl_w, rrr_sa) 362 INSN(alsl_wu, rrr_sa) 363 INSN(bytepick_w, rrr_sa) 364 INSN(bytepick_d, rrr_sa) 365 INSN(add_w, rrr) 366 INSN(add_d, rrr) 367 INSN(sub_w, rrr) 368 INSN(sub_d, rrr) 369 INSN(slt, rrr) 370 INSN(sltu, rrr) 371 INSN(maskeqz, rrr) 372 INSN(masknez, rrr) 373 INSN(nor, rrr) 374 INSN(and, rrr) 375 INSN(or, rrr) 376 INSN(xor, rrr) 377 INSN(orn, rrr) 378 INSN(andn, rrr) 379 INSN(sll_w, rrr) 380 INSN(srl_w, rrr) 381 INSN(sra_w, rrr) 382 INSN(sll_d, rrr) 383 INSN(srl_d, rrr) 384 INSN(sra_d, rrr) 385 INSN(rotr_w, rrr) 386 INSN(rotr_d, rrr) 387 INSN(mul_w, rrr) 388 INSN(mulh_w, rrr) 389 INSN(mulh_wu, rrr) 390 INSN(mul_d, rrr) 391 INSN(mulh_d, rrr) 392 INSN(mulh_du, rrr) 393 INSN(mulw_d_w, rrr) 394 INSN(mulw_d_wu, rrr) 395 INSN(div_w, rrr) 396 INSN(mod_w, rrr) 397 INSN(div_wu, rrr) 398 INSN(mod_wu, rrr) 399 INSN(div_d, rrr) 400 INSN(mod_d, rrr) 401 INSN(div_du, rrr) 402 INSN(mod_du, rrr) 403 INSN(crc_w_b_w, rrr) 404 INSN(crc_w_h_w, rrr) 405 INSN(crc_w_w_w, rrr) 406 INSN(crc_w_d_w, rrr) 407 INSN(crcc_w_b_w, rrr) 408 INSN(crcc_w_h_w, rrr) 409 INSN(crcc_w_w_w, rrr) 410 INSN(crcc_w_d_w, rrr) 411 INSN(break, i) 412 INSN(syscall, i) 413 INSN(alsl_d, rrr_sa) 414 INSN(slli_w, rr_i) 415 INSN(slli_d, rr_i) 416 INSN(srli_w, rr_i) 417 INSN(srli_d, rr_i) 418 INSN(srai_w, rr_i) 419 INSN(srai_d, rr_i) 420 INSN(rotri_w, rr_i) 421 INSN(rotri_d, rr_i) 422 INSN(bstrins_w, rr_ms_ls) 423 INSN(bstrpick_w, rr_ms_ls) 424 INSN(bstrins_d, rr_ms_ls) 425 INSN(bstrpick_d, rr_ms_ls) 426 INSN(fadd_s, fff) 427 INSN(fadd_d, fff) 428 INSN(fsub_s, fff) 429 INSN(fsub_d, fff) 430 INSN(fmul_s, fff) 431 INSN(fmul_d, fff) 432 INSN(fdiv_s, fff) 433 INSN(fdiv_d, fff) 434 INSN(fmax_s, fff) 435 INSN(fmax_d, fff) 436 INSN(fmin_s, fff) 437 INSN(fmin_d, fff) 438 INSN(fmaxa_s, fff) 439 INSN(fmaxa_d, fff) 440 INSN(fmina_s, fff) 441 INSN(fmina_d, fff) 442 INSN(fscaleb_s, fff) 443 INSN(fscaleb_d, fff) 444 INSN(fcopysign_s, fff) 445 INSN(fcopysign_d, fff) 446 INSN(fabs_s, ff) 447 INSN(fabs_d, ff) 448 INSN(fneg_s, ff) 449 INSN(fneg_d, ff) 450 INSN(flogb_s, ff) 451 INSN(flogb_d, ff) 452 INSN(fclass_s, ff) 453 INSN(fclass_d, ff) 454 INSN(fsqrt_s, ff) 455 INSN(fsqrt_d, ff) 456 INSN(frecip_s, ff) 457 INSN(frecip_d, ff) 458 INSN(frsqrt_s, ff) 459 INSN(frsqrt_d, ff) 460 INSN(fmov_s, ff) 461 INSN(fmov_d, ff) 462 INSN(movgr2fr_w, fr) 463 INSN(movgr2fr_d, fr) 464 INSN(movgr2frh_w, fr) 465 INSN(movfr2gr_s, rf) 466 INSN(movfr2gr_d, rf) 467 INSN(movfrh2gr_s, rf) 468 INSN(movgr2fcsr, fcsrd_r) 469 INSN(movfcsr2gr, r_fcsrs) 470 INSN(movfr2cf, cf) 471 INSN(movcf2fr, fc) 472 INSN(movgr2cf, cr) 473 INSN(movcf2gr, rc) 474 INSN(fcvt_s_d, ff) 475 INSN(fcvt_d_s, ff) 476 INSN(ftintrm_w_s, ff) 477 INSN(ftintrm_w_d, ff) 478 INSN(ftintrm_l_s, ff) 479 INSN(ftintrm_l_d, ff) 480 INSN(ftintrp_w_s, ff) 481 INSN(ftintrp_w_d, ff) 482 INSN(ftintrp_l_s, ff) 483 INSN(ftintrp_l_d, ff) 484 INSN(ftintrz_w_s, ff) 485 INSN(ftintrz_w_d, ff) 486 INSN(ftintrz_l_s, ff) 487 INSN(ftintrz_l_d, ff) 488 INSN(ftintrne_w_s, ff) 489 INSN(ftintrne_w_d, ff) 490 INSN(ftintrne_l_s, ff) 491 INSN(ftintrne_l_d, ff) 492 INSN(ftint_w_s, ff) 493 INSN(ftint_w_d, ff) 494 INSN(ftint_l_s, ff) 495 INSN(ftint_l_d, ff) 496 INSN(ffint_s_w, ff) 497 INSN(ffint_s_l, ff) 498 INSN(ffint_d_w, ff) 499 INSN(ffint_d_l, ff) 500 INSN(frint_s, ff) 501 INSN(frint_d, ff) 502 INSN(slti, rr_i) 503 INSN(sltui, rr_i) 504 INSN(addi_w, rr_i) 505 INSN(addi_d, rr_i) 506 INSN(lu52i_d, rr_i) 507 INSN(andi, rr_i) 508 INSN(ori, rr_i) 509 INSN(xori, rr_i) 510 INSN(fmadd_s, ffff) 511 INSN(fmadd_d, ffff) 512 INSN(fmsub_s, ffff) 513 INSN(fmsub_d, ffff) 514 INSN(fnmadd_s, ffff) 515 INSN(fnmadd_d, ffff) 516 INSN(fnmsub_s, ffff) 517 INSN(fnmsub_d, ffff) 518 INSN(fsel, fffc) 519 INSN(addu16i_d, rr_i) 520 INSN(lu12i_w, r_i) 521 INSN(lu32i_d, r_i) 522 INSN(ll_w, rr_i) 523 INSN(sc_w, rr_i) 524 INSN(ll_d, rr_i) 525 INSN(sc_d, rr_i) 526 INSN(ldptr_w, rr_i) 527 INSN(stptr_w, rr_i) 528 INSN(ldptr_d, rr_i) 529 INSN(stptr_d, rr_i) 530 INSN(ld_b, rr_i) 531 INSN(ld_h, rr_i) 532 INSN(ld_w, rr_i) 533 INSN(ld_d, rr_i) 534 INSN(st_b, rr_i) 535 INSN(st_h, rr_i) 536 INSN(st_w, rr_i) 537 INSN(st_d, rr_i) 538 INSN(ld_bu, rr_i) 539 INSN(ld_hu, rr_i) 540 INSN(ld_wu, rr_i) 541 INSN(preld, hint_r_i) 542 INSN(fld_s, fr_i) 543 INSN(fst_s, fr_i) 544 INSN(fld_d, fr_i) 545 INSN(fst_d, fr_i) 546 INSN(ldx_b, rrr) 547 INSN(ldx_h, rrr) 548 INSN(ldx_w, rrr) 549 INSN(ldx_d, rrr) 550 INSN(stx_b, rrr) 551 INSN(stx_h, rrr) 552 INSN(stx_w, rrr) 553 INSN(stx_d, rrr) 554 INSN(ldx_bu, rrr) 555 INSN(ldx_hu, rrr) 556 INSN(ldx_wu, rrr) 557 INSN(fldx_s, frr) 558 INSN(fldx_d, frr) 559 INSN(fstx_s, frr) 560 INSN(fstx_d, frr) 561 INSN(amswap_w, rrr) 562 INSN(amswap_d, rrr) 563 INSN(amadd_w, rrr) 564 INSN(amadd_d, rrr) 565 INSN(amand_w, rrr) 566 INSN(amand_d, rrr) 567 INSN(amor_w, rrr) 568 INSN(amor_d, rrr) 569 INSN(amxor_w, rrr) 570 INSN(amxor_d, rrr) 571 INSN(ammax_w, rrr) 572 INSN(ammax_d, rrr) 573 INSN(ammin_w, rrr) 574 INSN(ammin_d, rrr) 575 INSN(ammax_wu, rrr) 576 INSN(ammax_du, rrr) 577 INSN(ammin_wu, rrr) 578 INSN(ammin_du, rrr) 579 INSN(amswap_db_w, rrr) 580 INSN(amswap_db_d, rrr) 581 INSN(amadd_db_w, rrr) 582 INSN(amadd_db_d, rrr) 583 INSN(amand_db_w, rrr) 584 INSN(amand_db_d, rrr) 585 INSN(amor_db_w, rrr) 586 INSN(amor_db_d, rrr) 587 INSN(amxor_db_w, rrr) 588 INSN(amxor_db_d, rrr) 589 INSN(ammax_db_w, rrr) 590 INSN(ammax_db_d, rrr) 591 INSN(ammin_db_w, rrr) 592 INSN(ammin_db_d, rrr) 593 INSN(ammax_db_wu, rrr) 594 INSN(ammax_db_du, rrr) 595 INSN(ammin_db_wu, rrr) 596 INSN(ammin_db_du, rrr) 597 INSN(dbar, i) 598 INSN(ibar, i) 599 INSN(fldgt_s, frr) 600 INSN(fldgt_d, frr) 601 INSN(fldle_s, frr) 602 INSN(fldle_d, frr) 603 INSN(fstgt_s, frr) 604 INSN(fstgt_d, frr) 605 INSN(fstle_s, frr) 606 INSN(fstle_d, frr) 607 INSN(ldgt_b, rrr) 608 INSN(ldgt_h, rrr) 609 INSN(ldgt_w, rrr) 610 INSN(ldgt_d, rrr) 611 INSN(ldle_b, rrr) 612 INSN(ldle_h, rrr) 613 INSN(ldle_w, rrr) 614 INSN(ldle_d, rrr) 615 INSN(stgt_b, rrr) 616 INSN(stgt_h, rrr) 617 INSN(stgt_w, rrr) 618 INSN(stgt_d, rrr) 619 INSN(stle_b, rrr) 620 INSN(stle_h, rrr) 621 INSN(stle_w, rrr) 622 INSN(stle_d, rrr) 623 INSN(beqz, r_offs) 624 INSN(bnez, r_offs) 625 INSN(bceqz, c_offs) 626 INSN(bcnez, c_offs) 627 INSN(jirl, rr_i) 628 INSN(b, offs) 629 INSN(bl, offs) 630 INSN(beq, rr_offs) 631 INSN(bne, rr_offs) 632 INSN(blt, rr_offs) 633 INSN(bge, rr_offs) 634 INSN(bltu, rr_offs) 635 INSN(bgeu, rr_offs) 636 INSN(csrrd, r_csr) 637 INSN(csrwr, r_csr) 638 INSN(csrxchg, rr_csr) 639 INSN(iocsrrd_b, rr) 640 INSN(iocsrrd_h, rr) 641 INSN(iocsrrd_w, rr) 642 INSN(iocsrrd_d, rr) 643 INSN(iocsrwr_b, rr) 644 INSN(iocsrwr_h, rr) 645 INSN(iocsrwr_w, rr) 646 INSN(iocsrwr_d, rr) 647 INSN(tlbsrch, empty) 648 INSN(tlbrd, empty) 649 INSN(tlbwr, empty) 650 INSN(tlbfill, empty) 651 INSN(tlbclr, empty) 652 INSN(tlbflush, empty) 653 INSN(invtlb, i_rr) 654 INSN(cacop, cop_r_i) 655 INSN(lddir, rr_i) 656 INSN(ldpte, j_i) 657 INSN(ertn, empty) 658 INSN(idle, i) 659 INSN(dbcl, i) 660 661 #define output_fcmp(C, PREFIX, SUFFIX) \ 662 { \ 663 (C)->info->fprintf_func((C)->info->stream, "%08x %s%s\tfcc%d, f%d, f%d", \ 664 (C)->insn, PREFIX, SUFFIX, a->cd, \ 665 a->fj, a->fk); \ 666 } 667 668 static bool output_cff_fcond(DisasContext *ctx, arg_cff_fcond * a, 669 const char *suffix) 670 { 671 bool ret = true; 672 switch (a->fcond) { 673 case 0x0: 674 output_fcmp(ctx, "fcmp_caf_", suffix); 675 break; 676 case 0x1: 677 output_fcmp(ctx, "fcmp_saf_", suffix); 678 break; 679 case 0x2: 680 output_fcmp(ctx, "fcmp_clt_", suffix); 681 break; 682 case 0x3: 683 output_fcmp(ctx, "fcmp_slt_", suffix); 684 break; 685 case 0x4: 686 output_fcmp(ctx, "fcmp_ceq_", suffix); 687 break; 688 case 0x5: 689 output_fcmp(ctx, "fcmp_seq_", suffix); 690 break; 691 case 0x6: 692 output_fcmp(ctx, "fcmp_cle_", suffix); 693 break; 694 case 0x7: 695 output_fcmp(ctx, "fcmp_sle_", suffix); 696 break; 697 case 0x8: 698 output_fcmp(ctx, "fcmp_cun_", suffix); 699 break; 700 case 0x9: 701 output_fcmp(ctx, "fcmp_sun_", suffix); 702 break; 703 case 0xA: 704 output_fcmp(ctx, "fcmp_cult_", suffix); 705 break; 706 case 0xB: 707 output_fcmp(ctx, "fcmp_sult_", suffix); 708 break; 709 case 0xC: 710 output_fcmp(ctx, "fcmp_cueq_", suffix); 711 break; 712 case 0xD: 713 output_fcmp(ctx, "fcmp_sueq_", suffix); 714 break; 715 case 0xE: 716 output_fcmp(ctx, "fcmp_cule_", suffix); 717 break; 718 case 0xF: 719 output_fcmp(ctx, "fcmp_sule_", suffix); 720 break; 721 case 0x10: 722 output_fcmp(ctx, "fcmp_cne_", suffix); 723 break; 724 case 0x11: 725 output_fcmp(ctx, "fcmp_sne_", suffix); 726 break; 727 case 0x14: 728 output_fcmp(ctx, "fcmp_cor_", suffix); 729 break; 730 case 0x15: 731 output_fcmp(ctx, "fcmp_sor_", suffix); 732 break; 733 case 0x18: 734 output_fcmp(ctx, "fcmp_cune_", suffix); 735 break; 736 case 0x19: 737 output_fcmp(ctx, "fcmp_sune_", suffix); 738 break; 739 default: 740 ret = false; 741 } 742 return ret; 743 } 744 745 #define FCMP_INSN(suffix) \ 746 static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \ 747 arg_cff_fcond * a) \ 748 { \ 749 return output_cff_fcond(ctx, a, #suffix); \ 750 } 751 752 FCMP_INSN(s) 753 FCMP_INSN(d) 754 755 #define PCADD_INSN(name) \ 756 static bool trans_##name(DisasContext *ctx, arg_##name *a) \ 757 { \ 758 output(ctx, #name, "r%d, %d # 0x%" PRIx64, \ 759 a->rd, a->imm, gen_##name(ctx->pc, a->imm)); \ 760 return true; \ 761 } 762 763 static uint64_t gen_pcaddi(uint64_t pc, int imm) 764 { 765 return pc + (imm << 2); 766 } 767 768 static uint64_t gen_pcalau12i(uint64_t pc, int imm) 769 { 770 return (pc + (imm << 12)) & ~0xfff; 771 } 772 773 static uint64_t gen_pcaddu12i(uint64_t pc, int imm) 774 { 775 return pc + (imm << 12); 776 } 777 778 static uint64_t gen_pcaddu18i(uint64_t pc, int imm) 779 { 780 return pc + ((uint64_t)(imm) << 18); 781 } 782 783 PCADD_INSN(pcaddi) 784 PCADD_INSN(pcalau12i) 785 PCADD_INSN(pcaddu12i) 786 PCADD_INSN(pcaddu18i) 787