qemu/target/loongarch/disas.c
<<
>>
Prefs
   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
  13typedef struct {
  14    disassemble_info *info;
  15    uint64_t pc;
  16    uint32_t insn;
  17} DisasContext;
  18
  19static inline int plus_1(DisasContext *ctx, int x)
  20{
  21    return x + 1;
  22}
  23
  24static 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
  32static 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
 107static 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
 121int 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
 145static 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
 150static 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
 155static 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
 160static 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
 166static 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
 171static 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
 177static 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
 183static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
 184{
 185    output(ctx, mnemonic, "%d", a->imm);
 186}
 187
 188static 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
 194static 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
 199static 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
 204static 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
 209static 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
 214static 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
 219static 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
 224static 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
 230static 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
 236static 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
 241static 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
 246static 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
 251static 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
 256static 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
 261static 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
 266static 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
 273static 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
 280static 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
 286static 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
 293static 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
 299static 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
 306static void output_empty(DisasContext *ctx, arg_empty *a,
 307                         const char *mnemonic)
 308{
 309    output(ctx, mnemonic, "");
 310}
 311
 312static 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
 317static 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
 323static 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)                                    \
 329static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
 330{                                                           \
 331    output_##type(ctx, a, #insn);                           \
 332    return true;                                            \
 333}
 334
 335INSN(clo_w,        rr)
 336INSN(clz_w,        rr)
 337INSN(cto_w,        rr)
 338INSN(ctz_w,        rr)
 339INSN(clo_d,        rr)
 340INSN(clz_d,        rr)
 341INSN(cto_d,        rr)
 342INSN(ctz_d,        rr)
 343INSN(revb_2h,      rr)
 344INSN(revb_4h,      rr)
 345INSN(revb_2w,      rr)
 346INSN(revb_d,       rr)
 347INSN(revh_2w,      rr)
 348INSN(revh_d,       rr)
 349INSN(bitrev_4b,    rr)
 350INSN(bitrev_8b,    rr)
 351INSN(bitrev_w,     rr)
 352INSN(bitrev_d,     rr)
 353INSN(ext_w_h,      rr)
 354INSN(ext_w_b,      rr)
 355INSN(rdtimel_w,    rr)
 356INSN(rdtimeh_w,    rr)
 357INSN(rdtime_d,     rr)
 358INSN(cpucfg,       rr)
 359INSN(asrtle_d,     rr_jk)
 360INSN(asrtgt_d,     rr_jk)
 361INSN(alsl_w,       rrr_sa)
 362INSN(alsl_wu,      rrr_sa)
 363INSN(bytepick_w,   rrr_sa)
 364INSN(bytepick_d,   rrr_sa)
 365INSN(add_w,        rrr)
 366INSN(add_d,        rrr)
 367INSN(sub_w,        rrr)
 368INSN(sub_d,        rrr)
 369INSN(slt,          rrr)
 370INSN(sltu,         rrr)
 371INSN(maskeqz,      rrr)
 372INSN(masknez,      rrr)
 373INSN(nor,          rrr)
 374INSN(and,          rrr)
 375INSN(or,           rrr)
 376INSN(xor,          rrr)
 377INSN(orn,          rrr)
 378INSN(andn,         rrr)
 379INSN(sll_w,        rrr)
 380INSN(srl_w,        rrr)
 381INSN(sra_w,        rrr)
 382INSN(sll_d,        rrr)
 383INSN(srl_d,        rrr)
 384INSN(sra_d,        rrr)
 385INSN(rotr_w,       rrr)
 386INSN(rotr_d,       rrr)
 387INSN(mul_w,        rrr)
 388INSN(mulh_w,       rrr)
 389INSN(mulh_wu,      rrr)
 390INSN(mul_d,        rrr)
 391INSN(mulh_d,       rrr)
 392INSN(mulh_du,      rrr)
 393INSN(mulw_d_w,     rrr)
 394INSN(mulw_d_wu,    rrr)
 395INSN(div_w,        rrr)
 396INSN(mod_w,        rrr)
 397INSN(div_wu,       rrr)
 398INSN(mod_wu,       rrr)
 399INSN(div_d,        rrr)
 400INSN(mod_d,        rrr)
 401INSN(div_du,       rrr)
 402INSN(mod_du,       rrr)
 403INSN(crc_w_b_w,    rrr)
 404INSN(crc_w_h_w,    rrr)
 405INSN(crc_w_w_w,    rrr)
 406INSN(crc_w_d_w,    rrr)
 407INSN(crcc_w_b_w,   rrr)
 408INSN(crcc_w_h_w,   rrr)
 409INSN(crcc_w_w_w,   rrr)
 410INSN(crcc_w_d_w,   rrr)
 411INSN(break,        i)
 412INSN(syscall,      i)
 413INSN(alsl_d,       rrr_sa)
 414INSN(slli_w,       rr_i)
 415INSN(slli_d,       rr_i)
 416INSN(srli_w,       rr_i)
 417INSN(srli_d,       rr_i)
 418INSN(srai_w,       rr_i)
 419INSN(srai_d,       rr_i)
 420INSN(rotri_w,      rr_i)
 421INSN(rotri_d,      rr_i)
 422INSN(bstrins_w,    rr_ms_ls)
 423INSN(bstrpick_w,   rr_ms_ls)
 424INSN(bstrins_d,    rr_ms_ls)
 425INSN(bstrpick_d,   rr_ms_ls)
 426INSN(fadd_s,       fff)
 427INSN(fadd_d,       fff)
 428INSN(fsub_s,       fff)
 429INSN(fsub_d,       fff)
 430INSN(fmul_s,       fff)
 431INSN(fmul_d,       fff)
 432INSN(fdiv_s,       fff)
 433INSN(fdiv_d,       fff)
 434INSN(fmax_s,       fff)
 435INSN(fmax_d,       fff)
 436INSN(fmin_s,       fff)
 437INSN(fmin_d,       fff)
 438INSN(fmaxa_s,      fff)
 439INSN(fmaxa_d,      fff)
 440INSN(fmina_s,      fff)
 441INSN(fmina_d,      fff)
 442INSN(fscaleb_s,    fff)
 443INSN(fscaleb_d,    fff)
 444INSN(fcopysign_s,  fff)
 445INSN(fcopysign_d,  fff)
 446INSN(fabs_s,       ff)
 447INSN(fabs_d,       ff)
 448INSN(fneg_s,       ff)
 449INSN(fneg_d,       ff)
 450INSN(flogb_s,      ff)
 451INSN(flogb_d,      ff)
 452INSN(fclass_s,     ff)
 453INSN(fclass_d,     ff)
 454INSN(fsqrt_s,      ff)
 455INSN(fsqrt_d,      ff)
 456INSN(frecip_s,     ff)
 457INSN(frecip_d,     ff)
 458INSN(frsqrt_s,     ff)
 459INSN(frsqrt_d,     ff)
 460INSN(fmov_s,       ff)
 461INSN(fmov_d,       ff)
 462INSN(movgr2fr_w,   fr)
 463INSN(movgr2fr_d,   fr)
 464INSN(movgr2frh_w,  fr)
 465INSN(movfr2gr_s,   rf)
 466INSN(movfr2gr_d,   rf)
 467INSN(movfrh2gr_s,  rf)
 468INSN(movgr2fcsr,   fcsrd_r)
 469INSN(movfcsr2gr,   r_fcsrs)
 470INSN(movfr2cf,     cf)
 471INSN(movcf2fr,     fc)
 472INSN(movgr2cf,     cr)
 473INSN(movcf2gr,     rc)
 474INSN(fcvt_s_d,     ff)
 475INSN(fcvt_d_s,     ff)
 476INSN(ftintrm_w_s,  ff)
 477INSN(ftintrm_w_d,  ff)
 478INSN(ftintrm_l_s,  ff)
 479INSN(ftintrm_l_d,  ff)
 480INSN(ftintrp_w_s,  ff)
 481INSN(ftintrp_w_d,  ff)
 482INSN(ftintrp_l_s,  ff)
 483INSN(ftintrp_l_d,  ff)
 484INSN(ftintrz_w_s,  ff)
 485INSN(ftintrz_w_d,  ff)
 486INSN(ftintrz_l_s,  ff)
 487INSN(ftintrz_l_d,  ff)
 488INSN(ftintrne_w_s, ff)
 489INSN(ftintrne_w_d, ff)
 490INSN(ftintrne_l_s, ff)
 491INSN(ftintrne_l_d, ff)
 492INSN(ftint_w_s,    ff)
 493INSN(ftint_w_d,    ff)
 494INSN(ftint_l_s,    ff)
 495INSN(ftint_l_d,    ff)
 496INSN(ffint_s_w,    ff)
 497INSN(ffint_s_l,    ff)
 498INSN(ffint_d_w,    ff)
 499INSN(ffint_d_l,    ff)
 500INSN(frint_s,      ff)
 501INSN(frint_d,      ff)
 502INSN(slti,         rr_i)
 503INSN(sltui,        rr_i)
 504INSN(addi_w,       rr_i)
 505INSN(addi_d,       rr_i)
 506INSN(lu52i_d,      rr_i)
 507INSN(andi,         rr_i)
 508INSN(ori,          rr_i)
 509INSN(xori,         rr_i)
 510INSN(fmadd_s,      ffff)
 511INSN(fmadd_d,      ffff)
 512INSN(fmsub_s,      ffff)
 513INSN(fmsub_d,      ffff)
 514INSN(fnmadd_s,     ffff)
 515INSN(fnmadd_d,     ffff)
 516INSN(fnmsub_s,     ffff)
 517INSN(fnmsub_d,     ffff)
 518INSN(fsel,         fffc)
 519INSN(addu16i_d,    rr_i)
 520INSN(lu12i_w,      r_i)
 521INSN(lu32i_d,      r_i)
 522INSN(pcaddi,       r_i)
 523INSN(pcalau12i,    r_i)
 524INSN(pcaddu12i,    r_i)
 525INSN(pcaddu18i,    r_i)
 526INSN(ll_w,         rr_i)
 527INSN(sc_w,         rr_i)
 528INSN(ll_d,         rr_i)
 529INSN(sc_d,         rr_i)
 530INSN(ldptr_w,      rr_i)
 531INSN(stptr_w,      rr_i)
 532INSN(ldptr_d,      rr_i)
 533INSN(stptr_d,      rr_i)
 534INSN(ld_b,         rr_i)
 535INSN(ld_h,         rr_i)
 536INSN(ld_w,         rr_i)
 537INSN(ld_d,         rr_i)
 538INSN(st_b,         rr_i)
 539INSN(st_h,         rr_i)
 540INSN(st_w,         rr_i)
 541INSN(st_d,         rr_i)
 542INSN(ld_bu,        rr_i)
 543INSN(ld_hu,        rr_i)
 544INSN(ld_wu,        rr_i)
 545INSN(preld,        hint_r_i)
 546INSN(fld_s,        fr_i)
 547INSN(fst_s,        fr_i)
 548INSN(fld_d,        fr_i)
 549INSN(fst_d,        fr_i)
 550INSN(ldx_b,        rrr)
 551INSN(ldx_h,        rrr)
 552INSN(ldx_w,        rrr)
 553INSN(ldx_d,        rrr)
 554INSN(stx_b,        rrr)
 555INSN(stx_h,        rrr)
 556INSN(stx_w,        rrr)
 557INSN(stx_d,        rrr)
 558INSN(ldx_bu,       rrr)
 559INSN(ldx_hu,       rrr)
 560INSN(ldx_wu,       rrr)
 561INSN(fldx_s,       frr)
 562INSN(fldx_d,       frr)
 563INSN(fstx_s,       frr)
 564INSN(fstx_d,       frr)
 565INSN(amswap_w,     rrr)
 566INSN(amswap_d,     rrr)
 567INSN(amadd_w,      rrr)
 568INSN(amadd_d,      rrr)
 569INSN(amand_w,      rrr)
 570INSN(amand_d,      rrr)
 571INSN(amor_w,       rrr)
 572INSN(amor_d,       rrr)
 573INSN(amxor_w,      rrr)
 574INSN(amxor_d,      rrr)
 575INSN(ammax_w,      rrr)
 576INSN(ammax_d,      rrr)
 577INSN(ammin_w,      rrr)
 578INSN(ammin_d,      rrr)
 579INSN(ammax_wu,     rrr)
 580INSN(ammax_du,     rrr)
 581INSN(ammin_wu,     rrr)
 582INSN(ammin_du,     rrr)
 583INSN(amswap_db_w,  rrr)
 584INSN(amswap_db_d,  rrr)
 585INSN(amadd_db_w,   rrr)
 586INSN(amadd_db_d,   rrr)
 587INSN(amand_db_w,   rrr)
 588INSN(amand_db_d,   rrr)
 589INSN(amor_db_w,    rrr)
 590INSN(amor_db_d,    rrr)
 591INSN(amxor_db_w,   rrr)
 592INSN(amxor_db_d,   rrr)
 593INSN(ammax_db_w,   rrr)
 594INSN(ammax_db_d,   rrr)
 595INSN(ammin_db_w,   rrr)
 596INSN(ammin_db_d,   rrr)
 597INSN(ammax_db_wu,  rrr)
 598INSN(ammax_db_du,  rrr)
 599INSN(ammin_db_wu,  rrr)
 600INSN(ammin_db_du,  rrr)
 601INSN(dbar,         i)
 602INSN(ibar,         i)
 603INSN(fldgt_s,      frr)
 604INSN(fldgt_d,      frr)
 605INSN(fldle_s,      frr)
 606INSN(fldle_d,      frr)
 607INSN(fstgt_s,      frr)
 608INSN(fstgt_d,      frr)
 609INSN(fstle_s,      frr)
 610INSN(fstle_d,      frr)
 611INSN(ldgt_b,       rrr)
 612INSN(ldgt_h,       rrr)
 613INSN(ldgt_w,       rrr)
 614INSN(ldgt_d,       rrr)
 615INSN(ldle_b,       rrr)
 616INSN(ldle_h,       rrr)
 617INSN(ldle_w,       rrr)
 618INSN(ldle_d,       rrr)
 619INSN(stgt_b,       rrr)
 620INSN(stgt_h,       rrr)
 621INSN(stgt_w,       rrr)
 622INSN(stgt_d,       rrr)
 623INSN(stle_b,       rrr)
 624INSN(stle_h,       rrr)
 625INSN(stle_w,       rrr)
 626INSN(stle_d,       rrr)
 627INSN(beqz,         r_offs)
 628INSN(bnez,         r_offs)
 629INSN(bceqz,        c_offs)
 630INSN(bcnez,        c_offs)
 631INSN(jirl,         rr_offs)
 632INSN(b,            offs)
 633INSN(bl,           offs)
 634INSN(beq,          rr_offs)
 635INSN(bne,          rr_offs)
 636INSN(blt,          rr_offs)
 637INSN(bge,          rr_offs)
 638INSN(bltu,         rr_offs)
 639INSN(bgeu,         rr_offs)
 640INSN(csrrd,        r_csr)
 641INSN(csrwr,        r_csr)
 642INSN(csrxchg,      rr_csr)
 643INSN(iocsrrd_b,    rr)
 644INSN(iocsrrd_h,    rr)
 645INSN(iocsrrd_w,    rr)
 646INSN(iocsrrd_d,    rr)
 647INSN(iocsrwr_b,    rr)
 648INSN(iocsrwr_h,    rr)
 649INSN(iocsrwr_w,    rr)
 650INSN(iocsrwr_d,    rr)
 651INSN(tlbsrch,      empty)
 652INSN(tlbrd,        empty)
 653INSN(tlbwr,        empty)
 654INSN(tlbfill,      empty)
 655INSN(tlbclr,       empty)
 656INSN(tlbflush,     empty)
 657INSN(invtlb,       i_rr)
 658INSN(cacop,        cop_r_i)
 659INSN(lddir,        rr_i)
 660INSN(ldpte,        j_i)
 661INSN(ertn,         empty)
 662INSN(idle,         i)
 663INSN(dbcl,         i)
 664
 665#define output_fcmp(C, PREFIX, SUFFIX)                                         \
 666{                                                                              \
 667    (C)->info->fprintf_func((C)->info->stream, "%08x   %s%s\tfcc%d, f%d, f%d", \
 668                            (C)->insn, PREFIX, SUFFIX, a->cd,                  \
 669                            a->fj, a->fk);                                     \
 670}
 671
 672static bool output_cff_fcond(DisasContext *ctx, arg_cff_fcond * a,
 673                               const char *suffix)
 674{
 675    bool ret = true;
 676    switch (a->fcond) {
 677    case 0x0:
 678        output_fcmp(ctx, "fcmp_caf_", suffix);
 679        break;
 680    case 0x1:
 681        output_fcmp(ctx, "fcmp_saf_", suffix);
 682        break;
 683    case 0x2:
 684        output_fcmp(ctx, "fcmp_clt_", suffix);
 685        break;
 686    case 0x3:
 687        output_fcmp(ctx, "fcmp_slt_", suffix);
 688        break;
 689    case 0x4:
 690        output_fcmp(ctx, "fcmp_ceq_", suffix);
 691        break;
 692    case 0x5:
 693        output_fcmp(ctx, "fcmp_seq_", suffix);
 694        break;
 695    case 0x6:
 696        output_fcmp(ctx, "fcmp_cle_", suffix);
 697        break;
 698    case 0x7:
 699        output_fcmp(ctx, "fcmp_sle_", suffix);
 700        break;
 701    case 0x8:
 702        output_fcmp(ctx, "fcmp_cun_", suffix);
 703        break;
 704    case 0x9:
 705        output_fcmp(ctx, "fcmp_sun_", suffix);
 706        break;
 707    case 0xA:
 708        output_fcmp(ctx, "fcmp_cult_", suffix);
 709        break;
 710    case 0xB:
 711        output_fcmp(ctx, "fcmp_sult_", suffix);
 712        break;
 713    case 0xC:
 714        output_fcmp(ctx, "fcmp_cueq_", suffix);
 715        break;
 716    case 0xD:
 717        output_fcmp(ctx, "fcmp_sueq_", suffix);
 718        break;
 719    case 0xE:
 720        output_fcmp(ctx, "fcmp_cule_", suffix);
 721        break;
 722    case 0xF:
 723        output_fcmp(ctx, "fcmp_sule_", suffix);
 724        break;
 725    case 0x10:
 726        output_fcmp(ctx, "fcmp_cne_", suffix);
 727        break;
 728    case 0x11:
 729        output_fcmp(ctx, "fcmp_sne_", suffix);
 730        break;
 731    case 0x14:
 732        output_fcmp(ctx, "fcmp_cor_", suffix);
 733        break;
 734    case 0x15:
 735        output_fcmp(ctx, "fcmp_sor_", suffix);
 736        break;
 737    case 0x18:
 738        output_fcmp(ctx, "fcmp_cune_", suffix);
 739        break;
 740    case 0x19:
 741        output_fcmp(ctx, "fcmp_sune_", suffix);
 742        break;
 743    default:
 744        ret = false;
 745    }
 746    return ret;
 747}
 748
 749#define FCMP_INSN(suffix)                               \
 750static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \
 751                                     arg_cff_fcond * a) \
 752{                                                       \
 753    return output_cff_fcond(ctx, a, #suffix);           \
 754}
 755
 756FCMP_INSN(s)
 757FCMP_INSN(d)
 758