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