qemu/target/sparc/translate.c
<<
>>
Prefs
   1/*
   2   SPARC translation
   3
   4   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
   5   Copyright (C) 2003-2005 Fabrice Bellard
   6
   7   This library is free software; you can redistribute it and/or
   8   modify it under the terms of the GNU Lesser General Public
   9   License as published by the Free Software Foundation; either
  10   version 2 of the License, or (at your option) any later version.
  11
  12   This library is distributed in the hope that it will be useful,
  13   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15   Lesser General Public License for more details.
  16
  17   You should have received a copy of the GNU Lesser General Public
  18   License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu/osdep.h"
  22
  23#include "cpu.h"
  24#include "disas/disas.h"
  25#include "exec/helper-proto.h"
  26#include "exec/exec-all.h"
  27#include "tcg-op.h"
  28#include "exec/cpu_ldst.h"
  29
  30#include "exec/helper-gen.h"
  31
  32#include "trace-tcg.h"
  33#include "exec/log.h"
  34#include "asi.h"
  35
  36
  37#define DEBUG_DISAS
  38
  39#define DYNAMIC_PC  1 /* dynamic pc value */
  40#define JUMP_PC     2 /* dynamic pc value which takes only two values
  41                         according to jump_pc[T2] */
  42
  43/* global register indexes */
  44static TCGv_env cpu_env;
  45static TCGv_ptr cpu_regwptr;
  46static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
  47static TCGv_i32 cpu_cc_op;
  48static TCGv_i32 cpu_psr;
  49static TCGv cpu_fsr, cpu_pc, cpu_npc;
  50static TCGv cpu_regs[32];
  51static TCGv cpu_y;
  52#ifndef CONFIG_USER_ONLY
  53static TCGv cpu_tbr;
  54#endif
  55static TCGv cpu_cond;
  56#ifdef TARGET_SPARC64
  57static TCGv_i32 cpu_xcc, cpu_fprs;
  58static TCGv cpu_gsr;
  59static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
  60static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
  61#else
  62static TCGv cpu_wim;
  63#endif
  64/* Floating point registers */
  65static TCGv_i64 cpu_fpr[TARGET_DPREGS];
  66
  67#include "exec/gen-icount.h"
  68
  69typedef struct DisasContext {
  70    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
  71    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
  72    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
  73    int is_br;
  74    int mem_idx;
  75    bool fpu_enabled;
  76    bool address_mask_32bit;
  77    bool singlestep;
  78#ifndef CONFIG_USER_ONLY
  79    bool supervisor;
  80#ifdef TARGET_SPARC64
  81    bool hypervisor;
  82#endif
  83#endif
  84
  85    uint32_t cc_op;  /* current CC operation */
  86    struct TranslationBlock *tb;
  87    sparc_def_t *def;
  88    TCGv_i32 t32[3];
  89    TCGv ttl[5];
  90    int n_t32;
  91    int n_ttl;
  92#ifdef TARGET_SPARC64
  93    int fprs_dirty;
  94    int asi;
  95#endif
  96} DisasContext;
  97
  98typedef struct {
  99    TCGCond cond;
 100    bool is_bool;
 101    bool g1, g2;
 102    TCGv c1, c2;
 103} DisasCompare;
 104
 105// This function uses non-native bit order
 106#define GET_FIELD(X, FROM, TO)                                  \
 107    ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
 108
 109// This function uses the order in the manuals, i.e. bit 0 is 2^0
 110#define GET_FIELD_SP(X, FROM, TO)               \
 111    GET_FIELD(X, 31 - (TO), 31 - (FROM))
 112
 113#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
 114#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
 115
 116#ifdef TARGET_SPARC64
 117#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
 118#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
 119#else
 120#define DFPREG(r) (r & 0x1e)
 121#define QFPREG(r) (r & 0x1c)
 122#endif
 123
 124#define UA2005_HTRAP_MASK 0xff
 125#define V8_TRAP_MASK 0x7f
 126
 127static int sign_extend(int x, int len)
 128{
 129    len = 32 - len;
 130    return (x << len) >> len;
 131}
 132
 133#define IS_IMM (insn & (1<<13))
 134
 135static inline TCGv_i32 get_temp_i32(DisasContext *dc)
 136{
 137    TCGv_i32 t;
 138    assert(dc->n_t32 < ARRAY_SIZE(dc->t32));
 139    dc->t32[dc->n_t32++] = t = tcg_temp_new_i32();
 140    return t;
 141}
 142
 143static inline TCGv get_temp_tl(DisasContext *dc)
 144{
 145    TCGv t;
 146    assert(dc->n_ttl < ARRAY_SIZE(dc->ttl));
 147    dc->ttl[dc->n_ttl++] = t = tcg_temp_new();
 148    return t;
 149}
 150
 151static inline void gen_update_fprs_dirty(DisasContext *dc, int rd)
 152{
 153#if defined(TARGET_SPARC64)
 154    int bit = (rd < 32) ? 1 : 2;
 155    /* If we know we've already set this bit within the TB,
 156       we can avoid setting it again.  */
 157    if (!(dc->fprs_dirty & bit)) {
 158        dc->fprs_dirty |= bit;
 159        tcg_gen_ori_i32(cpu_fprs, cpu_fprs, bit);
 160    }
 161#endif
 162}
 163
 164/* floating point registers moves */
 165static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src)
 166{
 167#if TCG_TARGET_REG_BITS == 32
 168    if (src & 1) {
 169        return TCGV_LOW(cpu_fpr[src / 2]);
 170    } else {
 171        return TCGV_HIGH(cpu_fpr[src / 2]);
 172    }
 173#else
 174    if (src & 1) {
 175        return MAKE_TCGV_I32(GET_TCGV_I64(cpu_fpr[src / 2]));
 176    } else {
 177        TCGv_i32 ret = get_temp_i32(dc);
 178        TCGv_i64 t = tcg_temp_new_i64();
 179
 180        tcg_gen_shri_i64(t, cpu_fpr[src / 2], 32);
 181        tcg_gen_extrl_i64_i32(ret, t);
 182        tcg_temp_free_i64(t);
 183
 184        return ret;
 185    }
 186#endif
 187}
 188
 189static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
 190{
 191#if TCG_TARGET_REG_BITS == 32
 192    if (dst & 1) {
 193        tcg_gen_mov_i32(TCGV_LOW(cpu_fpr[dst / 2]), v);
 194    } else {
 195        tcg_gen_mov_i32(TCGV_HIGH(cpu_fpr[dst / 2]), v);
 196    }
 197#else
 198    TCGv_i64 t = MAKE_TCGV_I64(GET_TCGV_I32(v));
 199    tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
 200                        (dst & 1 ? 0 : 32), 32);
 201#endif
 202    gen_update_fprs_dirty(dc, dst);
 203}
 204
 205static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
 206{
 207    return get_temp_i32(dc);
 208}
 209
 210static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src)
 211{
 212    src = DFPREG(src);
 213    return cpu_fpr[src / 2];
 214}
 215
 216static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v)
 217{
 218    dst = DFPREG(dst);
 219    tcg_gen_mov_i64(cpu_fpr[dst / 2], v);
 220    gen_update_fprs_dirty(dc, dst);
 221}
 222
 223static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
 224{
 225    return cpu_fpr[DFPREG(dst) / 2];
 226}
 227
 228static void gen_op_load_fpr_QT0(unsigned int src)
 229{
 230    tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt0) +
 231                   offsetof(CPU_QuadU, ll.upper));
 232    tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
 233                   offsetof(CPU_QuadU, ll.lower));
 234}
 235
 236static void gen_op_load_fpr_QT1(unsigned int src)
 237{
 238    tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt1) +
 239                   offsetof(CPU_QuadU, ll.upper));
 240    tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt1) +
 241                   offsetof(CPU_QuadU, ll.lower));
 242}
 243
 244static void gen_op_store_QT0_fpr(unsigned int dst)
 245{
 246    tcg_gen_ld_i64(cpu_fpr[dst / 2], cpu_env, offsetof(CPUSPARCState, qt0) +
 247                   offsetof(CPU_QuadU, ll.upper));
 248    tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
 249                   offsetof(CPU_QuadU, ll.lower));
 250}
 251
 252static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst,
 253                            TCGv_i64 v1, TCGv_i64 v2)
 254{
 255    dst = QFPREG(dst);
 256
 257    tcg_gen_mov_i64(cpu_fpr[dst / 2], v1);
 258    tcg_gen_mov_i64(cpu_fpr[dst / 2 + 1], v2);
 259    gen_update_fprs_dirty(dc, dst);
 260}
 261
 262#ifdef TARGET_SPARC64
 263static TCGv_i64 gen_load_fpr_Q0(DisasContext *dc, unsigned int src)
 264{
 265    src = QFPREG(src);
 266    return cpu_fpr[src / 2];
 267}
 268
 269static TCGv_i64 gen_load_fpr_Q1(DisasContext *dc, unsigned int src)
 270{
 271    src = QFPREG(src);
 272    return cpu_fpr[src / 2 + 1];
 273}
 274
 275static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
 276{
 277    rd = QFPREG(rd);
 278    rs = QFPREG(rs);
 279
 280    tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
 281    tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
 282    gen_update_fprs_dirty(dc, rd);
 283}
 284#endif
 285
 286/* moves */
 287#ifdef CONFIG_USER_ONLY
 288#define supervisor(dc) 0
 289#ifdef TARGET_SPARC64
 290#define hypervisor(dc) 0
 291#endif
 292#else
 293#ifdef TARGET_SPARC64
 294#define hypervisor(dc) (dc->hypervisor)
 295#define supervisor(dc) (dc->supervisor | dc->hypervisor)
 296#else
 297#define supervisor(dc) (dc->supervisor)
 298#endif
 299#endif
 300
 301#ifdef TARGET_SPARC64
 302#ifndef TARGET_ABI32
 303#define AM_CHECK(dc) ((dc)->address_mask_32bit)
 304#else
 305#define AM_CHECK(dc) (1)
 306#endif
 307#endif
 308
 309static inline void gen_address_mask(DisasContext *dc, TCGv addr)
 310{
 311#ifdef TARGET_SPARC64
 312    if (AM_CHECK(dc))
 313        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
 314#endif
 315}
 316
 317static inline TCGv gen_load_gpr(DisasContext *dc, int reg)
 318{
 319    if (reg > 0) {
 320        assert(reg < 32);
 321        return cpu_regs[reg];
 322    } else {
 323        TCGv t = get_temp_tl(dc);
 324        tcg_gen_movi_tl(t, 0);
 325        return t;
 326    }
 327}
 328
 329static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v)
 330{
 331    if (reg > 0) {
 332        assert(reg < 32);
 333        tcg_gen_mov_tl(cpu_regs[reg], v);
 334    }
 335}
 336
 337static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
 338{
 339    if (reg > 0) {
 340        assert(reg < 32);
 341        return cpu_regs[reg];
 342    } else {
 343        return get_temp_tl(dc);
 344    }
 345}
 346
 347static inline bool use_goto_tb(DisasContext *s, target_ulong pc,
 348                               target_ulong npc)
 349{
 350    if (unlikely(s->singlestep)) {
 351        return false;
 352    }
 353
 354#ifndef CONFIG_USER_ONLY
 355    return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) &&
 356           (npc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK);
 357#else
 358    return true;
 359#endif
 360}
 361
 362static inline void gen_goto_tb(DisasContext *s, int tb_num,
 363                               target_ulong pc, target_ulong npc)
 364{
 365    if (use_goto_tb(s, pc, npc))  {
 366        /* jump to same page: we can use a direct jump */
 367        tcg_gen_goto_tb(tb_num);
 368        tcg_gen_movi_tl(cpu_pc, pc);
 369        tcg_gen_movi_tl(cpu_npc, npc);
 370        tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
 371    } else {
 372        /* jump to another page: currently not optimized */
 373        tcg_gen_movi_tl(cpu_pc, pc);
 374        tcg_gen_movi_tl(cpu_npc, npc);
 375        tcg_gen_exit_tb(0);
 376    }
 377}
 378
 379// XXX suboptimal
 380static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src)
 381{
 382    tcg_gen_extu_i32_tl(reg, src);
 383    tcg_gen_extract_tl(reg, reg, PSR_NEG_SHIFT, 1);
 384}
 385
 386static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
 387{
 388    tcg_gen_extu_i32_tl(reg, src);
 389    tcg_gen_extract_tl(reg, reg, PSR_ZERO_SHIFT, 1);
 390}
 391
 392static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
 393{
 394    tcg_gen_extu_i32_tl(reg, src);
 395    tcg_gen_extract_tl(reg, reg, PSR_OVF_SHIFT, 1);
 396}
 397
 398static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
 399{
 400    tcg_gen_extu_i32_tl(reg, src);
 401    tcg_gen_extract_tl(reg, reg, PSR_CARRY_SHIFT, 1);
 402}
 403
 404static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
 405{
 406    tcg_gen_mov_tl(cpu_cc_src, src1);
 407    tcg_gen_mov_tl(cpu_cc_src2, src2);
 408    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 409    tcg_gen_mov_tl(dst, cpu_cc_dst);
 410}
 411
 412static TCGv_i32 gen_add32_carry32(void)
 413{
 414    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
 415
 416    /* Carry is computed from a previous add: (dst < src)  */
 417#if TARGET_LONG_BITS == 64
 418    cc_src1_32 = tcg_temp_new_i32();
 419    cc_src2_32 = tcg_temp_new_i32();
 420    tcg_gen_extrl_i64_i32(cc_src1_32, cpu_cc_dst);
 421    tcg_gen_extrl_i64_i32(cc_src2_32, cpu_cc_src);
 422#else
 423    cc_src1_32 = cpu_cc_dst;
 424    cc_src2_32 = cpu_cc_src;
 425#endif
 426
 427    carry_32 = tcg_temp_new_i32();
 428    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
 429
 430#if TARGET_LONG_BITS == 64
 431    tcg_temp_free_i32(cc_src1_32);
 432    tcg_temp_free_i32(cc_src2_32);
 433#endif
 434
 435    return carry_32;
 436}
 437
 438static TCGv_i32 gen_sub32_carry32(void)
 439{
 440    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
 441
 442    /* Carry is computed from a previous borrow: (src1 < src2)  */
 443#if TARGET_LONG_BITS == 64
 444    cc_src1_32 = tcg_temp_new_i32();
 445    cc_src2_32 = tcg_temp_new_i32();
 446    tcg_gen_extrl_i64_i32(cc_src1_32, cpu_cc_src);
 447    tcg_gen_extrl_i64_i32(cc_src2_32, cpu_cc_src2);
 448#else
 449    cc_src1_32 = cpu_cc_src;
 450    cc_src2_32 = cpu_cc_src2;
 451#endif
 452
 453    carry_32 = tcg_temp_new_i32();
 454    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
 455
 456#if TARGET_LONG_BITS == 64
 457    tcg_temp_free_i32(cc_src1_32);
 458    tcg_temp_free_i32(cc_src2_32);
 459#endif
 460
 461    return carry_32;
 462}
 463
 464static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
 465                            TCGv src2, int update_cc)
 466{
 467    TCGv_i32 carry_32;
 468    TCGv carry;
 469
 470    switch (dc->cc_op) {
 471    case CC_OP_DIV:
 472    case CC_OP_LOGIC:
 473        /* Carry is known to be zero.  Fall back to plain ADD.  */
 474        if (update_cc) {
 475            gen_op_add_cc(dst, src1, src2);
 476        } else {
 477            tcg_gen_add_tl(dst, src1, src2);
 478        }
 479        return;
 480
 481    case CC_OP_ADD:
 482    case CC_OP_TADD:
 483    case CC_OP_TADDTV:
 484        if (TARGET_LONG_BITS == 32) {
 485            /* We can re-use the host's hardware carry generation by using
 486               an ADD2 opcode.  We discard the low part of the output.
 487               Ideally we'd combine this operation with the add that
 488               generated the carry in the first place.  */
 489            carry = tcg_temp_new();
 490            tcg_gen_add2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
 491            tcg_temp_free(carry);
 492            goto add_done;
 493        }
 494        carry_32 = gen_add32_carry32();
 495        break;
 496
 497    case CC_OP_SUB:
 498    case CC_OP_TSUB:
 499    case CC_OP_TSUBTV:
 500        carry_32 = gen_sub32_carry32();
 501        break;
 502
 503    default:
 504        /* We need external help to produce the carry.  */
 505        carry_32 = tcg_temp_new_i32();
 506        gen_helper_compute_C_icc(carry_32, cpu_env);
 507        break;
 508    }
 509
 510#if TARGET_LONG_BITS == 64
 511    carry = tcg_temp_new();
 512    tcg_gen_extu_i32_i64(carry, carry_32);
 513#else
 514    carry = carry_32;
 515#endif
 516
 517    tcg_gen_add_tl(dst, src1, src2);
 518    tcg_gen_add_tl(dst, dst, carry);
 519
 520    tcg_temp_free_i32(carry_32);
 521#if TARGET_LONG_BITS == 64
 522    tcg_temp_free(carry);
 523#endif
 524
 525 add_done:
 526    if (update_cc) {
 527        tcg_gen_mov_tl(cpu_cc_src, src1);
 528        tcg_gen_mov_tl(cpu_cc_src2, src2);
 529        tcg_gen_mov_tl(cpu_cc_dst, dst);
 530        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
 531        dc->cc_op = CC_OP_ADDX;
 532    }
 533}
 534
 535static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
 536{
 537    tcg_gen_mov_tl(cpu_cc_src, src1);
 538    tcg_gen_mov_tl(cpu_cc_src2, src2);
 539    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 540    tcg_gen_mov_tl(dst, cpu_cc_dst);
 541}
 542
 543static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
 544                            TCGv src2, int update_cc)
 545{
 546    TCGv_i32 carry_32;
 547    TCGv carry;
 548
 549    switch (dc->cc_op) {
 550    case CC_OP_DIV:
 551    case CC_OP_LOGIC:
 552        /* Carry is known to be zero.  Fall back to plain SUB.  */
 553        if (update_cc) {
 554            gen_op_sub_cc(dst, src1, src2);
 555        } else {
 556            tcg_gen_sub_tl(dst, src1, src2);
 557        }
 558        return;
 559
 560    case CC_OP_ADD:
 561    case CC_OP_TADD:
 562    case CC_OP_TADDTV:
 563        carry_32 = gen_add32_carry32();
 564        break;
 565
 566    case CC_OP_SUB:
 567    case CC_OP_TSUB:
 568    case CC_OP_TSUBTV:
 569        if (TARGET_LONG_BITS == 32) {
 570            /* We can re-use the host's hardware carry generation by using
 571               a SUB2 opcode.  We discard the low part of the output.
 572               Ideally we'd combine this operation with the add that
 573               generated the carry in the first place.  */
 574            carry = tcg_temp_new();
 575            tcg_gen_sub2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
 576            tcg_temp_free(carry);
 577            goto sub_done;
 578        }
 579        carry_32 = gen_sub32_carry32();
 580        break;
 581
 582    default:
 583        /* We need external help to produce the carry.  */
 584        carry_32 = tcg_temp_new_i32();
 585        gen_helper_compute_C_icc(carry_32, cpu_env);
 586        break;
 587    }
 588
 589#if TARGET_LONG_BITS == 64
 590    carry = tcg_temp_new();
 591    tcg_gen_extu_i32_i64(carry, carry_32);
 592#else
 593    carry = carry_32;
 594#endif
 595
 596    tcg_gen_sub_tl(dst, src1, src2);
 597    tcg_gen_sub_tl(dst, dst, carry);
 598
 599    tcg_temp_free_i32(carry_32);
 600#if TARGET_LONG_BITS == 64
 601    tcg_temp_free(carry);
 602#endif
 603
 604 sub_done:
 605    if (update_cc) {
 606        tcg_gen_mov_tl(cpu_cc_src, src1);
 607        tcg_gen_mov_tl(cpu_cc_src2, src2);
 608        tcg_gen_mov_tl(cpu_cc_dst, dst);
 609        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
 610        dc->cc_op = CC_OP_SUBX;
 611    }
 612}
 613
 614static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
 615{
 616    TCGv r_temp, zero, t0;
 617
 618    r_temp = tcg_temp_new();
 619    t0 = tcg_temp_new();
 620
 621    /* old op:
 622    if (!(env->y & 1))
 623        T1 = 0;
 624    */
 625    zero = tcg_const_tl(0);
 626    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
 627    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
 628    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
 629    tcg_gen_movcond_tl(TCG_COND_EQ, cpu_cc_src2, r_temp, zero,
 630                       zero, cpu_cc_src2);
 631    tcg_temp_free(zero);
 632
 633    // b2 = T0 & 1;
 634    // env->y = (b2 << 31) | (env->y >> 1);
 635    tcg_gen_extract_tl(t0, cpu_y, 1, 31);
 636    tcg_gen_deposit_tl(cpu_y, t0, cpu_cc_src, 31, 1);
 637
 638    // b1 = N ^ V;
 639    gen_mov_reg_N(t0, cpu_psr);
 640    gen_mov_reg_V(r_temp, cpu_psr);
 641    tcg_gen_xor_tl(t0, t0, r_temp);
 642    tcg_temp_free(r_temp);
 643
 644    // T0 = (b1 << 31) | (T0 >> 1);
 645    // src1 = T0;
 646    tcg_gen_shli_tl(t0, t0, 31);
 647    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
 648    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
 649    tcg_temp_free(t0);
 650
 651    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 652
 653    tcg_gen_mov_tl(dst, cpu_cc_dst);
 654}
 655
 656static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
 657{
 658#if TARGET_LONG_BITS == 32
 659    if (sign_ext) {
 660        tcg_gen_muls2_tl(dst, cpu_y, src1, src2);
 661    } else {
 662        tcg_gen_mulu2_tl(dst, cpu_y, src1, src2);
 663    }
 664#else
 665    TCGv t0 = tcg_temp_new_i64();
 666    TCGv t1 = tcg_temp_new_i64();
 667
 668    if (sign_ext) {
 669        tcg_gen_ext32s_i64(t0, src1);
 670        tcg_gen_ext32s_i64(t1, src2);
 671    } else {
 672        tcg_gen_ext32u_i64(t0, src1);
 673        tcg_gen_ext32u_i64(t1, src2);
 674    }
 675
 676    tcg_gen_mul_i64(dst, t0, t1);
 677    tcg_temp_free(t0);
 678    tcg_temp_free(t1);
 679
 680    tcg_gen_shri_i64(cpu_y, dst, 32);
 681#endif
 682}
 683
 684static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
 685{
 686    /* zero-extend truncated operands before multiplication */
 687    gen_op_multiply(dst, src1, src2, 0);
 688}
 689
 690static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
 691{
 692    /* sign-extend truncated operands before multiplication */
 693    gen_op_multiply(dst, src1, src2, 1);
 694}
 695
 696// 1
 697static inline void gen_op_eval_ba(TCGv dst)
 698{
 699    tcg_gen_movi_tl(dst, 1);
 700}
 701
 702// Z
 703static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
 704{
 705    gen_mov_reg_Z(dst, src);
 706}
 707
 708// Z | (N ^ V)
 709static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
 710{
 711    TCGv t0 = tcg_temp_new();
 712    gen_mov_reg_N(t0, src);
 713    gen_mov_reg_V(dst, src);
 714    tcg_gen_xor_tl(dst, dst, t0);
 715    gen_mov_reg_Z(t0, src);
 716    tcg_gen_or_tl(dst, dst, t0);
 717    tcg_temp_free(t0);
 718}
 719
 720// N ^ V
 721static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
 722{
 723    TCGv t0 = tcg_temp_new();
 724    gen_mov_reg_V(t0, src);
 725    gen_mov_reg_N(dst, src);
 726    tcg_gen_xor_tl(dst, dst, t0);
 727    tcg_temp_free(t0);
 728}
 729
 730// C | Z
 731static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
 732{
 733    TCGv t0 = tcg_temp_new();
 734    gen_mov_reg_Z(t0, src);
 735    gen_mov_reg_C(dst, src);
 736    tcg_gen_or_tl(dst, dst, t0);
 737    tcg_temp_free(t0);
 738}
 739
 740// C
 741static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
 742{
 743    gen_mov_reg_C(dst, src);
 744}
 745
 746// V
 747static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
 748{
 749    gen_mov_reg_V(dst, src);
 750}
 751
 752// 0
 753static inline void gen_op_eval_bn(TCGv dst)
 754{
 755    tcg_gen_movi_tl(dst, 0);
 756}
 757
 758// N
 759static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
 760{
 761    gen_mov_reg_N(dst, src);
 762}
 763
 764// !Z
 765static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
 766{
 767    gen_mov_reg_Z(dst, src);
 768    tcg_gen_xori_tl(dst, dst, 0x1);
 769}
 770
 771// !(Z | (N ^ V))
 772static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
 773{
 774    gen_op_eval_ble(dst, src);
 775    tcg_gen_xori_tl(dst, dst, 0x1);
 776}
 777
 778// !(N ^ V)
 779static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
 780{
 781    gen_op_eval_bl(dst, src);
 782    tcg_gen_xori_tl(dst, dst, 0x1);
 783}
 784
 785// !(C | Z)
 786static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
 787{
 788    gen_op_eval_bleu(dst, src);
 789    tcg_gen_xori_tl(dst, dst, 0x1);
 790}
 791
 792// !C
 793static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
 794{
 795    gen_mov_reg_C(dst, src);
 796    tcg_gen_xori_tl(dst, dst, 0x1);
 797}
 798
 799// !N
 800static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
 801{
 802    gen_mov_reg_N(dst, src);
 803    tcg_gen_xori_tl(dst, dst, 0x1);
 804}
 805
 806// !V
 807static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
 808{
 809    gen_mov_reg_V(dst, src);
 810    tcg_gen_xori_tl(dst, dst, 0x1);
 811}
 812
 813/*
 814  FPSR bit field FCC1 | FCC0:
 815   0 =
 816   1 <
 817   2 >
 818   3 unordered
 819*/
 820static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
 821                                    unsigned int fcc_offset)
 822{
 823    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
 824    tcg_gen_andi_tl(reg, reg, 0x1);
 825}
 826
 827static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
 828                                    unsigned int fcc_offset)
 829{
 830    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
 831    tcg_gen_andi_tl(reg, reg, 0x1);
 832}
 833
 834// !0: FCC0 | FCC1
 835static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
 836                                    unsigned int fcc_offset)
 837{
 838    TCGv t0 = tcg_temp_new();
 839    gen_mov_reg_FCC0(dst, src, fcc_offset);
 840    gen_mov_reg_FCC1(t0, src, fcc_offset);
 841    tcg_gen_or_tl(dst, dst, t0);
 842    tcg_temp_free(t0);
 843}
 844
 845// 1 or 2: FCC0 ^ FCC1
 846static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
 847                                    unsigned int fcc_offset)
 848{
 849    TCGv t0 = tcg_temp_new();
 850    gen_mov_reg_FCC0(dst, src, fcc_offset);
 851    gen_mov_reg_FCC1(t0, src, fcc_offset);
 852    tcg_gen_xor_tl(dst, dst, t0);
 853    tcg_temp_free(t0);
 854}
 855
 856// 1 or 3: FCC0
 857static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
 858                                    unsigned int fcc_offset)
 859{
 860    gen_mov_reg_FCC0(dst, src, fcc_offset);
 861}
 862
 863// 1: FCC0 & !FCC1
 864static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
 865                                    unsigned int fcc_offset)
 866{
 867    TCGv t0 = tcg_temp_new();
 868    gen_mov_reg_FCC0(dst, src, fcc_offset);
 869    gen_mov_reg_FCC1(t0, src, fcc_offset);
 870    tcg_gen_andc_tl(dst, dst, t0);
 871    tcg_temp_free(t0);
 872}
 873
 874// 2 or 3: FCC1
 875static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
 876                                    unsigned int fcc_offset)
 877{
 878    gen_mov_reg_FCC1(dst, src, fcc_offset);
 879}
 880
 881// 2: !FCC0 & FCC1
 882static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
 883                                    unsigned int fcc_offset)
 884{
 885    TCGv t0 = tcg_temp_new();
 886    gen_mov_reg_FCC0(dst, src, fcc_offset);
 887    gen_mov_reg_FCC1(t0, src, fcc_offset);
 888    tcg_gen_andc_tl(dst, t0, dst);
 889    tcg_temp_free(t0);
 890}
 891
 892// 3: FCC0 & FCC1
 893static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
 894                                    unsigned int fcc_offset)
 895{
 896    TCGv t0 = tcg_temp_new();
 897    gen_mov_reg_FCC0(dst, src, fcc_offset);
 898    gen_mov_reg_FCC1(t0, src, fcc_offset);
 899    tcg_gen_and_tl(dst, dst, t0);
 900    tcg_temp_free(t0);
 901}
 902
 903// 0: !(FCC0 | FCC1)
 904static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
 905                                    unsigned int fcc_offset)
 906{
 907    TCGv t0 = tcg_temp_new();
 908    gen_mov_reg_FCC0(dst, src, fcc_offset);
 909    gen_mov_reg_FCC1(t0, src, fcc_offset);
 910    tcg_gen_or_tl(dst, dst, t0);
 911    tcg_gen_xori_tl(dst, dst, 0x1);
 912    tcg_temp_free(t0);
 913}
 914
 915// 0 or 3: !(FCC0 ^ FCC1)
 916static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
 917                                    unsigned int fcc_offset)
 918{
 919    TCGv t0 = tcg_temp_new();
 920    gen_mov_reg_FCC0(dst, src, fcc_offset);
 921    gen_mov_reg_FCC1(t0, src, fcc_offset);
 922    tcg_gen_xor_tl(dst, dst, t0);
 923    tcg_gen_xori_tl(dst, dst, 0x1);
 924    tcg_temp_free(t0);
 925}
 926
 927// 0 or 2: !FCC0
 928static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
 929                                    unsigned int fcc_offset)
 930{
 931    gen_mov_reg_FCC0(dst, src, fcc_offset);
 932    tcg_gen_xori_tl(dst, dst, 0x1);
 933}
 934
 935// !1: !(FCC0 & !FCC1)
 936static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
 937                                    unsigned int fcc_offset)
 938{
 939    TCGv t0 = tcg_temp_new();
 940    gen_mov_reg_FCC0(dst, src, fcc_offset);
 941    gen_mov_reg_FCC1(t0, src, fcc_offset);
 942    tcg_gen_andc_tl(dst, dst, t0);
 943    tcg_gen_xori_tl(dst, dst, 0x1);
 944    tcg_temp_free(t0);
 945}
 946
 947// 0 or 1: !FCC1
 948static inline void gen_op_eval_fble(TCGv dst, TCGv src,
 949                                    unsigned int fcc_offset)
 950{
 951    gen_mov_reg_FCC1(dst, src, fcc_offset);
 952    tcg_gen_xori_tl(dst, dst, 0x1);
 953}
 954
 955// !2: !(!FCC0 & FCC1)
 956static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
 957                                    unsigned int fcc_offset)
 958{
 959    TCGv t0 = tcg_temp_new();
 960    gen_mov_reg_FCC0(dst, src, fcc_offset);
 961    gen_mov_reg_FCC1(t0, src, fcc_offset);
 962    tcg_gen_andc_tl(dst, t0, dst);
 963    tcg_gen_xori_tl(dst, dst, 0x1);
 964    tcg_temp_free(t0);
 965}
 966
 967// !3: !(FCC0 & FCC1)
 968static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
 969                                    unsigned int fcc_offset)
 970{
 971    TCGv t0 = tcg_temp_new();
 972    gen_mov_reg_FCC0(dst, src, fcc_offset);
 973    gen_mov_reg_FCC1(t0, src, fcc_offset);
 974    tcg_gen_and_tl(dst, dst, t0);
 975    tcg_gen_xori_tl(dst, dst, 0x1);
 976    tcg_temp_free(t0);
 977}
 978
 979static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
 980                               target_ulong pc2, TCGv r_cond)
 981{
 982    TCGLabel *l1 = gen_new_label();
 983
 984    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
 985
 986    gen_goto_tb(dc, 0, pc1, pc1 + 4);
 987
 988    gen_set_label(l1);
 989    gen_goto_tb(dc, 1, pc2, pc2 + 4);
 990}
 991
 992static void gen_branch_a(DisasContext *dc, target_ulong pc1)
 993{
 994    TCGLabel *l1 = gen_new_label();
 995    target_ulong npc = dc->npc;
 996
 997    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
 998
 999    gen_goto_tb(dc, 0, npc, pc1);
1000
1001    gen_set_label(l1);
1002    gen_goto_tb(dc, 1, npc + 4, npc + 8);
1003
1004    dc->is_br = 1;
1005}
1006
1007static void gen_branch_n(DisasContext *dc, target_ulong pc1)
1008{
1009    target_ulong npc = dc->npc;
1010
1011    if (likely(npc != DYNAMIC_PC)) {
1012        dc->pc = npc;
1013        dc->jump_pc[0] = pc1;
1014        dc->jump_pc[1] = npc + 4;
1015        dc->npc = JUMP_PC;
1016    } else {
1017        TCGv t, z;
1018
1019        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1020
1021        tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1022        t = tcg_const_tl(pc1);
1023        z = tcg_const_tl(0);
1024        tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, z, t, cpu_npc);
1025        tcg_temp_free(t);
1026        tcg_temp_free(z);
1027
1028        dc->pc = DYNAMIC_PC;
1029    }
1030}
1031
1032static inline void gen_generic_branch(DisasContext *dc)
1033{
1034    TCGv npc0 = tcg_const_tl(dc->jump_pc[0]);
1035    TCGv npc1 = tcg_const_tl(dc->jump_pc[1]);
1036    TCGv zero = tcg_const_tl(0);
1037
1038    tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, zero, npc0, npc1);
1039
1040    tcg_temp_free(npc0);
1041    tcg_temp_free(npc1);
1042    tcg_temp_free(zero);
1043}
1044
1045/* call this function before using the condition register as it may
1046   have been set for a jump */
1047static inline void flush_cond(DisasContext *dc)
1048{
1049    if (dc->npc == JUMP_PC) {
1050        gen_generic_branch(dc);
1051        dc->npc = DYNAMIC_PC;
1052    }
1053}
1054
1055static inline void save_npc(DisasContext *dc)
1056{
1057    if (dc->npc == JUMP_PC) {
1058        gen_generic_branch(dc);
1059        dc->npc = DYNAMIC_PC;
1060    } else if (dc->npc != DYNAMIC_PC) {
1061        tcg_gen_movi_tl(cpu_npc, dc->npc);
1062    }
1063}
1064
1065static inline void update_psr(DisasContext *dc)
1066{
1067    if (dc->cc_op != CC_OP_FLAGS) {
1068        dc->cc_op = CC_OP_FLAGS;
1069        gen_helper_compute_psr(cpu_env);
1070    }
1071}
1072
1073static inline void save_state(DisasContext *dc)
1074{
1075    tcg_gen_movi_tl(cpu_pc, dc->pc);
1076    save_npc(dc);
1077}
1078
1079static void gen_exception(DisasContext *dc, int which)
1080{
1081    TCGv_i32 t;
1082
1083    save_state(dc);
1084    t = tcg_const_i32(which);
1085    gen_helper_raise_exception(cpu_env, t);
1086    tcg_temp_free_i32(t);
1087    dc->is_br = 1;
1088}
1089
1090static void gen_check_align(TCGv addr, int mask)
1091{
1092    TCGv_i32 r_mask = tcg_const_i32(mask);
1093    gen_helper_check_align(cpu_env, addr, r_mask);
1094    tcg_temp_free_i32(r_mask);
1095}
1096
1097static inline void gen_mov_pc_npc(DisasContext *dc)
1098{
1099    if (dc->npc == JUMP_PC) {
1100        gen_generic_branch(dc);
1101        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1102        dc->pc = DYNAMIC_PC;
1103    } else if (dc->npc == DYNAMIC_PC) {
1104        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1105        dc->pc = DYNAMIC_PC;
1106    } else {
1107        dc->pc = dc->npc;
1108    }
1109}
1110
1111static inline void gen_op_next_insn(void)
1112{
1113    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1114    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1115}
1116
1117static void free_compare(DisasCompare *cmp)
1118{
1119    if (!cmp->g1) {
1120        tcg_temp_free(cmp->c1);
1121    }
1122    if (!cmp->g2) {
1123        tcg_temp_free(cmp->c2);
1124    }
1125}
1126
1127static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
1128                        DisasContext *dc)
1129{
1130    static int subcc_cond[16] = {
1131        TCG_COND_NEVER,
1132        TCG_COND_EQ,
1133        TCG_COND_LE,
1134        TCG_COND_LT,
1135        TCG_COND_LEU,
1136        TCG_COND_LTU,
1137        -1, /* neg */
1138        -1, /* overflow */
1139        TCG_COND_ALWAYS,
1140        TCG_COND_NE,
1141        TCG_COND_GT,
1142        TCG_COND_GE,
1143        TCG_COND_GTU,
1144        TCG_COND_GEU,
1145        -1, /* pos */
1146        -1, /* no overflow */
1147    };
1148
1149    static int logic_cond[16] = {
1150        TCG_COND_NEVER,
1151        TCG_COND_EQ,     /* eq:  Z */
1152        TCG_COND_LE,     /* le:  Z | (N ^ V) -> Z | N */
1153        TCG_COND_LT,     /* lt:  N ^ V -> N */
1154        TCG_COND_EQ,     /* leu: C | Z -> Z */
1155        TCG_COND_NEVER,  /* ltu: C -> 0 */
1156        TCG_COND_LT,     /* neg: N */
1157        TCG_COND_NEVER,  /* vs:  V -> 0 */
1158        TCG_COND_ALWAYS,
1159        TCG_COND_NE,     /* ne:  !Z */
1160        TCG_COND_GT,     /* gt:  !(Z | (N ^ V)) -> !(Z | N) */
1161        TCG_COND_GE,     /* ge:  !(N ^ V) -> !N */
1162        TCG_COND_NE,     /* gtu: !(C | Z) -> !Z */
1163        TCG_COND_ALWAYS, /* geu: !C -> 1 */
1164        TCG_COND_GE,     /* pos: !N */
1165        TCG_COND_ALWAYS, /* vc:  !V -> 1 */
1166    };
1167
1168    TCGv_i32 r_src;
1169    TCGv r_dst;
1170
1171#ifdef TARGET_SPARC64
1172    if (xcc) {
1173        r_src = cpu_xcc;
1174    } else {
1175        r_src = cpu_psr;
1176    }
1177#else
1178    r_src = cpu_psr;
1179#endif
1180
1181    switch (dc->cc_op) {
1182    case CC_OP_LOGIC:
1183        cmp->cond = logic_cond[cond];
1184    do_compare_dst_0:
1185        cmp->is_bool = false;
1186        cmp->g2 = false;
1187        cmp->c2 = tcg_const_tl(0);
1188#ifdef TARGET_SPARC64
1189        if (!xcc) {
1190            cmp->g1 = false;
1191            cmp->c1 = tcg_temp_new();
1192            tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
1193            break;
1194        }
1195#endif
1196        cmp->g1 = true;
1197        cmp->c1 = cpu_cc_dst;
1198        break;
1199
1200    case CC_OP_SUB:
1201        switch (cond) {
1202        case 6:  /* neg */
1203        case 14: /* pos */
1204            cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
1205            goto do_compare_dst_0;
1206
1207        case 7: /* overflow */
1208        case 15: /* !overflow */
1209            goto do_dynamic;
1210
1211        default:
1212            cmp->cond = subcc_cond[cond];
1213            cmp->is_bool = false;
1214#ifdef TARGET_SPARC64
1215            if (!xcc) {
1216                /* Note that sign-extension works for unsigned compares as
1217                   long as both operands are sign-extended.  */
1218                cmp->g1 = cmp->g2 = false;
1219                cmp->c1 = tcg_temp_new();
1220                cmp->c2 = tcg_temp_new();
1221                tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
1222                tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
1223                break;
1224            }
1225#endif
1226            cmp->g1 = cmp->g2 = true;
1227            cmp->c1 = cpu_cc_src;
1228            cmp->c2 = cpu_cc_src2;
1229            break;
1230        }
1231        break;
1232
1233    default:
1234    do_dynamic:
1235        gen_helper_compute_psr(cpu_env);
1236        dc->cc_op = CC_OP_FLAGS;
1237        /* FALLTHRU */
1238
1239    case CC_OP_FLAGS:
1240        /* We're going to generate a boolean result.  */
1241        cmp->cond = TCG_COND_NE;
1242        cmp->is_bool = true;
1243        cmp->g1 = cmp->g2 = false;
1244        cmp->c1 = r_dst = tcg_temp_new();
1245        cmp->c2 = tcg_const_tl(0);
1246
1247        switch (cond) {
1248        case 0x0:
1249            gen_op_eval_bn(r_dst);
1250            break;
1251        case 0x1:
1252            gen_op_eval_be(r_dst, r_src);
1253            break;
1254        case 0x2:
1255            gen_op_eval_ble(r_dst, r_src);
1256            break;
1257        case 0x3:
1258            gen_op_eval_bl(r_dst, r_src);
1259            break;
1260        case 0x4:
1261            gen_op_eval_bleu(r_dst, r_src);
1262            break;
1263        case 0x5:
1264            gen_op_eval_bcs(r_dst, r_src);
1265            break;
1266        case 0x6:
1267            gen_op_eval_bneg(r_dst, r_src);
1268            break;
1269        case 0x7:
1270            gen_op_eval_bvs(r_dst, r_src);
1271            break;
1272        case 0x8:
1273            gen_op_eval_ba(r_dst);
1274            break;
1275        case 0x9:
1276            gen_op_eval_bne(r_dst, r_src);
1277            break;
1278        case 0xa:
1279            gen_op_eval_bg(r_dst, r_src);
1280            break;
1281        case 0xb:
1282            gen_op_eval_bge(r_dst, r_src);
1283            break;
1284        case 0xc:
1285            gen_op_eval_bgu(r_dst, r_src);
1286            break;
1287        case 0xd:
1288            gen_op_eval_bcc(r_dst, r_src);
1289            break;
1290        case 0xe:
1291            gen_op_eval_bpos(r_dst, r_src);
1292            break;
1293        case 0xf:
1294            gen_op_eval_bvc(r_dst, r_src);
1295            break;
1296        }
1297        break;
1298    }
1299}
1300
1301static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
1302{
1303    unsigned int offset;
1304    TCGv r_dst;
1305
1306    /* For now we still generate a straight boolean result.  */
1307    cmp->cond = TCG_COND_NE;
1308    cmp->is_bool = true;
1309    cmp->g1 = cmp->g2 = false;
1310    cmp->c1 = r_dst = tcg_temp_new();
1311    cmp->c2 = tcg_const_tl(0);
1312
1313    switch (cc) {
1314    default:
1315    case 0x0:
1316        offset = 0;
1317        break;
1318    case 0x1:
1319        offset = 32 - 10;
1320        break;
1321    case 0x2:
1322        offset = 34 - 10;
1323        break;
1324    case 0x3:
1325        offset = 36 - 10;
1326        break;
1327    }
1328
1329    switch (cond) {
1330    case 0x0:
1331        gen_op_eval_bn(r_dst);
1332        break;
1333    case 0x1:
1334        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1335        break;
1336    case 0x2:
1337        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1338        break;
1339    case 0x3:
1340        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1341        break;
1342    case 0x4:
1343        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1344        break;
1345    case 0x5:
1346        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1347        break;
1348    case 0x6:
1349        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1350        break;
1351    case 0x7:
1352        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1353        break;
1354    case 0x8:
1355        gen_op_eval_ba(r_dst);
1356        break;
1357    case 0x9:
1358        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1359        break;
1360    case 0xa:
1361        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1362        break;
1363    case 0xb:
1364        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1365        break;
1366    case 0xc:
1367        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1368        break;
1369    case 0xd:
1370        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1371        break;
1372    case 0xe:
1373        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1374        break;
1375    case 0xf:
1376        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1377        break;
1378    }
1379}
1380
1381static void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
1382                     DisasContext *dc)
1383{
1384    DisasCompare cmp;
1385    gen_compare(&cmp, cc, cond, dc);
1386
1387    /* The interface is to return a boolean in r_dst.  */
1388    if (cmp.is_bool) {
1389        tcg_gen_mov_tl(r_dst, cmp.c1);
1390    } else {
1391        tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
1392    }
1393
1394    free_compare(&cmp);
1395}
1396
1397static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1398{
1399    DisasCompare cmp;
1400    gen_fcompare(&cmp, cc, cond);
1401
1402    /* The interface is to return a boolean in r_dst.  */
1403    if (cmp.is_bool) {
1404        tcg_gen_mov_tl(r_dst, cmp.c1);
1405    } else {
1406        tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
1407    }
1408
1409    free_compare(&cmp);
1410}
1411
1412#ifdef TARGET_SPARC64
1413// Inverted logic
1414static const int gen_tcg_cond_reg[8] = {
1415    -1,
1416    TCG_COND_NE,
1417    TCG_COND_GT,
1418    TCG_COND_GE,
1419    -1,
1420    TCG_COND_EQ,
1421    TCG_COND_LE,
1422    TCG_COND_LT,
1423};
1424
1425static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
1426{
1427    cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
1428    cmp->is_bool = false;
1429    cmp->g1 = true;
1430    cmp->g2 = false;
1431    cmp->c1 = r_src;
1432    cmp->c2 = tcg_const_tl(0);
1433}
1434
1435static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1436{
1437    DisasCompare cmp;
1438    gen_compare_reg(&cmp, cond, r_src);
1439
1440    /* The interface is to return a boolean in r_dst.  */
1441    tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
1442
1443    free_compare(&cmp);
1444}
1445#endif
1446
1447static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
1448{
1449    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1450    target_ulong target = dc->pc + offset;
1451
1452#ifdef TARGET_SPARC64
1453    if (unlikely(AM_CHECK(dc))) {
1454        target &= 0xffffffffULL;
1455    }
1456#endif
1457    if (cond == 0x0) {
1458        /* unconditional not taken */
1459        if (a) {
1460            dc->pc = dc->npc + 4;
1461            dc->npc = dc->pc + 4;
1462        } else {
1463            dc->pc = dc->npc;
1464            dc->npc = dc->pc + 4;
1465        }
1466    } else if (cond == 0x8) {
1467        /* unconditional taken */
1468        if (a) {
1469            dc->pc = target;
1470            dc->npc = dc->pc + 4;
1471        } else {
1472            dc->pc = dc->npc;
1473            dc->npc = target;
1474            tcg_gen_mov_tl(cpu_pc, cpu_npc);
1475        }
1476    } else {
1477        flush_cond(dc);
1478        gen_cond(cpu_cond, cc, cond, dc);
1479        if (a) {
1480            gen_branch_a(dc, target);
1481        } else {
1482            gen_branch_n(dc, target);
1483        }
1484    }
1485}
1486
1487static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
1488{
1489    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1490    target_ulong target = dc->pc + offset;
1491
1492#ifdef TARGET_SPARC64
1493    if (unlikely(AM_CHECK(dc))) {
1494        target &= 0xffffffffULL;
1495    }
1496#endif
1497    if (cond == 0x0) {
1498        /* unconditional not taken */
1499        if (a) {
1500            dc->pc = dc->npc + 4;
1501            dc->npc = dc->pc + 4;
1502        } else {
1503            dc->pc = dc->npc;
1504            dc->npc = dc->pc + 4;
1505        }
1506    } else if (cond == 0x8) {
1507        /* unconditional taken */
1508        if (a) {
1509            dc->pc = target;
1510            dc->npc = dc->pc + 4;
1511        } else {
1512            dc->pc = dc->npc;
1513            dc->npc = target;
1514            tcg_gen_mov_tl(cpu_pc, cpu_npc);
1515        }
1516    } else {
1517        flush_cond(dc);
1518        gen_fcond(cpu_cond, cc, cond);
1519        if (a) {
1520            gen_branch_a(dc, target);
1521        } else {
1522            gen_branch_n(dc, target);
1523        }
1524    }
1525}
1526
1527#ifdef TARGET_SPARC64
1528static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1529                          TCGv r_reg)
1530{
1531    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1532    target_ulong target = dc->pc + offset;
1533
1534    if (unlikely(AM_CHECK(dc))) {
1535        target &= 0xffffffffULL;
1536    }
1537    flush_cond(dc);
1538    gen_cond_reg(cpu_cond, cond, r_reg);
1539    if (a) {
1540        gen_branch_a(dc, target);
1541    } else {
1542        gen_branch_n(dc, target);
1543    }
1544}
1545
1546static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1547{
1548    switch (fccno) {
1549    case 0:
1550        gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
1551        break;
1552    case 1:
1553        gen_helper_fcmps_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1554        break;
1555    case 2:
1556        gen_helper_fcmps_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1557        break;
1558    case 3:
1559        gen_helper_fcmps_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1560        break;
1561    }
1562}
1563
1564static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1565{
1566    switch (fccno) {
1567    case 0:
1568        gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
1569        break;
1570    case 1:
1571        gen_helper_fcmpd_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1572        break;
1573    case 2:
1574        gen_helper_fcmpd_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1575        break;
1576    case 3:
1577        gen_helper_fcmpd_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1578        break;
1579    }
1580}
1581
1582static inline void gen_op_fcmpq(int fccno)
1583{
1584    switch (fccno) {
1585    case 0:
1586        gen_helper_fcmpq(cpu_fsr, cpu_env);
1587        break;
1588    case 1:
1589        gen_helper_fcmpq_fcc1(cpu_fsr, cpu_env);
1590        break;
1591    case 2:
1592        gen_helper_fcmpq_fcc2(cpu_fsr, cpu_env);
1593        break;
1594    case 3:
1595        gen_helper_fcmpq_fcc3(cpu_fsr, cpu_env);
1596        break;
1597    }
1598}
1599
1600static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1601{
1602    switch (fccno) {
1603    case 0:
1604        gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
1605        break;
1606    case 1:
1607        gen_helper_fcmpes_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1608        break;
1609    case 2:
1610        gen_helper_fcmpes_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1611        break;
1612    case 3:
1613        gen_helper_fcmpes_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1614        break;
1615    }
1616}
1617
1618static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1619{
1620    switch (fccno) {
1621    case 0:
1622        gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
1623        break;
1624    case 1:
1625        gen_helper_fcmped_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1626        break;
1627    case 2:
1628        gen_helper_fcmped_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1629        break;
1630    case 3:
1631        gen_helper_fcmped_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1632        break;
1633    }
1634}
1635
1636static inline void gen_op_fcmpeq(int fccno)
1637{
1638    switch (fccno) {
1639    case 0:
1640        gen_helper_fcmpeq(cpu_fsr, cpu_env);
1641        break;
1642    case 1:
1643        gen_helper_fcmpeq_fcc1(cpu_fsr, cpu_env);
1644        break;
1645    case 2:
1646        gen_helper_fcmpeq_fcc2(cpu_fsr, cpu_env);
1647        break;
1648    case 3:
1649        gen_helper_fcmpeq_fcc3(cpu_fsr, cpu_env);
1650        break;
1651    }
1652}
1653
1654#else
1655
1656static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1657{
1658    gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
1659}
1660
1661static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1662{
1663    gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
1664}
1665
1666static inline void gen_op_fcmpq(int fccno)
1667{
1668    gen_helper_fcmpq(cpu_fsr, cpu_env);
1669}
1670
1671static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1672{
1673    gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
1674}
1675
1676static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1677{
1678    gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
1679}
1680
1681static inline void gen_op_fcmpeq(int fccno)
1682{
1683    gen_helper_fcmpeq(cpu_fsr, cpu_env);
1684}
1685#endif
1686
1687static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
1688{
1689    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1690    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1691    gen_exception(dc, TT_FP_EXCP);
1692}
1693
1694static int gen_trap_ifnofpu(DisasContext *dc)
1695{
1696#if !defined(CONFIG_USER_ONLY)
1697    if (!dc->fpu_enabled) {
1698        gen_exception(dc, TT_NFPU_INSN);
1699        return 1;
1700    }
1701#endif
1702    return 0;
1703}
1704
1705static inline void gen_op_clear_ieee_excp_and_FTT(void)
1706{
1707    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1708}
1709
1710static inline void gen_fop_FF(DisasContext *dc, int rd, int rs,
1711                              void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32))
1712{
1713    TCGv_i32 dst, src;
1714
1715    src = gen_load_fpr_F(dc, rs);
1716    dst = gen_dest_fpr_F(dc);
1717
1718    gen(dst, cpu_env, src);
1719    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1720
1721    gen_store_fpr_F(dc, rd, dst);
1722}
1723
1724static inline void gen_ne_fop_FF(DisasContext *dc, int rd, int rs,
1725                                 void (*gen)(TCGv_i32, TCGv_i32))
1726{
1727    TCGv_i32 dst, src;
1728
1729    src = gen_load_fpr_F(dc, rs);
1730    dst = gen_dest_fpr_F(dc);
1731
1732    gen(dst, src);
1733
1734    gen_store_fpr_F(dc, rd, dst);
1735}
1736
1737static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
1738                        void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32))
1739{
1740    TCGv_i32 dst, src1, src2;
1741
1742    src1 = gen_load_fpr_F(dc, rs1);
1743    src2 = gen_load_fpr_F(dc, rs2);
1744    dst = gen_dest_fpr_F(dc);
1745
1746    gen(dst, cpu_env, src1, src2);
1747    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1748
1749    gen_store_fpr_F(dc, rd, dst);
1750}
1751
1752#ifdef TARGET_SPARC64
1753static inline void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
1754                                  void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
1755{
1756    TCGv_i32 dst, src1, src2;
1757
1758    src1 = gen_load_fpr_F(dc, rs1);
1759    src2 = gen_load_fpr_F(dc, rs2);
1760    dst = gen_dest_fpr_F(dc);
1761
1762    gen(dst, src1, src2);
1763
1764    gen_store_fpr_F(dc, rd, dst);
1765}
1766#endif
1767
1768static inline void gen_fop_DD(DisasContext *dc, int rd, int rs,
1769                              void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64))
1770{
1771    TCGv_i64 dst, src;
1772
1773    src = gen_load_fpr_D(dc, rs);
1774    dst = gen_dest_fpr_D(dc, rd);
1775
1776    gen(dst, cpu_env, src);
1777    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1778
1779    gen_store_fpr_D(dc, rd, dst);
1780}
1781
1782#ifdef TARGET_SPARC64
1783static inline void gen_ne_fop_DD(DisasContext *dc, int rd, int rs,
1784                                 void (*gen)(TCGv_i64, TCGv_i64))
1785{
1786    TCGv_i64 dst, src;
1787
1788    src = gen_load_fpr_D(dc, rs);
1789    dst = gen_dest_fpr_D(dc, rd);
1790
1791    gen(dst, src);
1792
1793    gen_store_fpr_D(dc, rd, dst);
1794}
1795#endif
1796
1797static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
1798                        void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
1799{
1800    TCGv_i64 dst, src1, src2;
1801
1802    src1 = gen_load_fpr_D(dc, rs1);
1803    src2 = gen_load_fpr_D(dc, rs2);
1804    dst = gen_dest_fpr_D(dc, rd);
1805
1806    gen(dst, cpu_env, src1, src2);
1807    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1808
1809    gen_store_fpr_D(dc, rd, dst);
1810}
1811
1812#ifdef TARGET_SPARC64
1813static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
1814                                  void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
1815{
1816    TCGv_i64 dst, src1, src2;
1817
1818    src1 = gen_load_fpr_D(dc, rs1);
1819    src2 = gen_load_fpr_D(dc, rs2);
1820    dst = gen_dest_fpr_D(dc, rd);
1821
1822    gen(dst, src1, src2);
1823
1824    gen_store_fpr_D(dc, rd, dst);
1825}
1826
1827static inline void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
1828                           void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
1829{
1830    TCGv_i64 dst, src1, src2;
1831
1832    src1 = gen_load_fpr_D(dc, rs1);
1833    src2 = gen_load_fpr_D(dc, rs2);
1834    dst = gen_dest_fpr_D(dc, rd);
1835
1836    gen(dst, cpu_gsr, src1, src2);
1837
1838    gen_store_fpr_D(dc, rd, dst);
1839}
1840
1841static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2,
1842                           void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
1843{
1844    TCGv_i64 dst, src0, src1, src2;
1845
1846    src1 = gen_load_fpr_D(dc, rs1);
1847    src2 = gen_load_fpr_D(dc, rs2);
1848    src0 = gen_load_fpr_D(dc, rd);
1849    dst = gen_dest_fpr_D(dc, rd);
1850
1851    gen(dst, src0, src1, src2);
1852
1853    gen_store_fpr_D(dc, rd, dst);
1854}
1855#endif
1856
1857static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs,
1858                              void (*gen)(TCGv_ptr))
1859{
1860    gen_op_load_fpr_QT1(QFPREG(rs));
1861
1862    gen(cpu_env);
1863    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1864
1865    gen_op_store_QT0_fpr(QFPREG(rd));
1866    gen_update_fprs_dirty(dc, QFPREG(rd));
1867}
1868
1869#ifdef TARGET_SPARC64
1870static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
1871                                 void (*gen)(TCGv_ptr))
1872{
1873    gen_op_load_fpr_QT1(QFPREG(rs));
1874
1875    gen(cpu_env);
1876
1877    gen_op_store_QT0_fpr(QFPREG(rd));
1878    gen_update_fprs_dirty(dc, QFPREG(rd));
1879}
1880#endif
1881
1882static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2,
1883                               void (*gen)(TCGv_ptr))
1884{
1885    gen_op_load_fpr_QT0(QFPREG(rs1));
1886    gen_op_load_fpr_QT1(QFPREG(rs2));
1887
1888    gen(cpu_env);
1889    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1890
1891    gen_op_store_QT0_fpr(QFPREG(rd));
1892    gen_update_fprs_dirty(dc, QFPREG(rd));
1893}
1894
1895static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
1896                        void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32))
1897{
1898    TCGv_i64 dst;
1899    TCGv_i32 src1, src2;
1900
1901    src1 = gen_load_fpr_F(dc, rs1);
1902    src2 = gen_load_fpr_F(dc, rs2);
1903    dst = gen_dest_fpr_D(dc, rd);
1904
1905    gen(dst, cpu_env, src1, src2);
1906    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1907
1908    gen_store_fpr_D(dc, rd, dst);
1909}
1910
1911static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2,
1912                               void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64))
1913{
1914    TCGv_i64 src1, src2;
1915
1916    src1 = gen_load_fpr_D(dc, rs1);
1917    src2 = gen_load_fpr_D(dc, rs2);
1918
1919    gen(cpu_env, src1, src2);
1920    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1921
1922    gen_op_store_QT0_fpr(QFPREG(rd));
1923    gen_update_fprs_dirty(dc, QFPREG(rd));
1924}
1925
1926#ifdef TARGET_SPARC64
1927static inline void gen_fop_DF(DisasContext *dc, int rd, int rs,
1928                              void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
1929{
1930    TCGv_i64 dst;
1931    TCGv_i32 src;
1932
1933    src = gen_load_fpr_F(dc, rs);
1934    dst = gen_dest_fpr_D(dc, rd);
1935
1936    gen(dst, cpu_env, src);
1937    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1938
1939    gen_store_fpr_D(dc, rd, dst);
1940}
1941#endif
1942
1943static inline void gen_ne_fop_DF(DisasContext *dc, int rd, int rs,
1944                                 void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
1945{
1946    TCGv_i64 dst;
1947    TCGv_i32 src;
1948
1949    src = gen_load_fpr_F(dc, rs);
1950    dst = gen_dest_fpr_D(dc, rd);
1951
1952    gen(dst, cpu_env, src);
1953
1954    gen_store_fpr_D(dc, rd, dst);
1955}
1956
1957static inline void gen_fop_FD(DisasContext *dc, int rd, int rs,
1958                              void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64))
1959{
1960    TCGv_i32 dst;
1961    TCGv_i64 src;
1962
1963    src = gen_load_fpr_D(dc, rs);
1964    dst = gen_dest_fpr_F(dc);
1965
1966    gen(dst, cpu_env, src);
1967    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1968
1969    gen_store_fpr_F(dc, rd, dst);
1970}
1971
1972static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs,
1973                              void (*gen)(TCGv_i32, TCGv_ptr))
1974{
1975    TCGv_i32 dst;
1976
1977    gen_op_load_fpr_QT1(QFPREG(rs));
1978    dst = gen_dest_fpr_F(dc);
1979
1980    gen(dst, cpu_env);
1981    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1982
1983    gen_store_fpr_F(dc, rd, dst);
1984}
1985
1986static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs,
1987                              void (*gen)(TCGv_i64, TCGv_ptr))
1988{
1989    TCGv_i64 dst;
1990
1991    gen_op_load_fpr_QT1(QFPREG(rs));
1992    dst = gen_dest_fpr_D(dc, rd);
1993
1994    gen(dst, cpu_env);
1995    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1996
1997    gen_store_fpr_D(dc, rd, dst);
1998}
1999
2000static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs,
2001                                 void (*gen)(TCGv_ptr, TCGv_i32))
2002{
2003    TCGv_i32 src;
2004
2005    src = gen_load_fpr_F(dc, rs);
2006
2007    gen(cpu_env, src);
2008
2009    gen_op_store_QT0_fpr(QFPREG(rd));
2010    gen_update_fprs_dirty(dc, QFPREG(rd));
2011}
2012
2013static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
2014                                 void (*gen)(TCGv_ptr, TCGv_i64))
2015{
2016    TCGv_i64 src;
2017
2018    src = gen_load_fpr_D(dc, rs);
2019
2020    gen(cpu_env, src);
2021
2022    gen_op_store_QT0_fpr(QFPREG(rd));
2023    gen_update_fprs_dirty(dc, QFPREG(rd));
2024}
2025
2026static void gen_swap(DisasContext *dc, TCGv dst, TCGv src,
2027                     TCGv addr, int mmu_idx, TCGMemOp memop)
2028{
2029    gen_address_mask(dc, addr);
2030    tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop);
2031}
2032
2033static void gen_ldstub(DisasContext *dc, TCGv dst, TCGv addr, int mmu_idx)
2034{
2035    TCGv m1 = tcg_const_tl(0xff);
2036    gen_address_mask(dc, addr);
2037    tcg_gen_atomic_xchg_tl(dst, addr, m1, mmu_idx, MO_UB);
2038    tcg_temp_free(m1);
2039}
2040
2041/* asi moves */
2042#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2043typedef enum {
2044    GET_ASI_HELPER,
2045    GET_ASI_EXCP,
2046    GET_ASI_DIRECT,
2047    GET_ASI_DTWINX,
2048    GET_ASI_BLOCK,
2049    GET_ASI_SHORT,
2050    GET_ASI_BCOPY,
2051    GET_ASI_BFILL,
2052} ASIType;
2053
2054typedef struct {
2055    ASIType type;
2056    int asi;
2057    int mem_idx;
2058    TCGMemOp memop;
2059} DisasASI;
2060
2061static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
2062{
2063    int asi = GET_FIELD(insn, 19, 26);
2064    ASIType type = GET_ASI_HELPER;
2065    int mem_idx = dc->mem_idx;
2066
2067#ifndef TARGET_SPARC64
2068    /* Before v9, all asis are immediate and privileged.  */
2069    if (IS_IMM) {
2070        gen_exception(dc, TT_ILL_INSN);
2071        type = GET_ASI_EXCP;
2072    } else if (supervisor(dc)
2073               /* Note that LEON accepts ASI_USERDATA in user mode, for
2074                  use with CASA.  Also note that previous versions of
2075                  QEMU allowed (and old versions of gcc emitted) ASI_P
2076                  for LEON, which is incorrect.  */
2077               || (asi == ASI_USERDATA
2078                   && (dc->def->features & CPU_FEATURE_CASA))) {
2079        switch (asi) {
2080        case ASI_USERDATA:   /* User data access */
2081            mem_idx = MMU_USER_IDX;
2082            type = GET_ASI_DIRECT;
2083            break;
2084        case ASI_KERNELDATA: /* Supervisor data access */
2085            mem_idx = MMU_KERNEL_IDX;
2086            type = GET_ASI_DIRECT;
2087            break;
2088        case ASI_M_BYPASS:    /* MMU passthrough */
2089        case ASI_LEON_BYPASS: /* LEON MMU passthrough */
2090            mem_idx = MMU_PHYS_IDX;
2091            type = GET_ASI_DIRECT;
2092            break;
2093        case ASI_M_BCOPY: /* Block copy, sta access */
2094            mem_idx = MMU_KERNEL_IDX;
2095            type = GET_ASI_BCOPY;
2096            break;
2097        case ASI_M_BFILL: /* Block fill, stda access */
2098            mem_idx = MMU_KERNEL_IDX;
2099            type = GET_ASI_BFILL;
2100            break;
2101        }
2102    } else {
2103        gen_exception(dc, TT_PRIV_INSN);
2104        type = GET_ASI_EXCP;
2105    }
2106#else
2107    if (IS_IMM) {
2108        asi = dc->asi;
2109    }
2110    /* With v9, all asis below 0x80 are privileged.  */
2111    /* ??? We ought to check cpu_has_hypervisor, but we didn't copy
2112       down that bit into DisasContext.  For the moment that's ok,
2113       since the direct implementations below doesn't have any ASIs
2114       in the restricted [0x30, 0x7f] range, and the check will be
2115       done properly in the helper.  */
2116    if (!supervisor(dc) && asi < 0x80) {
2117        gen_exception(dc, TT_PRIV_ACT);
2118        type = GET_ASI_EXCP;
2119    } else {
2120        switch (asi) {
2121        case ASI_REAL:      /* Bypass */
2122        case ASI_REAL_IO:   /* Bypass, non-cacheable */
2123        case ASI_REAL_L:    /* Bypass LE */
2124        case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
2125        case ASI_TWINX_REAL:   /* Real address, twinx */
2126        case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
2127        case ASI_QUAD_LDD_PHYS:
2128        case ASI_QUAD_LDD_PHYS_L:
2129            mem_idx = MMU_PHYS_IDX;
2130            break;
2131        case ASI_N:  /* Nucleus */
2132        case ASI_NL: /* Nucleus LE */
2133        case ASI_TWINX_N:
2134        case ASI_TWINX_NL:
2135        case ASI_NUCLEUS_QUAD_LDD:
2136        case ASI_NUCLEUS_QUAD_LDD_L:
2137            if (hypervisor(dc)) {
2138                mem_idx = MMU_PHYS_IDX;
2139            } else {
2140                mem_idx = MMU_NUCLEUS_IDX;
2141            }
2142            break;
2143        case ASI_AIUP:  /* As if user primary */
2144        case ASI_AIUPL: /* As if user primary LE */
2145        case ASI_TWINX_AIUP:
2146        case ASI_TWINX_AIUP_L:
2147        case ASI_BLK_AIUP_4V:
2148        case ASI_BLK_AIUP_L_4V:
2149        case ASI_BLK_AIUP:
2150        case ASI_BLK_AIUPL:
2151            mem_idx = MMU_USER_IDX;
2152            break;
2153        case ASI_AIUS:  /* As if user secondary */
2154        case ASI_AIUSL: /* As if user secondary LE */
2155        case ASI_TWINX_AIUS:
2156        case ASI_TWINX_AIUS_L:
2157        case ASI_BLK_AIUS_4V:
2158        case ASI_BLK_AIUS_L_4V:
2159        case ASI_BLK_AIUS:
2160        case ASI_BLK_AIUSL:
2161            mem_idx = MMU_USER_SECONDARY_IDX;
2162            break;
2163        case ASI_S:  /* Secondary */
2164        case ASI_SL: /* Secondary LE */
2165        case ASI_TWINX_S:
2166        case ASI_TWINX_SL:
2167        case ASI_BLK_COMMIT_S:
2168        case ASI_BLK_S:
2169        case ASI_BLK_SL:
2170        case ASI_FL8_S:
2171        case ASI_FL8_SL:
2172        case ASI_FL16_S:
2173        case ASI_FL16_SL:
2174            if (mem_idx == MMU_USER_IDX) {
2175                mem_idx = MMU_USER_SECONDARY_IDX;
2176            } else if (mem_idx == MMU_KERNEL_IDX) {
2177                mem_idx = MMU_KERNEL_SECONDARY_IDX;
2178            }
2179            break;
2180        case ASI_P:  /* Primary */
2181        case ASI_PL: /* Primary LE */
2182        case ASI_TWINX_P:
2183        case ASI_TWINX_PL:
2184        case ASI_BLK_COMMIT_P:
2185        case ASI_BLK_P:
2186        case ASI_BLK_PL:
2187        case ASI_FL8_P:
2188        case ASI_FL8_PL:
2189        case ASI_FL16_P:
2190        case ASI_FL16_PL:
2191            break;
2192        }
2193        switch (asi) {
2194        case ASI_REAL:
2195        case ASI_REAL_IO:
2196        case ASI_REAL_L:
2197        case ASI_REAL_IO_L:
2198        case ASI_N:
2199        case ASI_NL:
2200        case ASI_AIUP:
2201        case ASI_AIUPL:
2202        case ASI_AIUS:
2203        case ASI_AIUSL:
2204        case ASI_S:
2205        case ASI_SL:
2206        case ASI_P:
2207        case ASI_PL:
2208            type = GET_ASI_DIRECT;
2209            break;
2210        case ASI_TWINX_REAL:
2211        case ASI_TWINX_REAL_L:
2212        case ASI_TWINX_N:
2213        case ASI_TWINX_NL:
2214        case ASI_TWINX_AIUP:
2215        case ASI_TWINX_AIUP_L:
2216        case ASI_TWINX_AIUS:
2217        case ASI_TWINX_AIUS_L:
2218        case ASI_TWINX_P:
2219        case ASI_TWINX_PL:
2220        case ASI_TWINX_S:
2221        case ASI_TWINX_SL:
2222        case ASI_QUAD_LDD_PHYS:
2223        case ASI_QUAD_LDD_PHYS_L:
2224        case ASI_NUCLEUS_QUAD_LDD:
2225        case ASI_NUCLEUS_QUAD_LDD_L:
2226            type = GET_ASI_DTWINX;
2227            break;
2228        case ASI_BLK_COMMIT_P:
2229        case ASI_BLK_COMMIT_S:
2230        case ASI_BLK_AIUP_4V:
2231        case ASI_BLK_AIUP_L_4V:
2232        case ASI_BLK_AIUP:
2233        case ASI_BLK_AIUPL:
2234        case ASI_BLK_AIUS_4V:
2235        case ASI_BLK_AIUS_L_4V:
2236        case ASI_BLK_AIUS:
2237        case ASI_BLK_AIUSL:
2238        case ASI_BLK_S:
2239        case ASI_BLK_SL:
2240        case ASI_BLK_P:
2241        case ASI_BLK_PL:
2242            type = GET_ASI_BLOCK;
2243            break;
2244        case ASI_FL8_S:
2245        case ASI_FL8_SL:
2246        case ASI_FL8_P:
2247        case ASI_FL8_PL:
2248            memop = MO_UB;
2249            type = GET_ASI_SHORT;
2250            break;
2251        case ASI_FL16_S:
2252        case ASI_FL16_SL:
2253        case ASI_FL16_P:
2254        case ASI_FL16_PL:
2255            memop = MO_TEUW;
2256            type = GET_ASI_SHORT;
2257            break;
2258        }
2259        /* The little-endian asis all have bit 3 set.  */
2260        if (asi & 8) {
2261            memop ^= MO_BSWAP;
2262        }
2263    }
2264#endif
2265
2266    return (DisasASI){ type, asi, mem_idx, memop };
2267}
2268
2269static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
2270                       int insn, TCGMemOp memop)
2271{
2272    DisasASI da = get_asi(dc, insn, memop);
2273
2274    switch (da.type) {
2275    case GET_ASI_EXCP:
2276        break;
2277    case GET_ASI_DTWINX: /* Reserved for ldda.  */
2278        gen_exception(dc, TT_ILL_INSN);
2279        break;
2280    case GET_ASI_DIRECT:
2281        gen_address_mask(dc, addr);
2282        tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
2283        break;
2284    default:
2285        {
2286            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2287            TCGv_i32 r_mop = tcg_const_i32(memop);
2288
2289            save_state(dc);
2290#ifdef TARGET_SPARC64
2291            gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_mop);
2292#else
2293            {
2294                TCGv_i64 t64 = tcg_temp_new_i64();
2295                gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
2296                tcg_gen_trunc_i64_tl(dst, t64);
2297                tcg_temp_free_i64(t64);
2298            }
2299#endif
2300            tcg_temp_free_i32(r_mop);
2301            tcg_temp_free_i32(r_asi);
2302        }
2303        break;
2304    }
2305}
2306
2307static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
2308                       int insn, TCGMemOp memop)
2309{
2310    DisasASI da = get_asi(dc, insn, memop);
2311
2312    switch (da.type) {
2313    case GET_ASI_EXCP:
2314        break;
2315    case GET_ASI_DTWINX: /* Reserved for stda.  */
2316#ifndef TARGET_SPARC64
2317        gen_exception(dc, TT_ILL_INSN);
2318        break;
2319#else
2320        if (!(dc->def->features & CPU_FEATURE_HYPV)) {
2321            /* Pre OpenSPARC CPUs don't have these */
2322            gen_exception(dc, TT_ILL_INSN);
2323            return;
2324        }
2325        /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
2326         * are ST_BLKINIT_ ASIs */
2327        /* fall through */
2328#endif
2329    case GET_ASI_DIRECT:
2330        gen_address_mask(dc, addr);
2331        tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
2332        break;
2333#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
2334    case GET_ASI_BCOPY:
2335        /* Copy 32 bytes from the address in SRC to ADDR.  */
2336        /* ??? The original qemu code suggests 4-byte alignment, dropping
2337           the low bits, but the only place I can see this used is in the
2338           Linux kernel with 32 byte alignment, which would make more sense
2339           as a cacheline-style operation.  */
2340        {
2341            TCGv saddr = tcg_temp_new();
2342            TCGv daddr = tcg_temp_new();
2343            TCGv four = tcg_const_tl(4);
2344            TCGv_i32 tmp = tcg_temp_new_i32();
2345            int i;
2346
2347            tcg_gen_andi_tl(saddr, src, -4);
2348            tcg_gen_andi_tl(daddr, addr, -4);
2349            for (i = 0; i < 32; i += 4) {
2350                /* Since the loads and stores are paired, allow the
2351                   copy to happen in the host endianness.  */
2352                tcg_gen_qemu_ld_i32(tmp, saddr, da.mem_idx, MO_UL);
2353                tcg_gen_qemu_st_i32(tmp, daddr, da.mem_idx, MO_UL);
2354                tcg_gen_add_tl(saddr, saddr, four);
2355                tcg_gen_add_tl(daddr, daddr, four);
2356            }
2357
2358            tcg_temp_free(saddr);
2359            tcg_temp_free(daddr);
2360            tcg_temp_free(four);
2361            tcg_temp_free_i32(tmp);
2362        }
2363        break;
2364#endif
2365    default:
2366        {
2367            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2368            TCGv_i32 r_mop = tcg_const_i32(memop & MO_SIZE);
2369
2370            save_state(dc);
2371#ifdef TARGET_SPARC64
2372            gen_helper_st_asi(cpu_env, addr, src, r_asi, r_mop);
2373#else
2374            {
2375                TCGv_i64 t64 = tcg_temp_new_i64();
2376                tcg_gen_extu_tl_i64(t64, src);
2377                gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
2378                tcg_temp_free_i64(t64);
2379            }
2380#endif
2381            tcg_temp_free_i32(r_mop);
2382            tcg_temp_free_i32(r_asi);
2383
2384            /* A write to a TLB register may alter page maps.  End the TB. */
2385            dc->npc = DYNAMIC_PC;
2386        }
2387        break;
2388    }
2389}
2390
2391static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
2392                         TCGv addr, int insn)
2393{
2394    DisasASI da = get_asi(dc, insn, MO_TEUL);
2395
2396    switch (da.type) {
2397    case GET_ASI_EXCP:
2398        break;
2399    case GET_ASI_DIRECT:
2400        gen_swap(dc, dst, src, addr, da.mem_idx, da.memop);
2401        break;
2402    default:
2403        /* ??? Should be DAE_invalid_asi.  */
2404        gen_exception(dc, TT_DATA_ACCESS);
2405        break;
2406    }
2407}
2408
2409static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
2410                        int insn, int rd)
2411{
2412    DisasASI da = get_asi(dc, insn, MO_TEUL);
2413    TCGv oldv;
2414
2415    switch (da.type) {
2416    case GET_ASI_EXCP:
2417        return;
2418    case GET_ASI_DIRECT:
2419        oldv = tcg_temp_new();
2420        tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
2421                                  da.mem_idx, da.memop);
2422        gen_store_gpr(dc, rd, oldv);
2423        tcg_temp_free(oldv);
2424        break;
2425    default:
2426        /* ??? Should be DAE_invalid_asi.  */
2427        gen_exception(dc, TT_DATA_ACCESS);
2428        break;
2429    }
2430}
2431
2432static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
2433{
2434    DisasASI da = get_asi(dc, insn, MO_UB);
2435
2436    switch (da.type) {
2437    case GET_ASI_EXCP:
2438        break;
2439    case GET_ASI_DIRECT:
2440        gen_ldstub(dc, dst, addr, da.mem_idx);
2441        break;
2442    default:
2443        /* ??? In theory, this should be raise DAE_invalid_asi.
2444           But the SS-20 roms do ldstuba [%l0] #ASI_M_CTL, %o1.  */
2445        if (parallel_cpus) {
2446            gen_helper_exit_atomic(cpu_env);
2447        } else {
2448            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2449            TCGv_i32 r_mop = tcg_const_i32(MO_UB);
2450            TCGv_i64 s64, t64;
2451
2452            save_state(dc);
2453            t64 = tcg_temp_new_i64();
2454            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
2455
2456            s64 = tcg_const_i64(0xff);
2457            gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_mop);
2458            tcg_temp_free_i64(s64);
2459            tcg_temp_free_i32(r_mop);
2460            tcg_temp_free_i32(r_asi);
2461
2462            tcg_gen_trunc_i64_tl(dst, t64);
2463            tcg_temp_free_i64(t64);
2464
2465            /* End the TB.  */
2466            dc->npc = DYNAMIC_PC;
2467        }
2468        break;
2469    }
2470}
2471#endif
2472
2473#ifdef TARGET_SPARC64
2474static void gen_ldf_asi(DisasContext *dc, TCGv addr,
2475                        int insn, int size, int rd)
2476{
2477    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
2478    TCGv_i32 d32;
2479    TCGv_i64 d64;
2480
2481    switch (da.type) {
2482    case GET_ASI_EXCP:
2483        break;
2484
2485    case GET_ASI_DIRECT:
2486        gen_address_mask(dc, addr);
2487        switch (size) {
2488        case 4:
2489            d32 = gen_dest_fpr_F(dc);
2490            tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
2491            gen_store_fpr_F(dc, rd, d32);
2492            break;
2493        case 8:
2494            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
2495                                da.memop | MO_ALIGN_4);
2496            break;
2497        case 16:
2498            d64 = tcg_temp_new_i64();
2499            tcg_gen_qemu_ld_i64(d64, addr, da.mem_idx, da.memop | MO_ALIGN_4);
2500            tcg_gen_addi_tl(addr, addr, 8);
2501            tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx,
2502                                da.memop | MO_ALIGN_4);
2503            tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
2504            tcg_temp_free_i64(d64);
2505            break;
2506        default:
2507            g_assert_not_reached();
2508        }
2509        break;
2510
2511    case GET_ASI_BLOCK:
2512        /* Valid for lddfa on aligned registers only.  */
2513        if (size == 8 && (rd & 7) == 0) {
2514            TCGMemOp memop;
2515            TCGv eight;
2516            int i;
2517
2518            gen_address_mask(dc, addr);
2519
2520            /* The first operation checks required alignment.  */
2521            memop = da.memop | MO_ALIGN_64;
2522            eight = tcg_const_tl(8);
2523            for (i = 0; ; ++i) {
2524                tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
2525                                    da.mem_idx, memop);
2526                if (i == 7) {
2527                    break;
2528                }
2529                tcg_gen_add_tl(addr, addr, eight);
2530                memop = da.memop;
2531            }
2532            tcg_temp_free(eight);
2533        } else {
2534            gen_exception(dc, TT_ILL_INSN);
2535        }
2536        break;
2537
2538    case GET_ASI_SHORT:
2539        /* Valid for lddfa only.  */
2540        if (size == 8) {
2541            gen_address_mask(dc, addr);
2542            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
2543        } else {
2544            gen_exception(dc, TT_ILL_INSN);
2545        }
2546        break;
2547
2548    default:
2549        {
2550            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2551            TCGv_i32 r_mop = tcg_const_i32(da.memop);
2552
2553            save_state(dc);
2554            /* According to the table in the UA2011 manual, the only
2555               other asis that are valid for ldfa/lddfa/ldqfa are
2556               the NO_FAULT asis.  We still need a helper for these,
2557               but we can just use the integer asi helper for them.  */
2558            switch (size) {
2559            case 4:
2560                d64 = tcg_temp_new_i64();
2561                gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
2562                d32 = gen_dest_fpr_F(dc);
2563                tcg_gen_extrl_i64_i32(d32, d64);
2564                tcg_temp_free_i64(d64);
2565                gen_store_fpr_F(dc, rd, d32);
2566                break;
2567            case 8:
2568                gen_helper_ld_asi(cpu_fpr[rd / 2], cpu_env, addr, r_asi, r_mop);
2569                break;
2570            case 16:
2571                d64 = tcg_temp_new_i64();
2572                gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
2573                tcg_gen_addi_tl(addr, addr, 8);
2574                gen_helper_ld_asi(cpu_fpr[rd/2+1], cpu_env, addr, r_asi, r_mop);
2575                tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
2576                tcg_temp_free_i64(d64);
2577                break;
2578            default:
2579                g_assert_not_reached();
2580            }
2581            tcg_temp_free_i32(r_mop);
2582            tcg_temp_free_i32(r_asi);
2583        }
2584        break;
2585    }
2586}
2587
2588static void gen_stf_asi(DisasContext *dc, TCGv addr,
2589                        int insn, int size, int rd)
2590{
2591    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
2592    TCGv_i32 d32;
2593
2594    switch (da.type) {
2595    case GET_ASI_EXCP:
2596        break;
2597
2598    case GET_ASI_DIRECT:
2599        gen_address_mask(dc, addr);
2600        switch (size) {
2601        case 4:
2602            d32 = gen_load_fpr_F(dc, rd);
2603            tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
2604            break;
2605        case 8:
2606            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
2607                                da.memop | MO_ALIGN_4);
2608            break;
2609        case 16:
2610            /* Only 4-byte alignment required.  However, it is legal for the
2611               cpu to signal the alignment fault, and the OS trap handler is
2612               required to fix it up.  Requiring 16-byte alignment here avoids
2613               having to probe the second page before performing the first
2614               write.  */
2615            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
2616                                da.memop | MO_ALIGN_16);
2617            tcg_gen_addi_tl(addr, addr, 8);
2618            tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
2619            break;
2620        default:
2621            g_assert_not_reached();
2622        }
2623        break;
2624
2625    case GET_ASI_BLOCK:
2626        /* Valid for stdfa on aligned registers only.  */
2627        if (size == 8 && (rd & 7) == 0) {
2628            TCGMemOp memop;
2629            TCGv eight;
2630            int i;
2631
2632            gen_address_mask(dc, addr);
2633
2634            /* The first operation checks required alignment.  */
2635            memop = da.memop | MO_ALIGN_64;
2636            eight = tcg_const_tl(8);
2637            for (i = 0; ; ++i) {
2638                tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
2639                                    da.mem_idx, memop);
2640                if (i == 7) {
2641                    break;
2642                }
2643                tcg_gen_add_tl(addr, addr, eight);
2644                memop = da.memop;
2645            }
2646            tcg_temp_free(eight);
2647        } else {
2648            gen_exception(dc, TT_ILL_INSN);
2649        }
2650        break;
2651
2652    case GET_ASI_SHORT:
2653        /* Valid for stdfa only.  */
2654        if (size == 8) {
2655            gen_address_mask(dc, addr);
2656            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
2657        } else {
2658            gen_exception(dc, TT_ILL_INSN);
2659        }
2660        break;
2661
2662    default:
2663        /* According to the table in the UA2011 manual, the only
2664           other asis that are valid for ldfa/lddfa/ldqfa are
2665           the PST* asis, which aren't currently handled.  */
2666        gen_exception(dc, TT_ILL_INSN);
2667        break;
2668    }
2669}
2670
2671static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
2672{
2673    DisasASI da = get_asi(dc, insn, MO_TEQ);
2674    TCGv_i64 hi = gen_dest_gpr(dc, rd);
2675    TCGv_i64 lo = gen_dest_gpr(dc, rd + 1);
2676
2677    switch (da.type) {
2678    case GET_ASI_EXCP:
2679        return;
2680
2681    case GET_ASI_DTWINX:
2682        gen_address_mask(dc, addr);
2683        tcg_gen_qemu_ld_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
2684        tcg_gen_addi_tl(addr, addr, 8);
2685        tcg_gen_qemu_ld_i64(lo, addr, da.mem_idx, da.memop);
2686        break;
2687
2688    case GET_ASI_DIRECT:
2689        {
2690            TCGv_i64 tmp = tcg_temp_new_i64();
2691
2692            gen_address_mask(dc, addr);
2693            tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop);
2694
2695            /* Note that LE ldda acts as if each 32-bit register
2696               result is byte swapped.  Having just performed one
2697               64-bit bswap, we need now to swap the writebacks.  */
2698            if ((da.memop & MO_BSWAP) == MO_TE) {
2699                tcg_gen_extr32_i64(lo, hi, tmp);
2700            } else {
2701                tcg_gen_extr32_i64(hi, lo, tmp);
2702            }
2703            tcg_temp_free_i64(tmp);
2704        }
2705        break;
2706
2707    default:
2708        /* ??? In theory we've handled all of the ASIs that are valid
2709           for ldda, and this should raise DAE_invalid_asi.  However,
2710           real hardware allows others.  This can be seen with e.g.
2711           FreeBSD 10.3 wrt ASI_IC_TAG.  */
2712        {
2713            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2714            TCGv_i32 r_mop = tcg_const_i32(da.memop);
2715            TCGv_i64 tmp = tcg_temp_new_i64();
2716
2717            save_state(dc);
2718            gen_helper_ld_asi(tmp, cpu_env, addr, r_asi, r_mop);
2719            tcg_temp_free_i32(r_asi);
2720            tcg_temp_free_i32(r_mop);
2721
2722            /* See above.  */
2723            if ((da.memop & MO_BSWAP) == MO_TE) {
2724                tcg_gen_extr32_i64(lo, hi, tmp);
2725            } else {
2726                tcg_gen_extr32_i64(hi, lo, tmp);
2727            }
2728            tcg_temp_free_i64(tmp);
2729        }
2730        break;
2731    }
2732
2733    gen_store_gpr(dc, rd, hi);
2734    gen_store_gpr(dc, rd + 1, lo);
2735}
2736
2737static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
2738                         int insn, int rd)
2739{
2740    DisasASI da = get_asi(dc, insn, MO_TEQ);
2741    TCGv lo = gen_load_gpr(dc, rd + 1);
2742
2743    switch (da.type) {
2744    case GET_ASI_EXCP:
2745        break;
2746
2747    case GET_ASI_DTWINX:
2748        gen_address_mask(dc, addr);
2749        tcg_gen_qemu_st_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
2750        tcg_gen_addi_tl(addr, addr, 8);
2751        tcg_gen_qemu_st_i64(lo, addr, da.mem_idx, da.memop);
2752        break;
2753
2754    case GET_ASI_DIRECT:
2755        {
2756            TCGv_i64 t64 = tcg_temp_new_i64();
2757
2758            /* Note that LE stda acts as if each 32-bit register result is
2759               byte swapped.  We will perform one 64-bit LE store, so now
2760               we must swap the order of the construction.  */
2761            if ((da.memop & MO_BSWAP) == MO_TE) {
2762                tcg_gen_concat32_i64(t64, lo, hi);
2763            } else {
2764                tcg_gen_concat32_i64(t64, hi, lo);
2765            }
2766            gen_address_mask(dc, addr);
2767            tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
2768            tcg_temp_free_i64(t64);
2769        }
2770        break;
2771
2772    default:
2773        /* ??? In theory we've handled all of the ASIs that are valid
2774           for stda, and this should raise DAE_invalid_asi.  */
2775        {
2776            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2777            TCGv_i32 r_mop = tcg_const_i32(da.memop);
2778            TCGv_i64 t64 = tcg_temp_new_i64();
2779
2780            /* See above.  */
2781            if ((da.memop & MO_BSWAP) == MO_TE) {
2782                tcg_gen_concat32_i64(t64, lo, hi);
2783            } else {
2784                tcg_gen_concat32_i64(t64, hi, lo);
2785            }
2786
2787            save_state(dc);
2788            gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
2789            tcg_temp_free_i32(r_mop);
2790            tcg_temp_free_i32(r_asi);
2791            tcg_temp_free_i64(t64);
2792        }
2793        break;
2794    }
2795}
2796
2797static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
2798                         int insn, int rd)
2799{
2800    DisasASI da = get_asi(dc, insn, MO_TEQ);
2801    TCGv oldv;
2802
2803    switch (da.type) {
2804    case GET_ASI_EXCP:
2805        return;
2806    case GET_ASI_DIRECT:
2807        oldv = tcg_temp_new();
2808        tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
2809                                  da.mem_idx, da.memop);
2810        gen_store_gpr(dc, rd, oldv);
2811        tcg_temp_free(oldv);
2812        break;
2813    default:
2814        /* ??? Should be DAE_invalid_asi.  */
2815        gen_exception(dc, TT_DATA_ACCESS);
2816        break;
2817    }
2818}
2819
2820#elif !defined(CONFIG_USER_ONLY)
2821static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
2822{
2823    /* ??? Work around an apparent bug in Ubuntu gcc 4.8.2-10ubuntu2+12,
2824       whereby "rd + 1" elicits "error: array subscript is above array".
2825       Since we have already asserted that rd is even, the semantics
2826       are unchanged.  */
2827    TCGv lo = gen_dest_gpr(dc, rd | 1);
2828    TCGv hi = gen_dest_gpr(dc, rd);
2829    TCGv_i64 t64 = tcg_temp_new_i64();
2830    DisasASI da = get_asi(dc, insn, MO_TEQ);
2831
2832    switch (da.type) {
2833    case GET_ASI_EXCP:
2834        tcg_temp_free_i64(t64);
2835        return;
2836    case GET_ASI_DIRECT:
2837        gen_address_mask(dc, addr);
2838        tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop);
2839        break;
2840    default:
2841        {
2842            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2843            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
2844
2845            save_state(dc);
2846            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
2847            tcg_temp_free_i32(r_mop);
2848            tcg_temp_free_i32(r_asi);
2849        }
2850        break;
2851    }
2852
2853    tcg_gen_extr_i64_i32(lo, hi, t64);
2854    tcg_temp_free_i64(t64);
2855    gen_store_gpr(dc, rd | 1, lo);
2856    gen_store_gpr(dc, rd, hi);
2857}
2858
2859static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
2860                         int insn, int rd)
2861{
2862    DisasASI da = get_asi(dc, insn, MO_TEQ);
2863    TCGv lo = gen_load_gpr(dc, rd + 1);
2864    TCGv_i64 t64 = tcg_temp_new_i64();
2865
2866    tcg_gen_concat_tl_i64(t64, lo, hi);
2867
2868    switch (da.type) {
2869    case GET_ASI_EXCP:
2870        break;
2871    case GET_ASI_DIRECT:
2872        gen_address_mask(dc, addr);
2873        tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
2874        break;
2875    case GET_ASI_BFILL:
2876        /* Store 32 bytes of T64 to ADDR.  */
2877        /* ??? The original qemu code suggests 8-byte alignment, dropping
2878           the low bits, but the only place I can see this used is in the
2879           Linux kernel with 32 byte alignment, which would make more sense
2880           as a cacheline-style operation.  */
2881        {
2882            TCGv d_addr = tcg_temp_new();
2883            TCGv eight = tcg_const_tl(8);
2884            int i;
2885
2886            tcg_gen_andi_tl(d_addr, addr, -8);
2887            for (i = 0; i < 32; i += 8) {
2888                tcg_gen_qemu_st_i64(t64, d_addr, da.mem_idx, da.memop);
2889                tcg_gen_add_tl(d_addr, d_addr, eight);
2890            }
2891
2892            tcg_temp_free(d_addr);
2893            tcg_temp_free(eight);
2894        }
2895        break;
2896    default:
2897        {
2898            TCGv_i32 r_asi = tcg_const_i32(da.asi);
2899            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
2900
2901            save_state(dc);
2902            gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
2903            tcg_temp_free_i32(r_mop);
2904            tcg_temp_free_i32(r_asi);
2905        }
2906        break;
2907    }
2908
2909    tcg_temp_free_i64(t64);
2910}
2911#endif
2912
2913static TCGv get_src1(DisasContext *dc, unsigned int insn)
2914{
2915    unsigned int rs1 = GET_FIELD(insn, 13, 17);
2916    return gen_load_gpr(dc, rs1);
2917}
2918
2919static TCGv get_src2(DisasContext *dc, unsigned int insn)
2920{
2921    if (IS_IMM) { /* immediate */
2922        target_long simm = GET_FIELDs(insn, 19, 31);
2923        TCGv t = get_temp_tl(dc);
2924        tcg_gen_movi_tl(t, simm);
2925        return t;
2926    } else {      /* register */
2927        unsigned int rs2 = GET_FIELD(insn, 27, 31);
2928        return gen_load_gpr(dc, rs2);
2929    }
2930}
2931
2932#ifdef TARGET_SPARC64
2933static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2934{
2935    TCGv_i32 c32, zero, dst, s1, s2;
2936
2937    /* We have two choices here: extend the 32 bit data and use movcond_i64,
2938       or fold the comparison down to 32 bits and use movcond_i32.  Choose
2939       the later.  */
2940    c32 = tcg_temp_new_i32();
2941    if (cmp->is_bool) {
2942        tcg_gen_extrl_i64_i32(c32, cmp->c1);
2943    } else {
2944        TCGv_i64 c64 = tcg_temp_new_i64();
2945        tcg_gen_setcond_i64(cmp->cond, c64, cmp->c1, cmp->c2);
2946        tcg_gen_extrl_i64_i32(c32, c64);
2947        tcg_temp_free_i64(c64);
2948    }
2949
2950    s1 = gen_load_fpr_F(dc, rs);
2951    s2 = gen_load_fpr_F(dc, rd);
2952    dst = gen_dest_fpr_F(dc);
2953    zero = tcg_const_i32(0);
2954
2955    tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
2956
2957    tcg_temp_free_i32(c32);
2958    tcg_temp_free_i32(zero);
2959    gen_store_fpr_F(dc, rd, dst);
2960}
2961
2962static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2963{
2964    TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
2965    tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, cmp->c2,
2966                        gen_load_fpr_D(dc, rs),
2967                        gen_load_fpr_D(dc, rd));
2968    gen_store_fpr_D(dc, rd, dst);
2969}
2970
2971static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2972{
2973    int qd = QFPREG(rd);
2974    int qs = QFPREG(rs);
2975
2976    tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, cmp->c2,
2977                        cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
2978    tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
2979                        cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
2980
2981    gen_update_fprs_dirty(dc, qd);
2982}
2983
2984#ifndef CONFIG_USER_ONLY
2985static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env)
2986{
2987    TCGv_i32 r_tl = tcg_temp_new_i32();
2988
2989    /* load env->tl into r_tl */
2990    tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
2991
2992    /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
2993    tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
2994
2995    /* calculate offset to current trap state from env->ts, reuse r_tl */
2996    tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
2997    tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUSPARCState, ts));
2998
2999    /* tsptr = env->ts[env->tl & MAXTL_MASK] */
3000    {
3001        TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
3002        tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
3003        tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
3004        tcg_temp_free_ptr(r_tl_tmp);
3005    }
3006
3007    tcg_temp_free_i32(r_tl);
3008}
3009#endif
3010
3011static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
3012                     int width, bool cc, bool left)
3013{
3014    TCGv lo1, lo2, t1, t2;
3015    uint64_t amask, tabl, tabr;
3016    int shift, imask, omask;
3017
3018    if (cc) {
3019        tcg_gen_mov_tl(cpu_cc_src, s1);
3020        tcg_gen_mov_tl(cpu_cc_src2, s2);
3021        tcg_gen_sub_tl(cpu_cc_dst, s1, s2);
3022        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
3023        dc->cc_op = CC_OP_SUB;
3024    }
3025
3026    /* Theory of operation: there are two tables, left and right (not to
3027       be confused with the left and right versions of the opcode).  These
3028       are indexed by the low 3 bits of the inputs.  To make things "easy",
3029       these tables are loaded into two constants, TABL and TABR below.
3030       The operation index = (input & imask) << shift calculates the index
3031       into the constant, while val = (table >> index) & omask calculates
3032       the value we're looking for.  */
3033    switch (width) {
3034    case 8:
3035        imask = 0x7;
3036        shift = 3;
3037        omask = 0xff;
3038        if (left) {
3039            tabl = 0x80c0e0f0f8fcfeffULL;
3040            tabr = 0xff7f3f1f0f070301ULL;
3041        } else {
3042            tabl = 0x0103070f1f3f7fffULL;
3043            tabr = 0xfffefcf8f0e0c080ULL;
3044        }
3045        break;
3046    case 16:
3047        imask = 0x6;
3048        shift = 1;
3049        omask = 0xf;
3050        if (left) {
3051            tabl = 0x8cef;
3052            tabr = 0xf731;
3053        } else {
3054            tabl = 0x137f;
3055            tabr = 0xfec8;
3056        }
3057        break;
3058    case 32:
3059        imask = 0x4;
3060        shift = 0;
3061        omask = 0x3;
3062        if (left) {
3063            tabl = (2 << 2) | 3;
3064            tabr = (3 << 2) | 1;
3065        } else {
3066            tabl = (1 << 2) | 3;
3067            tabr = (3 << 2) | 2;
3068        }
3069        break;
3070    default:
3071        abort();
3072    }
3073
3074    lo1 = tcg_temp_new();
3075    lo2 = tcg_temp_new();
3076    tcg_gen_andi_tl(lo1, s1, imask);
3077    tcg_gen_andi_tl(lo2, s2, imask);
3078    tcg_gen_shli_tl(lo1, lo1, shift);
3079    tcg_gen_shli_tl(lo2, lo2, shift);
3080
3081    t1 = tcg_const_tl(tabl);
3082    t2 = tcg_const_tl(tabr);
3083    tcg_gen_shr_tl(lo1, t1, lo1);
3084    tcg_gen_shr_tl(lo2, t2, lo2);
3085    tcg_gen_andi_tl(dst, lo1, omask);
3086    tcg_gen_andi_tl(lo2, lo2, omask);
3087
3088    amask = -8;
3089    if (AM_CHECK(dc)) {
3090        amask &= 0xffffffffULL;
3091    }
3092    tcg_gen_andi_tl(s1, s1, amask);
3093    tcg_gen_andi_tl(s2, s2, amask);
3094
3095    /* We want to compute
3096        dst = (s1 == s2 ? lo1 : lo1 & lo2).
3097       We've already done dst = lo1, so this reduces to
3098        dst &= (s1 == s2 ? -1 : lo2)
3099       Which we perform by
3100        lo2 |= -(s1 == s2)
3101        dst &= lo2
3102    */
3103    tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2);
3104    tcg_gen_neg_tl(t1, t1);
3105    tcg_gen_or_tl(lo2, lo2, t1);
3106    tcg_gen_and_tl(dst, dst, lo2);
3107
3108    tcg_temp_free(lo1);
3109    tcg_temp_free(lo2);
3110    tcg_temp_free(t1);
3111    tcg_temp_free(t2);
3112}
3113
3114static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
3115{
3116    TCGv tmp = tcg_temp_new();
3117
3118    tcg_gen_add_tl(tmp, s1, s2);
3119    tcg_gen_andi_tl(dst, tmp, -8);
3120    if (left) {
3121        tcg_gen_neg_tl(tmp, tmp);
3122    }
3123    tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
3124
3125    tcg_temp_free(tmp);
3126}
3127
3128static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
3129{
3130    TCGv t1, t2, shift;
3131
3132    t1 = tcg_temp_new();
3133    t2 = tcg_temp_new();
3134    shift = tcg_temp_new();
3135
3136    tcg_gen_andi_tl(shift, gsr, 7);
3137    tcg_gen_shli_tl(shift, shift, 3);
3138    tcg_gen_shl_tl(t1, s1, shift);
3139
3140    /* A shift of 64 does not produce 0 in TCG.  Divide this into a
3141       shift of (up to 63) followed by a constant shift of 1.  */
3142    tcg_gen_xori_tl(shift, shift, 63);
3143    tcg_gen_shr_tl(t2, s2, shift);
3144    tcg_gen_shri_tl(t2, t2, 1);
3145
3146    tcg_gen_or_tl(dst, t1, t2);
3147
3148    tcg_temp_free(t1);
3149    tcg_temp_free(t2);
3150    tcg_temp_free(shift);
3151}
3152#endif
3153
3154#define CHECK_IU_FEATURE(dc, FEATURE)                      \
3155    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
3156        goto illegal_insn;
3157#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
3158    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
3159        goto nfpu_insn;
3160
3161/* before an instruction, dc->pc must be static */
3162static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
3163{
3164    unsigned int opc, rs1, rs2, rd;
3165    TCGv cpu_src1, cpu_src2;
3166    TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
3167    TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
3168    target_long simm;
3169
3170    opc = GET_FIELD(insn, 0, 1);
3171    rd = GET_FIELD(insn, 2, 6);
3172
3173    switch (opc) {
3174    case 0:                     /* branches/sethi */
3175        {
3176            unsigned int xop = GET_FIELD(insn, 7, 9);
3177            int32_t target;
3178            switch (xop) {
3179#ifdef TARGET_SPARC64
3180            case 0x1:           /* V9 BPcc */
3181                {
3182                    int cc;
3183
3184                    target = GET_FIELD_SP(insn, 0, 18);
3185                    target = sign_extend(target, 19);
3186                    target <<= 2;
3187                    cc = GET_FIELD_SP(insn, 20, 21);
3188                    if (cc == 0)
3189                        do_branch(dc, target, insn, 0);
3190                    else if (cc == 2)
3191                        do_branch(dc, target, insn, 1);
3192                    else
3193                        goto illegal_insn;
3194                    goto jmp_insn;
3195                }
3196            case 0x3:           /* V9 BPr */
3197                {
3198                    target = GET_FIELD_SP(insn, 0, 13) |
3199                        (GET_FIELD_SP(insn, 20, 21) << 14);
3200                    target = sign_extend(target, 16);
3201                    target <<= 2;
3202                    cpu_src1 = get_src1(dc, insn);
3203                    do_branch_reg(dc, target, insn, cpu_src1);
3204                    goto jmp_insn;
3205                }
3206            case 0x5:           /* V9 FBPcc */
3207                {
3208                    int cc = GET_FIELD_SP(insn, 20, 21);
3209                    if (gen_trap_ifnofpu(dc)) {
3210                        goto jmp_insn;
3211                    }
3212                    target = GET_FIELD_SP(insn, 0, 18);
3213                    target = sign_extend(target, 19);
3214                    target <<= 2;
3215                    do_fbranch(dc, target, insn, cc);
3216                    goto jmp_insn;
3217                }
3218#else
3219            case 0x7:           /* CBN+x */
3220                {
3221                    goto ncp_insn;
3222                }
3223#endif
3224            case 0x2:           /* BN+x */
3225                {
3226                    target = GET_FIELD(insn, 10, 31);
3227                    target = sign_extend(target, 22);
3228                    target <<= 2;
3229                    do_branch(dc, target, insn, 0);
3230                    goto jmp_insn;
3231                }
3232            case 0x6:           /* FBN+x */
3233                {
3234                    if (gen_trap_ifnofpu(dc)) {
3235                        goto jmp_insn;
3236                    }
3237                    target = GET_FIELD(insn, 10, 31);
3238                    target = sign_extend(target, 22);
3239                    target <<= 2;
3240                    do_fbranch(dc, target, insn, 0);
3241                    goto jmp_insn;
3242                }
3243            case 0x4:           /* SETHI */
3244                /* Special-case %g0 because that's the canonical nop.  */
3245                if (rd) {
3246                    uint32_t value = GET_FIELD(insn, 10, 31);
3247                    TCGv t = gen_dest_gpr(dc, rd);
3248                    tcg_gen_movi_tl(t, value << 10);
3249                    gen_store_gpr(dc, rd, t);
3250                }
3251                break;
3252            case 0x0:           /* UNIMPL */
3253            default:
3254                goto illegal_insn;
3255            }
3256            break;
3257        }
3258        break;
3259    case 1:                     /*CALL*/
3260        {
3261            target_long target = GET_FIELDs(insn, 2, 31) << 2;
3262            TCGv o7 = gen_dest_gpr(dc, 15);
3263
3264            tcg_gen_movi_tl(o7, dc->pc);
3265            gen_store_gpr(dc, 15, o7);
3266            target += dc->pc;
3267            gen_mov_pc_npc(dc);
3268#ifdef TARGET_SPARC64
3269            if (unlikely(AM_CHECK(dc))) {
3270                target &= 0xffffffffULL;
3271            }
3272#endif
3273            dc->npc = target;
3274        }
3275        goto jmp_insn;
3276    case 2:                     /* FPU & Logical Operations */
3277        {
3278            unsigned int xop = GET_FIELD(insn, 7, 12);
3279            TCGv cpu_dst = get_temp_tl(dc);
3280            TCGv cpu_tmp0;
3281
3282            if (xop == 0x3a) {  /* generate trap */
3283                int cond = GET_FIELD(insn, 3, 6);
3284                TCGv_i32 trap;
3285                TCGLabel *l1 = NULL;
3286                int mask;
3287
3288                if (cond == 0) {
3289                    /* Trap never.  */
3290                    break;
3291                }
3292
3293                save_state(dc);
3294
3295                if (cond != 8) {
3296                    /* Conditional trap.  */
3297                    DisasCompare cmp;
3298#ifdef TARGET_SPARC64
3299                    /* V9 icc/xcc */
3300                    int cc = GET_FIELD_SP(insn, 11, 12);
3301                    if (cc == 0) {
3302                        gen_compare(&cmp, 0, cond, dc);
3303                    } else if (cc == 2) {
3304                        gen_compare(&cmp, 1, cond, dc);
3305                    } else {
3306                        goto illegal_insn;
3307                    }
3308#else
3309                    gen_compare(&cmp, 0, cond, dc);
3310#endif
3311                    l1 = gen_new_label();
3312                    tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
3313                                      cmp.c1, cmp.c2, l1);
3314                    free_compare(&cmp);
3315                }
3316
3317                mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
3318                        ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
3319
3320                /* Don't use the normal temporaries, as they may well have
3321                   gone out of scope with the branch above.  While we're
3322                   doing that we might as well pre-truncate to 32-bit.  */
3323                trap = tcg_temp_new_i32();
3324
3325                rs1 = GET_FIELD_SP(insn, 14, 18);
3326                if (IS_IMM) {
3327                    rs2 = GET_FIELD_SP(insn, 0, 7);
3328                    if (rs1 == 0) {
3329                        tcg_gen_movi_i32(trap, (rs2 & mask) + TT_TRAP);
3330                        /* Signal that the trap value is fully constant.  */
3331                        mask = 0;
3332                    } else {
3333                        TCGv t1 = gen_load_gpr(dc, rs1);
3334                        tcg_gen_trunc_tl_i32(trap, t1);
3335                        tcg_gen_addi_i32(trap, trap, rs2);
3336                    }
3337                } else {
3338                    TCGv t1, t2;
3339                    rs2 = GET_FIELD_SP(insn, 0, 4);
3340                    t1 = gen_load_gpr(dc, rs1);
3341                    t2 = gen_load_gpr(dc, rs2);
3342                    tcg_gen_add_tl(t1, t1, t2);
3343                    tcg_gen_trunc_tl_i32(trap, t1);
3344                }
3345                if (mask != 0) {
3346                    tcg_gen_andi_i32(trap, trap, mask);
3347                    tcg_gen_addi_i32(trap, trap, TT_TRAP);
3348                }
3349
3350                gen_helper_raise_exception(cpu_env, trap);
3351                tcg_temp_free_i32(trap);
3352
3353                if (cond == 8) {
3354                    /* An unconditional trap ends the TB.  */
3355                    dc->is_br = 1;
3356                    goto jmp_insn;
3357                } else {
3358                    /* A conditional trap falls through to the next insn.  */
3359                    gen_set_label(l1);
3360                    break;
3361                }
3362            } else if (xop == 0x28) {
3363                rs1 = GET_FIELD(insn, 13, 17);
3364                switch(rs1) {
3365                case 0: /* rdy */
3366#ifndef TARGET_SPARC64
3367                case 0x01 ... 0x0e: /* undefined in the SPARCv8
3368                                       manual, rdy on the microSPARC
3369                                       II */
3370                case 0x0f:          /* stbar in the SPARCv8 manual,
3371                                       rdy on the microSPARC II */
3372                case 0x10 ... 0x1f: /* implementation-dependent in the
3373                                       SPARCv8 manual, rdy on the
3374                                       microSPARC II */
3375                    /* Read Asr17 */
3376                    if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
3377                        TCGv t = gen_dest_gpr(dc, rd);
3378                        /* Read Asr17 for a Leon3 monoprocessor */
3379                        tcg_gen_movi_tl(t, (1 << 8) | (dc->def->nwindows - 1));
3380                        gen_store_gpr(dc, rd, t);
3381                        break;
3382                    }
3383#endif
3384                    gen_store_gpr(dc, rd, cpu_y);
3385                    break;
3386#ifdef TARGET_SPARC64
3387                case 0x2: /* V9 rdccr */
3388                    update_psr(dc);
3389                    gen_helper_rdccr(cpu_dst, cpu_env);
3390                    gen_store_gpr(dc, rd, cpu_dst);
3391                    break;
3392                case 0x3: /* V9 rdasi */
3393                    tcg_gen_movi_tl(cpu_dst, dc->asi);
3394                    gen_store_gpr(dc, rd, cpu_dst);
3395                    break;
3396                case 0x4: /* V9 rdtick */
3397                    {
3398                        TCGv_ptr r_tickptr;
3399                        TCGv_i32 r_const;
3400
3401                        r_tickptr = tcg_temp_new_ptr();
3402                        r_const = tcg_const_i32(dc->mem_idx);
3403                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
3404                                       offsetof(CPUSPARCState, tick));
3405                        gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
3406                                                  r_const);
3407                        tcg_temp_free_ptr(r_tickptr);
3408                        tcg_temp_free_i32(r_const);
3409                        gen_store_gpr(dc, rd, cpu_dst);
3410                    }
3411                    break;
3412                case 0x5: /* V9 rdpc */
3413                    {
3414                        TCGv t = gen_dest_gpr(dc, rd);
3415                        if (unlikely(AM_CHECK(dc))) {
3416                            tcg_gen_movi_tl(t, dc->pc & 0xffffffffULL);
3417                        } else {
3418                            tcg_gen_movi_tl(t, dc->pc);
3419                        }
3420                        gen_store_gpr(dc, rd, t);
3421                    }
3422                    break;
3423                case 0x6: /* V9 rdfprs */
3424                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
3425                    gen_store_gpr(dc, rd, cpu_dst);
3426                    break;
3427                case 0xf: /* V9 membar */
3428                    break; /* no effect */
3429                case 0x13: /* Graphics Status */
3430                    if (gen_trap_ifnofpu(dc)) {
3431                        goto jmp_insn;
3432                    }
3433                    gen_store_gpr(dc, rd, cpu_gsr);
3434                    break;
3435                case 0x16: /* Softint */
3436                    tcg_gen_ld32s_tl(cpu_dst, cpu_env,
3437                                     offsetof(CPUSPARCState, softint));
3438                    gen_store_gpr(dc, rd, cpu_dst);
3439                    break;
3440                case 0x17: /* Tick compare */
3441                    gen_store_gpr(dc, rd, cpu_tick_cmpr);
3442                    break;
3443                case 0x18: /* System tick */
3444                    {
3445                        TCGv_ptr r_tickptr;
3446                        TCGv_i32 r_const;
3447
3448                        r_tickptr = tcg_temp_new_ptr();
3449                        r_const = tcg_const_i32(dc->mem_idx);
3450                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
3451                                       offsetof(CPUSPARCState, stick));
3452                        gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
3453                                                  r_const);
3454                        tcg_temp_free_ptr(r_tickptr);
3455                        tcg_temp_free_i32(r_const);
3456                        gen_store_gpr(dc, rd, cpu_dst);
3457                    }
3458                    break;
3459                case 0x19: /* System tick compare */
3460                    gen_store_gpr(dc, rd, cpu_stick_cmpr);
3461                    break;
3462                case 0x1a: /* UltraSPARC-T1 Strand status */
3463                    /* XXX HYPV check maybe not enough, UA2005 & UA2007 describe
3464                     * this ASR as impl. dep
3465                     */
3466                    CHECK_IU_FEATURE(dc, HYPV);
3467                    {
3468                        TCGv t = gen_dest_gpr(dc, rd);
3469                        tcg_gen_movi_tl(t, 1UL);
3470                        gen_store_gpr(dc, rd, t);
3471                    }
3472                    break;
3473                case 0x10: /* Performance Control */
3474                case 0x11: /* Performance Instrumentation Counter */
3475                case 0x12: /* Dispatch Control */
3476                case 0x14: /* Softint set, WO */
3477                case 0x15: /* Softint clear, WO */
3478#endif
3479                default:
3480                    goto illegal_insn;
3481                }
3482#if !defined(CONFIG_USER_ONLY)
3483            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
3484#ifndef TARGET_SPARC64
3485                if (!supervisor(dc)) {
3486                    goto priv_insn;
3487                }
3488                update_psr(dc);
3489                gen_helper_rdpsr(cpu_dst, cpu_env);
3490#else
3491                CHECK_IU_FEATURE(dc, HYPV);
3492                if (!hypervisor(dc))
3493                    goto priv_insn;
3494                rs1 = GET_FIELD(insn, 13, 17);
3495                switch (rs1) {
3496                case 0: // hpstate
3497                    tcg_gen_ld_i64(cpu_dst, cpu_env,
3498                                   offsetof(CPUSPARCState, hpstate));
3499                    break;
3500                case 1: // htstate
3501                    // gen_op_rdhtstate();
3502                    break;
3503                case 3: // hintp
3504                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
3505                    break;
3506                case 5: // htba
3507                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
3508                    break;
3509                case 6: // hver
3510                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
3511                    break;
3512                case 31: // hstick_cmpr
3513                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
3514                    break;
3515                default:
3516                    goto illegal_insn;
3517                }
3518#endif
3519                gen_store_gpr(dc, rd, cpu_dst);
3520                break;
3521            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
3522                if (!supervisor(dc)) {
3523                    goto priv_insn;
3524                }
3525                cpu_tmp0 = get_temp_tl(dc);
3526#ifdef TARGET_SPARC64
3527                rs1 = GET_FIELD(insn, 13, 17);
3528                switch (rs1) {
3529                case 0: // tpc
3530                    {
3531                        TCGv_ptr r_tsptr;
3532
3533                        r_tsptr = tcg_temp_new_ptr();
3534                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3535                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
3536                                      offsetof(trap_state, tpc));
3537                        tcg_temp_free_ptr(r_tsptr);
3538                    }
3539                    break;
3540                case 1: // tnpc
3541                    {
3542                        TCGv_ptr r_tsptr;
3543
3544                        r_tsptr = tcg_temp_new_ptr();
3545                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3546                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
3547                                      offsetof(trap_state, tnpc));
3548                        tcg_temp_free_ptr(r_tsptr);
3549                    }
3550                    break;
3551                case 2: // tstate
3552                    {
3553                        TCGv_ptr r_tsptr;
3554
3555                        r_tsptr = tcg_temp_new_ptr();
3556                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3557                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
3558                                      offsetof(trap_state, tstate));
3559                        tcg_temp_free_ptr(r_tsptr);
3560                    }
3561                    break;
3562                case 3: // tt
3563                    {
3564                        TCGv_ptr r_tsptr = tcg_temp_new_ptr();
3565
3566                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3567                        tcg_gen_ld32s_tl(cpu_tmp0, r_tsptr,
3568                                         offsetof(trap_state, tt));
3569                        tcg_temp_free_ptr(r_tsptr);
3570                    }
3571                    break;
3572                case 4: // tick
3573                    {
3574                        TCGv_ptr r_tickptr;
3575                        TCGv_i32 r_const;
3576
3577                        r_tickptr = tcg_temp_new_ptr();
3578                        r_const = tcg_const_i32(dc->mem_idx);
3579                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
3580                                       offsetof(CPUSPARCState, tick));
3581                        gen_helper_tick_get_count(cpu_tmp0, cpu_env,
3582                                                  r_tickptr, r_const);
3583                        tcg_temp_free_ptr(r_tickptr);
3584                        tcg_temp_free_i32(r_const);
3585                    }
3586                    break;
3587                case 5: // tba
3588                    tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
3589                    break;
3590                case 6: // pstate
3591                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3592                                     offsetof(CPUSPARCState, pstate));
3593                    break;
3594                case 7: // tl
3595                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3596                                     offsetof(CPUSPARCState, tl));
3597                    break;
3598                case 8: // pil
3599                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3600                                     offsetof(CPUSPARCState, psrpil));
3601                    break;
3602                case 9: // cwp
3603                    gen_helper_rdcwp(cpu_tmp0, cpu_env);
3604                    break;
3605                case 10: // cansave
3606                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3607                                     offsetof(CPUSPARCState, cansave));
3608                    break;
3609                case 11: // canrestore
3610                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3611                                     offsetof(CPUSPARCState, canrestore));
3612                    break;
3613                case 12: // cleanwin
3614                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3615                                     offsetof(CPUSPARCState, cleanwin));
3616                    break;
3617                case 13: // otherwin
3618                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3619                                     offsetof(CPUSPARCState, otherwin));
3620                    break;
3621                case 14: // wstate
3622                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3623                                     offsetof(CPUSPARCState, wstate));
3624                    break;
3625                case 16: // UA2005 gl
3626                    CHECK_IU_FEATURE(dc, GL);
3627                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3628                                     offsetof(CPUSPARCState, gl));
3629                    break;
3630                case 26: // UA2005 strand status
3631                    CHECK_IU_FEATURE(dc, HYPV);
3632                    if (!hypervisor(dc))
3633                        goto priv_insn;
3634                    tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
3635                    break;
3636                case 31: // ver
3637                    tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
3638                    break;
3639                case 15: // fq
3640                default:
3641                    goto illegal_insn;
3642                }
3643#else
3644                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
3645#endif
3646                gen_store_gpr(dc, rd, cpu_tmp0);
3647                break;
3648            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
3649#ifdef TARGET_SPARC64
3650                gen_helper_flushw(cpu_env);
3651#else
3652                if (!supervisor(dc))
3653                    goto priv_insn;
3654                gen_store_gpr(dc, rd, cpu_tbr);
3655#endif
3656                break;
3657#endif
3658            } else if (xop == 0x34) {   /* FPU Operations */
3659                if (gen_trap_ifnofpu(dc)) {
3660                    goto jmp_insn;
3661                }
3662                gen_op_clear_ieee_excp_and_FTT();
3663                rs1 = GET_FIELD(insn, 13, 17);
3664                rs2 = GET_FIELD(insn, 27, 31);
3665                xop = GET_FIELD(insn, 18, 26);
3666
3667                switch (xop) {
3668                case 0x1: /* fmovs */
3669                    cpu_src1_32 = gen_load_fpr_F(dc, rs2);
3670                    gen_store_fpr_F(dc, rd, cpu_src1_32);
3671                    break;
3672                case 0x5: /* fnegs */
3673                    gen_ne_fop_FF(dc, rd, rs2, gen_helper_fnegs);
3674                    break;
3675                case 0x9: /* fabss */
3676                    gen_ne_fop_FF(dc, rd, rs2, gen_helper_fabss);
3677                    break;
3678                case 0x29: /* fsqrts */
3679                    CHECK_FPU_FEATURE(dc, FSQRT);
3680                    gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
3681                    break;
3682                case 0x2a: /* fsqrtd */
3683                    CHECK_FPU_FEATURE(dc, FSQRT);
3684                    gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd);
3685                    break;
3686                case 0x2b: /* fsqrtq */
3687                    CHECK_FPU_FEATURE(dc, FLOAT128);
3688                    gen_fop_QQ(dc, rd, rs2, gen_helper_fsqrtq);
3689                    break;
3690                case 0x41: /* fadds */
3691                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fadds);
3692                    break;
3693                case 0x42: /* faddd */
3694                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_faddd);
3695                    break;
3696                case 0x43: /* faddq */
3697                    CHECK_FPU_FEATURE(dc, FLOAT128);
3698                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq);
3699                    break;
3700                case 0x45: /* fsubs */
3701                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fsubs);
3702                    break;
3703                case 0x46: /* fsubd */
3704                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fsubd);
3705                    break;
3706                case 0x47: /* fsubq */
3707                    CHECK_FPU_FEATURE(dc, FLOAT128);
3708                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
3709                    break;
3710                case 0x49: /* fmuls */
3711                    CHECK_FPU_FEATURE(dc, FMUL);
3712                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fmuls);
3713                    break;
3714                case 0x4a: /* fmuld */
3715                    CHECK_FPU_FEATURE(dc, FMUL);
3716                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld);
3717                    break;
3718                case 0x4b: /* fmulq */
3719                    CHECK_FPU_FEATURE(dc, FLOAT128);
3720                    CHECK_FPU_FEATURE(dc, FMUL);
3721                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
3722                    break;
3723                case 0x4d: /* fdivs */
3724                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fdivs);
3725                    break;
3726                case 0x4e: /* fdivd */
3727                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fdivd);
3728                    break;
3729                case 0x4f: /* fdivq */
3730                    CHECK_FPU_FEATURE(dc, FLOAT128);
3731                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fdivq);
3732                    break;
3733                case 0x69: /* fsmuld */
3734                    CHECK_FPU_FEATURE(dc, FSMULD);
3735                    gen_fop_DFF(dc, rd, rs1, rs2, gen_helper_fsmuld);
3736                    break;
3737                case 0x6e: /* fdmulq */
3738                    CHECK_FPU_FEATURE(dc, FLOAT128);
3739                    gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq);
3740                    break;
3741                case 0xc4: /* fitos */
3742                    gen_fop_FF(dc, rd, rs2, gen_helper_fitos);
3743                    break;
3744                case 0xc6: /* fdtos */
3745                    gen_fop_FD(dc, rd, rs2, gen_helper_fdtos);
3746                    break;
3747                case 0xc7: /* fqtos */
3748                    CHECK_FPU_FEATURE(dc, FLOAT128);
3749                    gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos);
3750                    break;
3751                case 0xc8: /* fitod */
3752                    gen_ne_fop_DF(dc, rd, rs2, gen_helper_fitod);
3753                    break;
3754                case 0xc9: /* fstod */
3755                    gen_ne_fop_DF(dc, rd, rs2, gen_helper_fstod);
3756                    break;
3757                case 0xcb: /* fqtod */
3758                    CHECK_FPU_FEATURE(dc, FLOAT128);
3759                    gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod);
3760                    break;
3761                case 0xcc: /* fitoq */
3762                    CHECK_FPU_FEATURE(dc, FLOAT128);
3763                    gen_ne_fop_QF(dc, rd, rs2, gen_helper_fitoq);
3764                    break;
3765                case 0xcd: /* fstoq */
3766                    CHECK_FPU_FEATURE(dc, FLOAT128);
3767                    gen_ne_fop_QF(dc, rd, rs2, gen_helper_fstoq);
3768                    break;
3769                case 0xce: /* fdtoq */
3770                    CHECK_FPU_FEATURE(dc, FLOAT128);
3771                    gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
3772                    break;
3773                case 0xd1: /* fstoi */
3774                    gen_fop_FF(dc, rd, rs2, gen_helper_fstoi);
3775                    break;
3776                case 0xd2: /* fdtoi */
3777                    gen_fop_FD(dc, rd, rs2, gen_helper_fdtoi);
3778                    break;
3779                case 0xd3: /* fqtoi */
3780                    CHECK_FPU_FEATURE(dc, FLOAT128);
3781                    gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi);
3782                    break;
3783#ifdef TARGET_SPARC64
3784                case 0x2: /* V9 fmovd */
3785                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
3786                    gen_store_fpr_D(dc, rd, cpu_src1_64);
3787                    break;
3788                case 0x3: /* V9 fmovq */
3789                    CHECK_FPU_FEATURE(dc, FLOAT128);
3790                    gen_move_Q(dc, rd, rs2);
3791                    break;
3792                case 0x6: /* V9 fnegd */
3793                    gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd);
3794                    break;
3795                case 0x7: /* V9 fnegq */
3796                    CHECK_FPU_FEATURE(dc, FLOAT128);
3797                    gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fnegq);
3798                    break;
3799                case 0xa: /* V9 fabsd */
3800                    gen_ne_fop_DD(dc, rd, rs2, gen_helper_fabsd);
3801                    break;
3802                case 0xb: /* V9 fabsq */
3803                    CHECK_FPU_FEATURE(dc, FLOAT128);
3804                    gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
3805                    break;
3806                case 0x81: /* V9 fstox */
3807                    gen_fop_DF(dc, rd, rs2, gen_helper_fstox);
3808                    break;
3809                case 0x82: /* V9 fdtox */
3810                    gen_fop_DD(dc, rd, rs2, gen_helper_fdtox);
3811                    break;
3812                case 0x83: /* V9 fqtox */
3813                    CHECK_FPU_FEATURE(dc, FLOAT128);
3814                    gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
3815                    break;
3816                case 0x84: /* V9 fxtos */
3817                    gen_fop_FD(dc, rd, rs2, gen_helper_fxtos);
3818                    break;
3819                case 0x88: /* V9 fxtod */
3820                    gen_fop_DD(dc, rd, rs2, gen_helper_fxtod);
3821                    break;
3822                case 0x8c: /* V9 fxtoq */
3823                    CHECK_FPU_FEATURE(dc, FLOAT128);
3824                    gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
3825                    break;
3826#endif
3827                default:
3828                    goto illegal_insn;
3829                }
3830            } else if (xop == 0x35) {   /* FPU Operations */
3831#ifdef TARGET_SPARC64
3832                int cond;
3833#endif
3834                if (gen_trap_ifnofpu(dc)) {
3835                    goto jmp_insn;
3836                }
3837                gen_op_clear_ieee_excp_and_FTT();
3838                rs1 = GET_FIELD(insn, 13, 17);
3839                rs2 = GET_FIELD(insn, 27, 31);
3840                xop = GET_FIELD(insn, 18, 26);
3841
3842#ifdef TARGET_SPARC64
3843#define FMOVR(sz)                                                  \
3844                do {                                               \
3845                    DisasCompare cmp;                              \
3846                    cond = GET_FIELD_SP(insn, 10, 12);             \
3847                    cpu_src1 = get_src1(dc, insn);                 \
3848                    gen_compare_reg(&cmp, cond, cpu_src1);         \
3849                    gen_fmov##sz(dc, &cmp, rd, rs2);               \
3850                    free_compare(&cmp);                            \
3851                } while (0)
3852
3853                if ((xop & 0x11f) == 0x005) { /* V9 fmovsr */
3854                    FMOVR(s);
3855                    break;
3856                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
3857                    FMOVR(d);
3858                    break;
3859                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
3860                    CHECK_FPU_FEATURE(dc, FLOAT128);
3861                    FMOVR(q);
3862                    break;
3863                }
3864#undef FMOVR
3865#endif
3866                switch (xop) {
3867#ifdef TARGET_SPARC64
3868#define FMOVCC(fcc, sz)                                                 \
3869                    do {                                                \
3870                        DisasCompare cmp;                               \
3871                        cond = GET_FIELD_SP(insn, 14, 17);              \
3872                        gen_fcompare(&cmp, fcc, cond);                  \
3873                        gen_fmov##sz(dc, &cmp, rd, rs2);                \
3874                        free_compare(&cmp);                             \
3875                    } while (0)
3876
3877                    case 0x001: /* V9 fmovscc %fcc0 */
3878                        FMOVCC(0, s);
3879                        break;
3880                    case 0x002: /* V9 fmovdcc %fcc0 */
3881                        FMOVCC(0, d);
3882                        break;
3883                    case 0x003: /* V9 fmovqcc %fcc0 */
3884                        CHECK_FPU_FEATURE(dc, FLOAT128);
3885                        FMOVCC(0, q);
3886                        break;
3887                    case 0x041: /* V9 fmovscc %fcc1 */
3888                        FMOVCC(1, s);
3889                        break;
3890                    case 0x042: /* V9 fmovdcc %fcc1 */
3891                        FMOVCC(1, d);
3892                        break;
3893                    case 0x043: /* V9 fmovqcc %fcc1 */
3894                        CHECK_FPU_FEATURE(dc, FLOAT128);
3895                        FMOVCC(1, q);
3896                        break;
3897                    case 0x081: /* V9 fmovscc %fcc2 */
3898                        FMOVCC(2, s);
3899                        break;
3900                    case 0x082: /* V9 fmovdcc %fcc2 */
3901                        FMOVCC(2, d);
3902                        break;
3903                    case 0x083: /* V9 fmovqcc %fcc2 */
3904                        CHECK_FPU_FEATURE(dc, FLOAT128);
3905                        FMOVCC(2, q);
3906                        break;
3907                    case 0x0c1: /* V9 fmovscc %fcc3 */
3908                        FMOVCC(3, s);
3909                        break;
3910                    case 0x0c2: /* V9 fmovdcc %fcc3 */
3911                        FMOVCC(3, d);
3912                        break;
3913                    case 0x0c3: /* V9 fmovqcc %fcc3 */
3914                        CHECK_FPU_FEATURE(dc, FLOAT128);
3915                        FMOVCC(3, q);
3916                        break;
3917#undef FMOVCC
3918#define FMOVCC(xcc, sz)                                                 \
3919                    do {                                                \
3920                        DisasCompare cmp;                               \
3921                        cond = GET_FIELD_SP(insn, 14, 17);              \
3922                        gen_compare(&cmp, xcc, cond, dc);               \
3923                        gen_fmov##sz(dc, &cmp, rd, rs2);                \
3924                        free_compare(&cmp);                             \
3925                    } while (0)
3926
3927                    case 0x101: /* V9 fmovscc %icc */
3928                        FMOVCC(0, s);
3929                        break;
3930                    case 0x102: /* V9 fmovdcc %icc */
3931                        FMOVCC(0, d);
3932                        break;
3933                    case 0x103: /* V9 fmovqcc %icc */
3934                        CHECK_FPU_FEATURE(dc, FLOAT128);
3935                        FMOVCC(0, q);
3936                        break;
3937                    case 0x181: /* V9 fmovscc %xcc */
3938                        FMOVCC(1, s);
3939                        break;
3940                    case 0x182: /* V9 fmovdcc %xcc */
3941                        FMOVCC(1, d);
3942                        break;
3943                    case 0x183: /* V9 fmovqcc %xcc */
3944                        CHECK_FPU_FEATURE(dc, FLOAT128);
3945                        FMOVCC(1, q);
3946                        break;
3947#undef FMOVCC
3948#endif
3949                    case 0x51: /* fcmps, V9 %fcc */
3950                        cpu_src1_32 = gen_load_fpr_F(dc, rs1);
3951                        cpu_src2_32 = gen_load_fpr_F(dc, rs2);
3952                        gen_op_fcmps(rd & 3, cpu_src1_32, cpu_src2_32);
3953                        break;
3954                    case 0x52: /* fcmpd, V9 %fcc */
3955                        cpu_src1_64 = gen_load_fpr_D(dc, rs1);
3956                        cpu_src2_64 = gen_load_fpr_D(dc, rs2);
3957                        gen_op_fcmpd(rd & 3, cpu_src1_64, cpu_src2_64);
3958                        break;
3959                    case 0x53: /* fcmpq, V9 %fcc */
3960                        CHECK_FPU_FEATURE(dc, FLOAT128);
3961                        gen_op_load_fpr_QT0(QFPREG(rs1));
3962                        gen_op_load_fpr_QT1(QFPREG(rs2));
3963                        gen_op_fcmpq(rd & 3);
3964                        break;
3965                    case 0x55: /* fcmpes, V9 %fcc */
3966                        cpu_src1_32 = gen_load_fpr_F(dc, rs1);
3967                        cpu_src2_32 = gen_load_fpr_F(dc, rs2);
3968                        gen_op_fcmpes(rd & 3, cpu_src1_32, cpu_src2_32);
3969                        break;
3970                    case 0x56: /* fcmped, V9 %fcc */
3971                        cpu_src1_64 = gen_load_fpr_D(dc, rs1);
3972                        cpu_src2_64 = gen_load_fpr_D(dc, rs2);
3973                        gen_op_fcmped(rd & 3, cpu_src1_64, cpu_src2_64);
3974                        break;
3975                    case 0x57: /* fcmpeq, V9 %fcc */
3976                        CHECK_FPU_FEATURE(dc, FLOAT128);
3977                        gen_op_load_fpr_QT0(QFPREG(rs1));
3978                        gen_op_load_fpr_QT1(QFPREG(rs2));
3979                        gen_op_fcmpeq(rd & 3);
3980                        break;
3981                    default:
3982                        goto illegal_insn;
3983                }
3984            } else if (xop == 0x2) {
3985                TCGv dst = gen_dest_gpr(dc, rd);
3986                rs1 = GET_FIELD(insn, 13, 17);
3987                if (rs1 == 0) {
3988                    /* clr/mov shortcut : or %g0, x, y -> mov x, y */
3989                    if (IS_IMM) {       /* immediate */
3990                        simm = GET_FIELDs(insn, 19, 31);
3991                        tcg_gen_movi_tl(dst, simm);
3992                        gen_store_gpr(dc, rd, dst);
3993                    } else {            /* register */
3994                        rs2 = GET_FIELD(insn, 27, 31);
3995                        if (rs2 == 0) {
3996                            tcg_gen_movi_tl(dst, 0);
3997                            gen_store_gpr(dc, rd, dst);
3998                        } else {
3999                            cpu_src2 = gen_load_gpr(dc, rs2);
4000                            gen_store_gpr(dc, rd, cpu_src2);
4001                        }
4002                    }
4003                } else {
4004                    cpu_src1 = get_src1(dc, insn);
4005                    if (IS_IMM) {       /* immediate */
4006                        simm = GET_FIELDs(insn, 19, 31);
4007                        tcg_gen_ori_tl(dst, cpu_src1, simm);
4008                        gen_store_gpr(dc, rd, dst);
4009                    } else {            /* register */
4010                        rs2 = GET_FIELD(insn, 27, 31);
4011                        if (rs2 == 0) {
4012                            /* mov shortcut:  or x, %g0, y -> mov x, y */
4013                            gen_store_gpr(dc, rd, cpu_src1);
4014                        } else {
4015                            cpu_src2 = gen_load_gpr(dc, rs2);
4016                            tcg_gen_or_tl(dst, cpu_src1, cpu_src2);
4017                            gen_store_gpr(dc, rd, dst);
4018                        }
4019                    }
4020                }
4021#ifdef TARGET_SPARC64
4022            } else if (xop == 0x25) { /* sll, V9 sllx */
4023                cpu_src1 = get_src1(dc, insn);
4024                if (IS_IMM) {   /* immediate */
4025                    simm = GET_FIELDs(insn, 20, 31);
4026                    if (insn & (1 << 12)) {
4027                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
4028                    } else {
4029                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
4030                    }
4031                } else {                /* register */
4032                    rs2 = GET_FIELD(insn, 27, 31);
4033                    cpu_src2 = gen_load_gpr(dc, rs2);
4034                    cpu_tmp0 = get_temp_tl(dc);
4035                    if (insn & (1 << 12)) {
4036                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
4037                    } else {
4038                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
4039                    }
4040                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
4041                }
4042                gen_store_gpr(dc, rd, cpu_dst);
4043            } else if (xop == 0x26) { /* srl, V9 srlx */
4044                cpu_src1 = get_src1(dc, insn);
4045                if (IS_IMM) {   /* immediate */
4046                    simm = GET_FIELDs(insn, 20, 31);
4047                    if (insn & (1 << 12)) {
4048                        tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
4049                    } else {
4050                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
4051                        tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
4052                    }
4053                } else {                /* register */
4054                    rs2 = GET_FIELD(insn, 27, 31);
4055                    cpu_src2 = gen_load_gpr(dc, rs2);
4056                    cpu_tmp0 = get_temp_tl(dc);
4057                    if (insn & (1 << 12)) {
4058                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
4059                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
4060                    } else {
4061                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
4062                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
4063                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
4064                    }
4065                }
4066                gen_store_gpr(dc, rd, cpu_dst);
4067            } else if (xop == 0x27) { /* sra, V9 srax */
4068                cpu_src1 = get_src1(dc, insn);
4069                if (IS_IMM) {   /* immediate */
4070                    simm = GET_FIELDs(insn, 20, 31);
4071                    if (insn & (1 << 12)) {
4072                        tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
4073                    } else {
4074                        tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
4075                        tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
4076                    }
4077                } else {                /* register */
4078                    rs2 = GET_FIELD(insn, 27, 31);
4079                    cpu_src2 = gen_load_gpr(dc, rs2);
4080                    cpu_tmp0 = get_temp_tl(dc);
4081                    if (insn & (1 << 12)) {
4082                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
4083                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
4084                    } else {
4085                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
4086                        tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
4087                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
4088                    }
4089                }
4090                gen_store_gpr(dc, rd, cpu_dst);
4091#endif
4092            } else if (xop < 0x36) {
4093                if (xop < 0x20) {
4094                    cpu_src1 = get_src1(dc, insn);
4095                    cpu_src2 = get_src2(dc, insn);
4096                    switch (xop & ~0x10) {
4097                    case 0x0: /* add */
4098                        if (xop & 0x10) {
4099                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
4100                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
4101                            dc->cc_op = CC_OP_ADD;
4102                        } else {
4103                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4104                        }
4105                        break;
4106                    case 0x1: /* and */
4107                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
4108                        if (xop & 0x10) {
4109                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4110                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4111                            dc->cc_op = CC_OP_LOGIC;
4112                        }
4113                        break;
4114                    case 0x2: /* or */
4115                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
4116                        if (xop & 0x10) {
4117                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4118                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4119                            dc->cc_op = CC_OP_LOGIC;
4120                        }
4121                        break;
4122                    case 0x3: /* xor */
4123                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
4124                        if (xop & 0x10) {
4125                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4126                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4127                            dc->cc_op = CC_OP_LOGIC;
4128                        }
4129                        break;
4130                    case 0x4: /* sub */
4131                        if (xop & 0x10) {
4132                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
4133                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
4134                            dc->cc_op = CC_OP_SUB;
4135                        } else {
4136                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
4137                        }
4138                        break;
4139                    case 0x5: /* andn */
4140                        tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
4141                        if (xop & 0x10) {
4142                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4143                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4144                            dc->cc_op = CC_OP_LOGIC;
4145                        }
4146                        break;
4147                    case 0x6: /* orn */
4148                        tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
4149                        if (xop & 0x10) {
4150                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4151                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4152                            dc->cc_op = CC_OP_LOGIC;
4153                        }
4154                        break;
4155                    case 0x7: /* xorn */
4156                        tcg_gen_eqv_tl(cpu_dst, cpu_src1, cpu_src2);
4157                        if (xop & 0x10) {
4158                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4159                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4160                            dc->cc_op = CC_OP_LOGIC;
4161                        }
4162                        break;
4163                    case 0x8: /* addx, V9 addc */
4164                        gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
4165                                        (xop & 0x10));
4166                        break;
4167#ifdef TARGET_SPARC64
4168                    case 0x9: /* V9 mulx */
4169                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
4170                        break;
4171#endif
4172                    case 0xa: /* umul */
4173                        CHECK_IU_FEATURE(dc, MUL);
4174                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
4175                        if (xop & 0x10) {
4176                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4177                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4178                            dc->cc_op = CC_OP_LOGIC;
4179                        }
4180                        break;
4181                    case 0xb: /* smul */
4182                        CHECK_IU_FEATURE(dc, MUL);
4183                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
4184                        if (xop & 0x10) {
4185                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4186                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4187                            dc->cc_op = CC_OP_LOGIC;
4188                        }
4189                        break;
4190                    case 0xc: /* subx, V9 subc */
4191                        gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
4192                                        (xop & 0x10));
4193                        break;
4194#ifdef TARGET_SPARC64
4195                    case 0xd: /* V9 udivx */
4196                        gen_helper_udivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
4197                        break;
4198#endif
4199                    case 0xe: /* udiv */
4200                        CHECK_IU_FEATURE(dc, DIV);
4201                        if (xop & 0x10) {
4202                            gen_helper_udiv_cc(cpu_dst, cpu_env, cpu_src1,
4203                                               cpu_src2);
4204                            dc->cc_op = CC_OP_DIV;
4205                        } else {
4206                            gen_helper_udiv(cpu_dst, cpu_env, cpu_src1,
4207                                            cpu_src2);
4208                        }
4209                        break;
4210                    case 0xf: /* sdiv */
4211                        CHECK_IU_FEATURE(dc, DIV);
4212                        if (xop & 0x10) {
4213                            gen_helper_sdiv_cc(cpu_dst, cpu_env, cpu_src1,
4214                                               cpu_src2);
4215                            dc->cc_op = CC_OP_DIV;
4216                        } else {
4217                            gen_helper_sdiv(cpu_dst, cpu_env, cpu_src1,
4218                                            cpu_src2);
4219                        }
4220                        break;
4221                    default:
4222                        goto illegal_insn;
4223                    }
4224                    gen_store_gpr(dc, rd, cpu_dst);
4225                } else {
4226                    cpu_src1 = get_src1(dc, insn);
4227                    cpu_src2 = get_src2(dc, insn);
4228                    switch (xop) {
4229                    case 0x20: /* taddcc */
4230                        gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
4231                        gen_store_gpr(dc, rd, cpu_dst);
4232                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
4233                        dc->cc_op = CC_OP_TADD;
4234                        break;
4235                    case 0x21: /* tsubcc */
4236                        gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
4237                        gen_store_gpr(dc, rd, cpu_dst);
4238                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
4239                        dc->cc_op = CC_OP_TSUB;
4240                        break;
4241                    case 0x22: /* taddcctv */
4242                        gen_helper_taddcctv(cpu_dst, cpu_env,
4243                                            cpu_src1, cpu_src2);
4244                        gen_store_gpr(dc, rd, cpu_dst);
4245                        dc->cc_op = CC_OP_TADDTV;
4246                        break;
4247                    case 0x23: /* tsubcctv */
4248                        gen_helper_tsubcctv(cpu_dst, cpu_env,
4249                                            cpu_src1, cpu_src2);
4250                        gen_store_gpr(dc, rd, cpu_dst);
4251                        dc->cc_op = CC_OP_TSUBTV;
4252                        break;
4253                    case 0x24: /* mulscc */
4254                        update_psr(dc);
4255                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
4256                        gen_store_gpr(dc, rd, cpu_dst);
4257                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
4258                        dc->cc_op = CC_OP_ADD;
4259                        break;
4260#ifndef TARGET_SPARC64
4261                    case 0x25:  /* sll */
4262                        if (IS_IMM) { /* immediate */
4263                            simm = GET_FIELDs(insn, 20, 31);
4264                            tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
4265                        } else { /* register */
4266                            cpu_tmp0 = get_temp_tl(dc);
4267                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
4268                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
4269                        }
4270                        gen_store_gpr(dc, rd, cpu_dst);
4271                        break;
4272                    case 0x26:  /* srl */
4273                        if (IS_IMM) { /* immediate */
4274                            simm = GET_FIELDs(insn, 20, 31);
4275                            tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
4276                        } else { /* register */
4277                            cpu_tmp0 = get_temp_tl(dc);
4278                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
4279                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
4280                        }
4281                        gen_store_gpr(dc, rd, cpu_dst);
4282                        break;
4283                    case 0x27:  /* sra */
4284                        if (IS_IMM) { /* immediate */
4285                            simm = GET_FIELDs(insn, 20, 31);
4286                            tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
4287                        } else { /* register */
4288                            cpu_tmp0 = get_temp_tl(dc);
4289                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
4290                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
4291                        }
4292                        gen_store_gpr(dc, rd, cpu_dst);
4293                        break;
4294#endif
4295                    case 0x30:
4296                        {
4297                            cpu_tmp0 = get_temp_tl(dc);
4298                            switch(rd) {
4299                            case 0: /* wry */
4300                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4301                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
4302                                break;
4303#ifndef TARGET_SPARC64
4304                            case 0x01 ... 0x0f: /* undefined in the
4305                                                   SPARCv8 manual, nop
4306                                                   on the microSPARC
4307                                                   II */
4308                            case 0x10 ... 0x1f: /* implementation-dependent
4309                                                   in the SPARCv8
4310                                                   manual, nop on the
4311                                                   microSPARC II */
4312                                if ((rd == 0x13) && (dc->def->features &
4313                                                     CPU_FEATURE_POWERDOWN)) {
4314                                    /* LEON3 power-down */
4315                                    save_state(dc);
4316                                    gen_helper_power_down(cpu_env);
4317                                }
4318                                break;
4319#else
4320                            case 0x2: /* V9 wrccr */
4321                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4322                                gen_helper_wrccr(cpu_env, cpu_tmp0);
4323                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
4324                                dc->cc_op = CC_OP_FLAGS;
4325                                break;
4326                            case 0x3: /* V9 wrasi */
4327                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4328                                tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
4329                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4330                                                offsetof(CPUSPARCState, asi));
4331                                /* End TB to notice changed ASI.  */
4332                                save_state(dc);
4333                                gen_op_next_insn();
4334                                tcg_gen_exit_tb(0);
4335                                dc->is_br = 1;
4336                                break;
4337                            case 0x6: /* V9 wrfprs */
4338                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4339                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0);
4340                                dc->fprs_dirty = 0;
4341                                save_state(dc);
4342                                gen_op_next_insn();
4343                                tcg_gen_exit_tb(0);
4344                                dc->is_br = 1;
4345                                break;
4346                            case 0xf: /* V9 sir, nop if user */
4347#if !defined(CONFIG_USER_ONLY)
4348                                if (supervisor(dc)) {
4349                                    ; // XXX
4350                                }
4351#endif
4352                                break;
4353                            case 0x13: /* Graphics Status */
4354                                if (gen_trap_ifnofpu(dc)) {
4355                                    goto jmp_insn;
4356                                }
4357                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
4358                                break;
4359                            case 0x14: /* Softint set */
4360                                if (!supervisor(dc))
4361                                    goto illegal_insn;
4362                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4363                                gen_helper_set_softint(cpu_env, cpu_tmp0);
4364                                break;
4365                            case 0x15: /* Softint clear */
4366                                if (!supervisor(dc))
4367                                    goto illegal_insn;
4368                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4369                                gen_helper_clear_softint(cpu_env, cpu_tmp0);
4370                                break;
4371                            case 0x16: /* Softint write */
4372                                if (!supervisor(dc))
4373                                    goto illegal_insn;
4374                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4375                                gen_helper_write_softint(cpu_env, cpu_tmp0);
4376                                break;
4377                            case 0x17: /* Tick compare */
4378#if !defined(CONFIG_USER_ONLY)
4379                                if (!supervisor(dc))
4380                                    goto illegal_insn;
4381#endif
4382                                {
4383                                    TCGv_ptr r_tickptr;
4384
4385                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
4386                                                   cpu_src2);
4387                                    r_tickptr = tcg_temp_new_ptr();
4388                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
4389                                                   offsetof(CPUSPARCState, tick));
4390                                    gen_helper_tick_set_limit(r_tickptr,
4391                                                              cpu_tick_cmpr);
4392                                    tcg_temp_free_ptr(r_tickptr);
4393                                }
4394                                break;
4395                            case 0x18: /* System tick */
4396#if !defined(CONFIG_USER_ONLY)
4397                                if (!supervisor(dc))
4398                                    goto illegal_insn;
4399#endif
4400                                {
4401                                    TCGv_ptr r_tickptr;
4402
4403                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
4404                                                   cpu_src2);
4405                                    r_tickptr = tcg_temp_new_ptr();
4406                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
4407                                                   offsetof(CPUSPARCState, stick));
4408                                    gen_helper_tick_set_count(r_tickptr,
4409                                                              cpu_tmp0);
4410                                    tcg_temp_free_ptr(r_tickptr);
4411                                }
4412                                break;
4413                            case 0x19: /* System tick compare */
4414#if !defined(CONFIG_USER_ONLY)
4415                                if (!supervisor(dc))
4416                                    goto illegal_insn;
4417#endif
4418                                {
4419                                    TCGv_ptr r_tickptr;
4420
4421                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
4422                                                   cpu_src2);
4423                                    r_tickptr = tcg_temp_new_ptr();
4424                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
4425                                                   offsetof(CPUSPARCState, stick));
4426                                    gen_helper_tick_set_limit(r_tickptr,
4427                                                              cpu_stick_cmpr);
4428                                    tcg_temp_free_ptr(r_tickptr);
4429                                }
4430                                break;
4431
4432                            case 0x10: /* Performance Control */
4433                            case 0x11: /* Performance Instrumentation
4434                                          Counter */
4435                            case 0x12: /* Dispatch Control */
4436#endif
4437                            default:
4438                                goto illegal_insn;
4439                            }
4440                        }
4441                        break;
4442#if !defined(CONFIG_USER_ONLY)
4443                    case 0x31: /* wrpsr, V9 saved, restored */
4444                        {
4445                            if (!supervisor(dc))
4446                                goto priv_insn;
4447#ifdef TARGET_SPARC64
4448                            switch (rd) {
4449                            case 0:
4450                                gen_helper_saved(cpu_env);
4451                                break;
4452                            case 1:
4453                                gen_helper_restored(cpu_env);
4454                                break;
4455                            case 2: /* UA2005 allclean */
4456                            case 3: /* UA2005 otherw */
4457                            case 4: /* UA2005 normalw */
4458                            case 5: /* UA2005 invalw */
4459                                // XXX
4460                            default:
4461                                goto illegal_insn;
4462                            }
4463#else
4464                            cpu_tmp0 = get_temp_tl(dc);
4465                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4466                            gen_helper_wrpsr(cpu_env, cpu_tmp0);
4467                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
4468                            dc->cc_op = CC_OP_FLAGS;
4469                            save_state(dc);
4470                            gen_op_next_insn();
4471                            tcg_gen_exit_tb(0);
4472                            dc->is_br = 1;
4473#endif
4474                        }
4475                        break;
4476                    case 0x32: /* wrwim, V9 wrpr */
4477                        {
4478                            if (!supervisor(dc))
4479                                goto priv_insn;
4480                            cpu_tmp0 = get_temp_tl(dc);
4481                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4482#ifdef TARGET_SPARC64
4483                            switch (rd) {
4484                            case 0: // tpc
4485                                {
4486                                    TCGv_ptr r_tsptr;
4487
4488                                    r_tsptr = tcg_temp_new_ptr();
4489                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4490                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
4491                                                  offsetof(trap_state, tpc));
4492                                    tcg_temp_free_ptr(r_tsptr);
4493                                }
4494                                break;
4495                            case 1: // tnpc
4496                                {
4497                                    TCGv_ptr r_tsptr;
4498
4499                                    r_tsptr = tcg_temp_new_ptr();
4500                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4501                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
4502                                                  offsetof(trap_state, tnpc));
4503                                    tcg_temp_free_ptr(r_tsptr);
4504                                }
4505                                break;
4506                            case 2: // tstate
4507                                {
4508                                    TCGv_ptr r_tsptr;
4509
4510                                    r_tsptr = tcg_temp_new_ptr();
4511                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4512                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
4513                                                  offsetof(trap_state,
4514                                                           tstate));
4515                                    tcg_temp_free_ptr(r_tsptr);
4516                                }
4517                                break;
4518                            case 3: // tt
4519                                {
4520                                    TCGv_ptr r_tsptr;
4521
4522                                    r_tsptr = tcg_temp_new_ptr();
4523                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4524                                    tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
4525                                                    offsetof(trap_state, tt));
4526                                    tcg_temp_free_ptr(r_tsptr);
4527                                }
4528                                break;
4529                            case 4: // tick
4530                                {
4531                                    TCGv_ptr r_tickptr;
4532
4533                                    r_tickptr = tcg_temp_new_ptr();
4534                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
4535                                                   offsetof(CPUSPARCState, tick));
4536                                    gen_helper_tick_set_count(r_tickptr,
4537                                                              cpu_tmp0);
4538                                    tcg_temp_free_ptr(r_tickptr);
4539                                }
4540                                break;
4541                            case 5: // tba
4542                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
4543                                break;
4544                            case 6: // pstate
4545                                save_state(dc);
4546                                gen_helper_wrpstate(cpu_env, cpu_tmp0);
4547                                dc->npc = DYNAMIC_PC;
4548                                break;
4549                            case 7: // tl
4550                                save_state(dc);
4551                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4552                                               offsetof(CPUSPARCState, tl));
4553                                dc->npc = DYNAMIC_PC;
4554                                break;
4555                            case 8: // pil
4556                                gen_helper_wrpil(cpu_env, cpu_tmp0);
4557                                break;
4558                            case 9: // cwp
4559                                gen_helper_wrcwp(cpu_env, cpu_tmp0);
4560                                break;
4561                            case 10: // cansave
4562                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4563                                                offsetof(CPUSPARCState,
4564                                                         cansave));
4565                                break;
4566                            case 11: // canrestore
4567                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4568                                                offsetof(CPUSPARCState,
4569                                                         canrestore));
4570                                break;
4571                            case 12: // cleanwin
4572                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4573                                                offsetof(CPUSPARCState,
4574                                                         cleanwin));
4575                                break;
4576                            case 13: // otherwin
4577                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4578                                                offsetof(CPUSPARCState,
4579                                                         otherwin));
4580                                break;
4581                            case 14: // wstate
4582                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4583                                                offsetof(CPUSPARCState,
4584                                                         wstate));
4585                                break;
4586                            case 16: // UA2005 gl
4587                                CHECK_IU_FEATURE(dc, GL);
4588                                gen_helper_wrgl(cpu_env, cpu_tmp0);
4589                                break;
4590                            case 26: // UA2005 strand status
4591                                CHECK_IU_FEATURE(dc, HYPV);
4592                                if (!hypervisor(dc))
4593                                    goto priv_insn;
4594                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
4595                                break;
4596                            default:
4597                                goto illegal_insn;
4598                            }
4599#else
4600                            tcg_gen_trunc_tl_i32(cpu_wim, cpu_tmp0);
4601                            if (dc->def->nwindows != 32) {
4602                                tcg_gen_andi_tl(cpu_wim, cpu_wim,
4603                                                (1 << dc->def->nwindows) - 1);
4604                            }
4605#endif
4606                        }
4607                        break;
4608                    case 0x33: /* wrtbr, UA2005 wrhpr */
4609                        {
4610#ifndef TARGET_SPARC64
4611                            if (!supervisor(dc))
4612                                goto priv_insn;
4613                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
4614#else
4615                            CHECK_IU_FEATURE(dc, HYPV);
4616                            if (!hypervisor(dc))
4617                                goto priv_insn;
4618                            cpu_tmp0 = get_temp_tl(dc);
4619                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4620                            switch (rd) {
4621                            case 0: // hpstate
4622                                tcg_gen_st_i64(cpu_tmp0, cpu_env,
4623                                               offsetof(CPUSPARCState,
4624                                                        hpstate));
4625                                save_state(dc);
4626                                gen_op_next_insn();
4627                                tcg_gen_exit_tb(0);
4628                                dc->is_br = 1;
4629                                break;
4630                            case 1: // htstate
4631                                // XXX gen_op_wrhtstate();
4632                                break;
4633                            case 3: // hintp
4634                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
4635                                break;
4636                            case 5: // htba
4637                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
4638                                break;
4639                            case 31: // hstick_cmpr
4640                                {
4641                                    TCGv_ptr r_tickptr;
4642
4643                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
4644                                    r_tickptr = tcg_temp_new_ptr();
4645                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
4646                                                   offsetof(CPUSPARCState, hstick));
4647                                    gen_helper_tick_set_limit(r_tickptr,
4648                                                              cpu_hstick_cmpr);
4649                                    tcg_temp_free_ptr(r_tickptr);
4650                                }
4651                                break;
4652                            case 6: // hver readonly
4653                            default:
4654                                goto illegal_insn;
4655                            }
4656#endif
4657                        }
4658                        break;
4659#endif
4660#ifdef TARGET_SPARC64
4661                    case 0x2c: /* V9 movcc */
4662                        {
4663                            int cc = GET_FIELD_SP(insn, 11, 12);
4664                            int cond = GET_FIELD_SP(insn, 14, 17);
4665                            DisasCompare cmp;
4666                            TCGv dst;
4667
4668                            if (insn & (1 << 18)) {
4669                                if (cc == 0) {
4670                                    gen_compare(&cmp, 0, cond, dc);
4671                                } else if (cc == 2) {
4672                                    gen_compare(&cmp, 1, cond, dc);
4673                                } else {
4674                                    goto illegal_insn;
4675                                }
4676                            } else {
4677                                gen_fcompare(&cmp, cc, cond);
4678                            }
4679
4680                            /* The get_src2 above loaded the normal 13-bit
4681                               immediate field, not the 11-bit field we have
4682                               in movcc.  But it did handle the reg case.  */
4683                            if (IS_IMM) {
4684                                simm = GET_FIELD_SPs(insn, 0, 10);
4685                                tcg_gen_movi_tl(cpu_src2, simm);
4686                            }
4687
4688                            dst = gen_load_gpr(dc, rd);
4689                            tcg_gen_movcond_tl(cmp.cond, dst,
4690                                               cmp.c1, cmp.c2,
4691                                               cpu_src2, dst);
4692                            free_compare(&cmp);
4693                            gen_store_gpr(dc, rd, dst);
4694                            break;
4695                        }
4696                    case 0x2d: /* V9 sdivx */
4697                        gen_helper_sdivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
4698                        gen_store_gpr(dc, rd, cpu_dst);
4699                        break;
4700                    case 0x2e: /* V9 popc */
4701                        tcg_gen_ctpop_tl(cpu_dst, cpu_src2);
4702                        gen_store_gpr(dc, rd, cpu_dst);
4703                        break;
4704                    case 0x2f: /* V9 movr */
4705                        {
4706                            int cond = GET_FIELD_SP(insn, 10, 12);
4707                            DisasCompare cmp;
4708                            TCGv dst;
4709
4710                            gen_compare_reg(&cmp, cond, cpu_src1);
4711
4712                            /* The get_src2 above loaded the normal 13-bit
4713                               immediate field, not the 10-bit field we have
4714                               in movr.  But it did handle the reg case.  */
4715                            if (IS_IMM) {
4716                                simm = GET_FIELD_SPs(insn, 0, 9);
4717                                tcg_gen_movi_tl(cpu_src2, simm);
4718                            }
4719
4720                            dst = gen_load_gpr(dc, rd);
4721                            tcg_gen_movcond_tl(cmp.cond, dst,
4722                                               cmp.c1, cmp.c2,
4723                                               cpu_src2, dst);
4724                            free_compare(&cmp);
4725                            gen_store_gpr(dc, rd, dst);
4726                            break;
4727                        }
4728#endif
4729                    default:
4730                        goto illegal_insn;
4731                    }
4732                }
4733            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
4734#ifdef TARGET_SPARC64
4735                int opf = GET_FIELD_SP(insn, 5, 13);
4736                rs1 = GET_FIELD(insn, 13, 17);
4737                rs2 = GET_FIELD(insn, 27, 31);
4738                if (gen_trap_ifnofpu(dc)) {
4739                    goto jmp_insn;
4740                }
4741
4742                switch (opf) {
4743                case 0x000: /* VIS I edge8cc */
4744                    CHECK_FPU_FEATURE(dc, VIS1);
4745                    cpu_src1 = gen_load_gpr(dc, rs1);
4746                    cpu_src2 = gen_load_gpr(dc, rs2);
4747                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0);
4748                    gen_store_gpr(dc, rd, cpu_dst);
4749                    break;
4750                case 0x001: /* VIS II edge8n */
4751                    CHECK_FPU_FEATURE(dc, VIS2);
4752                    cpu_src1 = gen_load_gpr(dc, rs1);
4753                    cpu_src2 = gen_load_gpr(dc, rs2);
4754                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0);
4755                    gen_store_gpr(dc, rd, cpu_dst);
4756                    break;
4757                case 0x002: /* VIS I edge8lcc */
4758                    CHECK_FPU_FEATURE(dc, VIS1);
4759                    cpu_src1 = gen_load_gpr(dc, rs1);
4760                    cpu_src2 = gen_load_gpr(dc, rs2);
4761                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1);
4762                    gen_store_gpr(dc, rd, cpu_dst);
4763                    break;
4764                case 0x003: /* VIS II edge8ln */
4765                    CHECK_FPU_FEATURE(dc, VIS2);
4766                    cpu_src1 = gen_load_gpr(dc, rs1);
4767                    cpu_src2 = gen_load_gpr(dc, rs2);
4768                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1);
4769                    gen_store_gpr(dc, rd, cpu_dst);
4770                    break;
4771                case 0x004: /* VIS I edge16cc */
4772                    CHECK_FPU_FEATURE(dc, VIS1);
4773                    cpu_src1 = gen_load_gpr(dc, rs1);
4774                    cpu_src2 = gen_load_gpr(dc, rs2);
4775                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0);
4776                    gen_store_gpr(dc, rd, cpu_dst);
4777                    break;
4778                case 0x005: /* VIS II edge16n */
4779                    CHECK_FPU_FEATURE(dc, VIS2);
4780                    cpu_src1 = gen_load_gpr(dc, rs1);
4781                    cpu_src2 = gen_load_gpr(dc, rs2);
4782                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0);
4783                    gen_store_gpr(dc, rd, cpu_dst);
4784                    break;
4785                case 0x006: /* VIS I edge16lcc */
4786                    CHECK_FPU_FEATURE(dc, VIS1);
4787                    cpu_src1 = gen_load_gpr(dc, rs1);
4788                    cpu_src2 = gen_load_gpr(dc, rs2);
4789                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1);
4790                    gen_store_gpr(dc, rd, cpu_dst);
4791                    break;
4792                case 0x007: /* VIS II edge16ln */
4793                    CHECK_FPU_FEATURE(dc, VIS2);
4794                    cpu_src1 = gen_load_gpr(dc, rs1);
4795                    cpu_src2 = gen_load_gpr(dc, rs2);
4796                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1);
4797                    gen_store_gpr(dc, rd, cpu_dst);
4798                    break;
4799                case 0x008: /* VIS I edge32cc */
4800                    CHECK_FPU_FEATURE(dc, VIS1);
4801                    cpu_src1 = gen_load_gpr(dc, rs1);
4802                    cpu_src2 = gen_load_gpr(dc, rs2);
4803                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0);
4804                    gen_store_gpr(dc, rd, cpu_dst);
4805                    break;
4806                case 0x009: /* VIS II edge32n */
4807                    CHECK_FPU_FEATURE(dc, VIS2);
4808                    cpu_src1 = gen_load_gpr(dc, rs1);
4809                    cpu_src2 = gen_load_gpr(dc, rs2);
4810                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0);
4811                    gen_store_gpr(dc, rd, cpu_dst);
4812                    break;
4813                case 0x00a: /* VIS I edge32lcc */
4814                    CHECK_FPU_FEATURE(dc, VIS1);
4815                    cpu_src1 = gen_load_gpr(dc, rs1);
4816                    cpu_src2 = gen_load_gpr(dc, rs2);
4817                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1);
4818                    gen_store_gpr(dc, rd, cpu_dst);
4819                    break;
4820                case 0x00b: /* VIS II edge32ln */
4821                    CHECK_FPU_FEATURE(dc, VIS2);
4822                    cpu_src1 = gen_load_gpr(dc, rs1);
4823                    cpu_src2 = gen_load_gpr(dc, rs2);
4824                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1);
4825                    gen_store_gpr(dc, rd, cpu_dst);
4826                    break;
4827                case 0x010: /* VIS I array8 */
4828                    CHECK_FPU_FEATURE(dc, VIS1);
4829                    cpu_src1 = gen_load_gpr(dc, rs1);
4830                    cpu_src2 = gen_load_gpr(dc, rs2);
4831                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
4832                    gen_store_gpr(dc, rd, cpu_dst);
4833                    break;
4834                case 0x012: /* VIS I array16 */
4835                    CHECK_FPU_FEATURE(dc, VIS1);
4836                    cpu_src1 = gen_load_gpr(dc, rs1);
4837                    cpu_src2 = gen_load_gpr(dc, rs2);
4838                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
4839                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
4840                    gen_store_gpr(dc, rd, cpu_dst);
4841                    break;
4842                case 0x014: /* VIS I array32 */
4843                    CHECK_FPU_FEATURE(dc, VIS1);
4844                    cpu_src1 = gen_load_gpr(dc, rs1);
4845                    cpu_src2 = gen_load_gpr(dc, rs2);
4846                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
4847                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
4848                    gen_store_gpr(dc, rd, cpu_dst);
4849                    break;
4850                case 0x018: /* VIS I alignaddr */
4851                    CHECK_FPU_FEATURE(dc, VIS1);
4852                    cpu_src1 = gen_load_gpr(dc, rs1);
4853                    cpu_src2 = gen_load_gpr(dc, rs2);
4854                    gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 0);
4855                    gen_store_gpr(dc, rd, cpu_dst);
4856                    break;
4857                case 0x01a: /* VIS I alignaddrl */
4858                    CHECK_FPU_FEATURE(dc, VIS1);
4859                    cpu_src1 = gen_load_gpr(dc, rs1);
4860                    cpu_src2 = gen_load_gpr(dc, rs2);
4861                    gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 1);
4862                    gen_store_gpr(dc, rd, cpu_dst);
4863                    break;
4864                case 0x019: /* VIS II bmask */
4865                    CHECK_FPU_FEATURE(dc, VIS2);
4866                    cpu_src1 = gen_load_gpr(dc, rs1);
4867                    cpu_src2 = gen_load_gpr(dc, rs2);
4868                    tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4869                    tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, cpu_dst, 32, 32);
4870                    gen_store_gpr(dc, rd, cpu_dst);
4871                    break;
4872                case 0x020: /* VIS I fcmple16 */
4873                    CHECK_FPU_FEATURE(dc, VIS1);
4874                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4875                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4876                    gen_helper_fcmple16(cpu_dst, cpu_src1_64, cpu_src2_64);
4877                    gen_store_gpr(dc, rd, cpu_dst);
4878                    break;
4879                case 0x022: /* VIS I fcmpne16 */
4880                    CHECK_FPU_FEATURE(dc, VIS1);
4881                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4882                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4883                    gen_helper_fcmpne16(cpu_dst, cpu_src1_64, cpu_src2_64);
4884                    gen_store_gpr(dc, rd, cpu_dst);
4885                    break;
4886                case 0x024: /* VIS I fcmple32 */
4887                    CHECK_FPU_FEATURE(dc, VIS1);
4888                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4889                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4890                    gen_helper_fcmple32(cpu_dst, cpu_src1_64, cpu_src2_64);
4891                    gen_store_gpr(dc, rd, cpu_dst);
4892                    break;
4893                case 0x026: /* VIS I fcmpne32 */
4894                    CHECK_FPU_FEATURE(dc, VIS1);
4895                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4896                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4897                    gen_helper_fcmpne32(cpu_dst, cpu_src1_64, cpu_src2_64);
4898                    gen_store_gpr(dc, rd, cpu_dst);
4899                    break;
4900                case 0x028: /* VIS I fcmpgt16 */
4901                    CHECK_FPU_FEATURE(dc, VIS1);
4902                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4903                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4904                    gen_helper_fcmpgt16(cpu_dst, cpu_src1_64, cpu_src2_64);
4905                    gen_store_gpr(dc, rd, cpu_dst);
4906                    break;
4907                case 0x02a: /* VIS I fcmpeq16 */
4908                    CHECK_FPU_FEATURE(dc, VIS1);
4909                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4910                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4911                    gen_helper_fcmpeq16(cpu_dst, cpu_src1_64, cpu_src2_64);
4912                    gen_store_gpr(dc, rd, cpu_dst);
4913                    break;
4914                case 0x02c: /* VIS I fcmpgt32 */
4915                    CHECK_FPU_FEATURE(dc, VIS1);
4916                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4917                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4918                    gen_helper_fcmpgt32(cpu_dst, cpu_src1_64, cpu_src2_64);
4919                    gen_store_gpr(dc, rd, cpu_dst);
4920                    break;
4921                case 0x02e: /* VIS I fcmpeq32 */
4922                    CHECK_FPU_FEATURE(dc, VIS1);
4923                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4924                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4925                    gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64);
4926                    gen_store_gpr(dc, rd, cpu_dst);
4927                    break;
4928                case 0x031: /* VIS I fmul8x16 */
4929                    CHECK_FPU_FEATURE(dc, VIS1);
4930                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16);
4931                    break;
4932                case 0x033: /* VIS I fmul8x16au */
4933                    CHECK_FPU_FEATURE(dc, VIS1);
4934                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16au);
4935                    break;
4936                case 0x035: /* VIS I fmul8x16al */
4937                    CHECK_FPU_FEATURE(dc, VIS1);
4938                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16al);
4939                    break;
4940                case 0x036: /* VIS I fmul8sux16 */
4941                    CHECK_FPU_FEATURE(dc, VIS1);
4942                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8sux16);
4943                    break;
4944                case 0x037: /* VIS I fmul8ulx16 */
4945                    CHECK_FPU_FEATURE(dc, VIS1);
4946                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8ulx16);
4947                    break;
4948                case 0x038: /* VIS I fmuld8sux16 */
4949                    CHECK_FPU_FEATURE(dc, VIS1);
4950                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8sux16);
4951                    break;
4952                case 0x039: /* VIS I fmuld8ulx16 */
4953                    CHECK_FPU_FEATURE(dc, VIS1);
4954                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8ulx16);
4955                    break;
4956                case 0x03a: /* VIS I fpack32 */
4957                    CHECK_FPU_FEATURE(dc, VIS1);
4958                    gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpack32);
4959                    break;
4960                case 0x03b: /* VIS I fpack16 */
4961                    CHECK_FPU_FEATURE(dc, VIS1);
4962                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
4963                    cpu_dst_32 = gen_dest_fpr_F(dc);
4964                    gen_helper_fpack16(cpu_dst_32, cpu_gsr, cpu_src1_64);
4965                    gen_store_fpr_F(dc, rd, cpu_dst_32);
4966                    break;
4967                case 0x03d: /* VIS I fpackfix */
4968                    CHECK_FPU_FEATURE(dc, VIS1);
4969                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
4970                    cpu_dst_32 = gen_dest_fpr_F(dc);
4971                    gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64);
4972                    gen_store_fpr_F(dc, rd, cpu_dst_32);
4973                    break;
4974                case 0x03e: /* VIS I pdist */
4975                    CHECK_FPU_FEATURE(dc, VIS1);
4976                    gen_ne_fop_DDDD(dc, rd, rs1, rs2, gen_helper_pdist);
4977                    break;
4978                case 0x048: /* VIS I faligndata */
4979                    CHECK_FPU_FEATURE(dc, VIS1);
4980                    gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata);
4981                    break;
4982                case 0x04b: /* VIS I fpmerge */
4983                    CHECK_FPU_FEATURE(dc, VIS1);
4984                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpmerge);
4985                    break;
4986                case 0x04c: /* VIS II bshuffle */
4987                    CHECK_FPU_FEATURE(dc, VIS2);
4988                    gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_bshuffle);
4989                    break;
4990                case 0x04d: /* VIS I fexpand */
4991                    CHECK_FPU_FEATURE(dc, VIS1);
4992                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fexpand);
4993                    break;
4994                case 0x050: /* VIS I fpadd16 */
4995                    CHECK_FPU_FEATURE(dc, VIS1);
4996                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd16);
4997                    break;
4998                case 0x051: /* VIS I fpadd16s */
4999                    CHECK_FPU_FEATURE(dc, VIS1);
5000                    gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpadd16s);
5001                    break;
5002                case 0x052: /* VIS I fpadd32 */
5003                    CHECK_FPU_FEATURE(dc, VIS1);
5004                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd32);
5005                    break;
5006                case 0x053: /* VIS I fpadd32s */
5007                    CHECK_FPU_FEATURE(dc, VIS1);
5008                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_add_i32);
5009                    break;
5010                case 0x054: /* VIS I fpsub16 */
5011                    CHECK_FPU_FEATURE(dc, VIS1);
5012                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub16);
5013                    break;
5014                case 0x055: /* VIS I fpsub16s */
5015                    CHECK_FPU_FEATURE(dc, VIS1);
5016                    gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpsub16s);
5017                    break;
5018                case 0x056: /* VIS I fpsub32 */
5019                    CHECK_FPU_FEATURE(dc, VIS1);
5020                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub32);
5021                    break;
5022                case 0x057: /* VIS I fpsub32s */
5023                    CHECK_FPU_FEATURE(dc, VIS1);
5024                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_sub_i32);
5025                    break;
5026                case 0x060: /* VIS I fzero */
5027                    CHECK_FPU_FEATURE(dc, VIS1);
5028                    cpu_dst_64 = gen_dest_fpr_D(dc, rd);
5029                    tcg_gen_movi_i64(cpu_dst_64, 0);
5030                    gen_store_fpr_D(dc, rd, cpu_dst_64);
5031                    break;
5032                case 0x061: /* VIS I fzeros */
5033                    CHECK_FPU_FEATURE(dc, VIS1);
5034                    cpu_dst_32 = gen_dest_fpr_F(dc);
5035                    tcg_gen_movi_i32(cpu_dst_32, 0);
5036                    gen_store_fpr_F(dc, rd, cpu_dst_32);
5037                    break;
5038                case 0x062: /* VIS I fnor */
5039                    CHECK_FPU_FEATURE(dc, VIS1);
5040                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nor_i64);
5041                    break;
5042                case 0x063: /* VIS I fnors */
5043                    CHECK_FPU_FEATURE(dc, VIS1);
5044                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nor_i32);
5045                    break;
5046                case 0x064: /* VIS I fandnot2 */
5047                    CHECK_FPU_FEATURE(dc, VIS1);
5048                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_andc_i64);
5049                    break;
5050                case 0x065: /* VIS I fandnot2s */
5051                    CHECK_FPU_FEATURE(dc, VIS1);
5052                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_andc_i32);
5053                    break;
5054                case 0x066: /* VIS I fnot2 */
5055                    CHECK_FPU_FEATURE(dc, VIS1);
5056                    gen_ne_fop_DD(dc, rd, rs2, tcg_gen_not_i64);
5057                    break;
5058                case 0x067: /* VIS I fnot2s */
5059                    CHECK_FPU_FEATURE(dc, VIS1);
5060                    gen_ne_fop_FF(dc, rd, rs2, tcg_gen_not_i32);
5061                    break;
5062                case 0x068: /* VIS I fandnot1 */
5063                    CHECK_FPU_FEATURE(dc, VIS1);
5064                    gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
5065                    break;
5066                case 0x069: /* VIS I fandnot1s */
5067                    CHECK_FPU_FEATURE(dc, VIS1);
5068                    gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_andc_i32);
5069                    break;
5070                case 0x06a: /* VIS I fnot1 */
5071                    CHECK_FPU_FEATURE(dc, VIS1);
5072                    gen_ne_fop_DD(dc, rd, rs1, tcg_gen_not_i64);
5073                    break;
5074                case 0x06b: /* VIS I fnot1s */
5075                    CHECK_FPU_FEATURE(dc, VIS1);
5076                    gen_ne_fop_FF(dc, rd, rs1, tcg_gen_not_i32);
5077                    break;
5078                case 0x06c: /* VIS I fxor */
5079                    CHECK_FPU_FEATURE(dc, VIS1);
5080                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
5081                    break;
5082                case 0x06d: /* VIS I fxors */
5083                    CHECK_FPU_FEATURE(dc, VIS1);
5084                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_xor_i32);
5085                    break;
5086                case 0x06e: /* VIS I fnand */
5087                    CHECK_FPU_FEATURE(dc, VIS1);
5088                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nand_i64);
5089                    break;
5090                case 0x06f: /* VIS I fnands */
5091                    CHECK_FPU_FEATURE(dc, VIS1);
5092                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nand_i32);
5093                    break;
5094                case 0x070: /* VIS I fand */
5095                    CHECK_FPU_FEATURE(dc, VIS1);
5096                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_and_i64);
5097                    break;
5098                case 0x071: /* VIS I fands */
5099                    CHECK_FPU_FEATURE(dc, VIS1);
5100                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_and_i32);
5101                    break;
5102                case 0x072: /* VIS I fxnor */
5103                    CHECK_FPU_FEATURE(dc, VIS1);
5104                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_eqv_i64);
5105                    break;
5106                case 0x073: /* VIS I fxnors */
5107                    CHECK_FPU_FEATURE(dc, VIS1);
5108                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_eqv_i32);
5109                    break;
5110                case 0x074: /* VIS I fsrc1 */
5111                    CHECK_FPU_FEATURE(dc, VIS1);
5112                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
5113                    gen_store_fpr_D(dc, rd, cpu_src1_64);
5114                    break;
5115                case 0x075: /* VIS I fsrc1s */
5116                    CHECK_FPU_FEATURE(dc, VIS1);
5117                    cpu_src1_32 = gen_load_fpr_F(dc, rs1);
5118                    gen_store_fpr_F(dc, rd, cpu_src1_32);
5119                    break;
5120                case 0x076: /* VIS I fornot2 */
5121                    CHECK_FPU_FEATURE(dc, VIS1);
5122                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64);
5123                    break;
5124                case 0x077: /* VIS I fornot2s */
5125                    CHECK_FPU_FEATURE(dc, VIS1);
5126                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_orc_i32);
5127                    break;
5128                case 0x078: /* VIS I fsrc2 */
5129                    CHECK_FPU_FEATURE(dc, VIS1);
5130                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
5131                    gen_store_fpr_D(dc, rd, cpu_src1_64);
5132                    break;
5133                case 0x079: /* VIS I fsrc2s */
5134                    CHECK_FPU_FEATURE(dc, VIS1);
5135                    cpu_src1_32 = gen_load_fpr_F(dc, rs2);
5136                    gen_store_fpr_F(dc, rd, cpu_src1_32);
5137                    break;
5138                case 0x07a: /* VIS I fornot1 */
5139                    CHECK_FPU_FEATURE(dc, VIS1);
5140                    gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
5141                    break;
5142                case 0x07b: /* VIS I fornot1s */
5143                    CHECK_FPU_FEATURE(dc, VIS1);
5144                    gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_orc_i32);
5145                    break;
5146                case 0x07c: /* VIS I for */
5147                    CHECK_FPU_FEATURE(dc, VIS1);
5148                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_or_i64);
5149                    break;
5150                case 0x07d: /* VIS I fors */
5151                    CHECK_FPU_FEATURE(dc, VIS1);
5152                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_or_i32);
5153                    break;
5154                case 0x07e: /* VIS I fone */
5155                    CHECK_FPU_FEATURE(dc, VIS1);
5156                    cpu_dst_64 = gen_dest_fpr_D(dc, rd);
5157                    tcg_gen_movi_i64(cpu_dst_64, -1);
5158                    gen_store_fpr_D(dc, rd, cpu_dst_64);
5159                    break;
5160                case 0x07f: /* VIS I fones */
5161                    CHECK_FPU_FEATURE(dc, VIS1);
5162                    cpu_dst_32 = gen_dest_fpr_F(dc);
5163                    tcg_gen_movi_i32(cpu_dst_32, -1);
5164                    gen_store_fpr_F(dc, rd, cpu_dst_32);
5165                    break;
5166                case 0x080: /* VIS I shutdown */
5167                case 0x081: /* VIS II siam */
5168                    // XXX
5169                    goto illegal_insn;
5170                default:
5171                    goto illegal_insn;
5172                }
5173#else
5174                goto ncp_insn;
5175#endif
5176            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
5177#ifdef TARGET_SPARC64
5178                goto illegal_insn;
5179#else
5180                goto ncp_insn;
5181#endif
5182#ifdef TARGET_SPARC64
5183            } else if (xop == 0x39) { /* V9 return */
5184                save_state(dc);
5185                cpu_src1 = get_src1(dc, insn);
5186                cpu_tmp0 = get_temp_tl(dc);
5187                if (IS_IMM) {   /* immediate */
5188                    simm = GET_FIELDs(insn, 19, 31);
5189                    tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
5190                } else {                /* register */
5191                    rs2 = GET_FIELD(insn, 27, 31);
5192                    if (rs2) {
5193                        cpu_src2 = gen_load_gpr(dc, rs2);
5194                        tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
5195                    } else {
5196                        tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
5197                    }
5198                }
5199                gen_helper_restore(cpu_env);
5200                gen_mov_pc_npc(dc);
5201                gen_check_align(cpu_tmp0, 3);
5202                tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
5203                dc->npc = DYNAMIC_PC;
5204                goto jmp_insn;
5205#endif
5206            } else {
5207                cpu_src1 = get_src1(dc, insn);
5208                cpu_tmp0 = get_temp_tl(dc);
5209                if (IS_IMM) {   /* immediate */
5210                    simm = GET_FIELDs(insn, 19, 31);
5211                    tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
5212                } else {                /* register */
5213                    rs2 = GET_FIELD(insn, 27, 31);
5214                    if (rs2) {
5215                        cpu_src2 = gen_load_gpr(dc, rs2);
5216                        tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
5217                    } else {
5218                        tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
5219                    }
5220                }
5221                switch (xop) {
5222                case 0x38:      /* jmpl */
5223                    {
5224                        TCGv t = gen_dest_gpr(dc, rd);
5225                        tcg_gen_movi_tl(t, dc->pc);
5226                        gen_store_gpr(dc, rd, t);
5227
5228                        gen_mov_pc_npc(dc);
5229                        gen_check_align(cpu_tmp0, 3);
5230                        gen_address_mask(dc, cpu_tmp0);
5231                        tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
5232                        dc->npc = DYNAMIC_PC;
5233                    }
5234                    goto jmp_insn;
5235#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
5236                case 0x39:      /* rett, V9 return */
5237                    {
5238                        if (!supervisor(dc))
5239                            goto priv_insn;
5240                        gen_mov_pc_npc(dc);
5241                        gen_check_align(cpu_tmp0, 3);
5242                        tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
5243                        dc->npc = DYNAMIC_PC;
5244                        gen_helper_rett(cpu_env);
5245                    }
5246                    goto jmp_insn;
5247#endif
5248                case 0x3b: /* flush */
5249                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
5250                        goto unimp_flush;
5251                    /* nop */
5252                    break;
5253                case 0x3c:      /* save */
5254                    gen_helper_save(cpu_env);
5255                    gen_store_gpr(dc, rd, cpu_tmp0);
5256                    break;
5257                case 0x3d:      /* restore */
5258                    gen_helper_restore(cpu_env);
5259                    gen_store_gpr(dc, rd, cpu_tmp0);
5260                    break;
5261#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
5262                case 0x3e:      /* V9 done/retry */
5263                    {
5264                        switch (rd) {
5265                        case 0:
5266                            if (!supervisor(dc))
5267                                goto priv_insn;
5268                            dc->npc = DYNAMIC_PC;
5269                            dc->pc = DYNAMIC_PC;
5270                            gen_helper_done(cpu_env);
5271                            goto jmp_insn;
5272                        case 1:
5273                            if (!supervisor(dc))
5274                                goto priv_insn;
5275                            dc->npc = DYNAMIC_PC;
5276                            dc->pc = DYNAMIC_PC;
5277                            gen_helper_retry(cpu_env);
5278                            goto jmp_insn;
5279                        default:
5280                            goto illegal_insn;
5281                        }
5282                    }
5283                    break;
5284#endif
5285                default:
5286                    goto illegal_insn;
5287                }
5288            }
5289            break;
5290        }
5291        break;
5292    case 3:                     /* load/store instructions */
5293        {
5294            unsigned int xop = GET_FIELD(insn, 7, 12);
5295            /* ??? gen_address_mask prevents us from using a source
5296               register directly.  Always generate a temporary.  */
5297            TCGv cpu_addr = get_temp_tl(dc);
5298
5299            tcg_gen_mov_tl(cpu_addr, get_src1(dc, insn));
5300            if (xop == 0x3c || xop == 0x3e) {
5301                /* V9 casa/casxa : no offset */
5302            } else if (IS_IMM) {     /* immediate */
5303                simm = GET_FIELDs(insn, 19, 31);
5304                if (simm != 0) {
5305                    tcg_gen_addi_tl(cpu_addr, cpu_addr, simm);
5306                }
5307            } else {            /* register */
5308                rs2 = GET_FIELD(insn, 27, 31);
5309                if (rs2 != 0) {
5310                    tcg_gen_add_tl(cpu_addr, cpu_addr, gen_load_gpr(dc, rs2));
5311                }
5312            }
5313            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
5314                (xop > 0x17 && xop <= 0x1d ) ||
5315                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
5316                TCGv cpu_val = gen_dest_gpr(dc, rd);
5317
5318                switch (xop) {
5319                case 0x0:       /* ld, V9 lduw, load unsigned word */
5320                    gen_address_mask(dc, cpu_addr);
5321                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
5322                    break;
5323                case 0x1:       /* ldub, load unsigned byte */
5324                    gen_address_mask(dc, cpu_addr);
5325                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
5326                    break;
5327                case 0x2:       /* lduh, load unsigned halfword */
5328                    gen_address_mask(dc, cpu_addr);
5329                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
5330                    break;
5331                case 0x3:       /* ldd, load double word */
5332                    if (rd & 1)
5333                        goto illegal_insn;
5334                    else {
5335                        TCGv_i64 t64;
5336
5337                        gen_address_mask(dc, cpu_addr);
5338                        t64 = tcg_temp_new_i64();
5339                        tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
5340                        tcg_gen_trunc_i64_tl(cpu_val, t64);
5341                        tcg_gen_ext32u_tl(cpu_val, cpu_val);
5342                        gen_store_gpr(dc, rd + 1, cpu_val);
5343                        tcg_gen_shri_i64(t64, t64, 32);
5344                        tcg_gen_trunc_i64_tl(cpu_val, t64);
5345                        tcg_temp_free_i64(t64);
5346                        tcg_gen_ext32u_tl(cpu_val, cpu_val);
5347                    }
5348                    break;
5349                case 0x9:       /* ldsb, load signed byte */
5350                    gen_address_mask(dc, cpu_addr);
5351                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
5352                    break;
5353                case 0xa:       /* ldsh, load signed halfword */
5354                    gen_address_mask(dc, cpu_addr);
5355                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
5356                    break;
5357                case 0xd:       /* ldstub */
5358                    gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
5359                    break;
5360                case 0x0f:
5361                    /* swap, swap register with memory. Also atomically */
5362                    CHECK_IU_FEATURE(dc, SWAP);
5363                    cpu_src1 = gen_load_gpr(dc, rd);
5364                    gen_swap(dc, cpu_val, cpu_src1, cpu_addr,
5365                             dc->mem_idx, MO_TEUL);
5366                    break;
5367#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5368                case 0x10:      /* lda, V9 lduwa, load word alternate */
5369                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
5370                    break;
5371                case 0x11:      /* lduba, load unsigned byte alternate */
5372                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
5373                    break;
5374                case 0x12:      /* lduha, load unsigned halfword alternate */
5375                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
5376                    break;
5377                case 0x13:      /* ldda, load double word alternate */
5378                    if (rd & 1) {
5379                        goto illegal_insn;
5380                    }
5381                    gen_ldda_asi(dc, cpu_addr, insn, rd);
5382                    goto skip_move;
5383                case 0x19:      /* ldsba, load signed byte alternate */
5384                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
5385                    break;
5386                case 0x1a:      /* ldsha, load signed halfword alternate */
5387                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
5388                    break;
5389                case 0x1d:      /* ldstuba -- XXX: should be atomically */
5390                    gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
5391                    break;
5392                case 0x1f:      /* swapa, swap reg with alt. memory. Also
5393                                   atomically */
5394                    CHECK_IU_FEATURE(dc, SWAP);
5395                    cpu_src1 = gen_load_gpr(dc, rd);
5396                    gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
5397                    break;
5398
5399#ifndef TARGET_SPARC64
5400                case 0x30: /* ldc */
5401                case 0x31: /* ldcsr */
5402                case 0x33: /* lddc */
5403                    goto ncp_insn;
5404#endif
5405#endif
5406#ifdef TARGET_SPARC64
5407                case 0x08: /* V9 ldsw */
5408                    gen_address_mask(dc, cpu_addr);
5409                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
5410                    break;
5411                case 0x0b: /* V9 ldx */
5412                    gen_address_mask(dc, cpu_addr);
5413                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
5414                    break;
5415                case 0x18: /* V9 ldswa */
5416                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
5417                    break;
5418                case 0x1b: /* V9 ldxa */
5419                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
5420                    break;
5421                case 0x2d: /* V9 prefetch, no effect */
5422                    goto skip_move;
5423                case 0x30: /* V9 ldfa */
5424                    if (gen_trap_ifnofpu(dc)) {
5425                        goto jmp_insn;
5426                    }
5427                    gen_ldf_asi(dc, cpu_addr, insn, 4, rd);
5428                    gen_update_fprs_dirty(dc, rd);
5429                    goto skip_move;
5430                case 0x33: /* V9 lddfa */
5431                    if (gen_trap_ifnofpu(dc)) {
5432                        goto jmp_insn;
5433                    }
5434                    gen_ldf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
5435                    gen_update_fprs_dirty(dc, DFPREG(rd));
5436                    goto skip_move;
5437                case 0x3d: /* V9 prefetcha, no effect */
5438                    goto skip_move;
5439                case 0x32: /* V9 ldqfa */
5440                    CHECK_FPU_FEATURE(dc, FLOAT128);
5441                    if (gen_trap_ifnofpu(dc)) {
5442                        goto jmp_insn;
5443                    }
5444                    gen_ldf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
5445                    gen_update_fprs_dirty(dc, QFPREG(rd));
5446                    goto skip_move;
5447#endif
5448                default:
5449                    goto illegal_insn;
5450                }
5451                gen_store_gpr(dc, rd, cpu_val);
5452#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5453            skip_move: ;
5454#endif
5455            } else if (xop >= 0x20 && xop < 0x24) {
5456                if (gen_trap_ifnofpu(dc)) {
5457                    goto jmp_insn;
5458                }
5459                switch (xop) {
5460                case 0x20:      /* ldf, load fpreg */
5461                    gen_address_mask(dc, cpu_addr);
5462                    cpu_dst_32 = gen_dest_fpr_F(dc);
5463                    tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
5464                                        dc->mem_idx, MO_TEUL);
5465                    gen_store_fpr_F(dc, rd, cpu_dst_32);
5466                    break;
5467                case 0x21:      /* ldfsr, V9 ldxfsr */
5468#ifdef TARGET_SPARC64
5469                    gen_address_mask(dc, cpu_addr);
5470                    if (rd == 1) {
5471                        TCGv_i64 t64 = tcg_temp_new_i64();
5472                        tcg_gen_qemu_ld_i64(t64, cpu_addr,
5473                                            dc->mem_idx, MO_TEQ);
5474                        gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64);
5475                        tcg_temp_free_i64(t64);
5476                        break;
5477                    }
5478#endif
5479                    cpu_dst_32 = get_temp_i32(dc);
5480                    tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
5481                                        dc->mem_idx, MO_TEUL);
5482                    gen_helper_ldfsr(cpu_fsr, cpu_env, cpu_fsr, cpu_dst_32);
5483                    break;
5484                case 0x22:      /* ldqf, load quad fpreg */
5485                    CHECK_FPU_FEATURE(dc, FLOAT128);
5486                    gen_address_mask(dc, cpu_addr);
5487                    cpu_src1_64 = tcg_temp_new_i64();
5488                    tcg_gen_qemu_ld_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
5489                                        MO_TEQ | MO_ALIGN_4);
5490                    tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
5491                    cpu_src2_64 = tcg_temp_new_i64();
5492                    tcg_gen_qemu_ld_i64(cpu_src2_64, cpu_addr, dc->mem_idx,
5493                                        MO_TEQ | MO_ALIGN_4);
5494                    gen_store_fpr_Q(dc, rd, cpu_src1_64, cpu_src2_64);
5495                    tcg_temp_free_i64(cpu_src1_64);
5496                    tcg_temp_free_i64(cpu_src2_64);
5497                    break;
5498                case 0x23:      /* lddf, load double fpreg */
5499                    gen_address_mask(dc, cpu_addr);
5500                    cpu_dst_64 = gen_dest_fpr_D(dc, rd);
5501                    tcg_gen_qemu_ld_i64(cpu_dst_64, cpu_addr, dc->mem_idx,
5502                                        MO_TEQ | MO_ALIGN_4);
5503                    gen_store_fpr_D(dc, rd, cpu_dst_64);
5504                    break;
5505                default:
5506                    goto illegal_insn;
5507                }
5508            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
5509                       xop == 0xe || xop == 0x1e) {
5510                TCGv cpu_val = gen_load_gpr(dc, rd);
5511
5512                switch (xop) {
5513                case 0x4: /* st, store word */
5514                    gen_address_mask(dc, cpu_addr);
5515                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
5516                    break;
5517                case 0x5: /* stb, store byte */
5518                    gen_address_mask(dc, cpu_addr);
5519                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
5520                    break;
5521                case 0x6: /* sth, store halfword */
5522                    gen_address_mask(dc, cpu_addr);
5523                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
5524                    break;
5525                case 0x7: /* std, store double word */
5526                    if (rd & 1)
5527                        goto illegal_insn;
5528                    else {
5529                        TCGv_i64 t64;
5530                        TCGv lo;
5531
5532                        gen_address_mask(dc, cpu_addr);
5533                        lo = gen_load_gpr(dc, rd + 1);
5534                        t64 = tcg_temp_new_i64();
5535                        tcg_gen_concat_tl_i64(t64, lo, cpu_val);
5536                        tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
5537                        tcg_temp_free_i64(t64);
5538                    }
5539                    break;
5540#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5541                case 0x14: /* sta, V9 stwa, store word alternate */
5542                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
5543                    break;
5544                case 0x15: /* stba, store byte alternate */
5545                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
5546                    break;
5547                case 0x16: /* stha, store halfword alternate */
5548                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
5549                    break;
5550                case 0x17: /* stda, store double word alternate */
5551                    if (rd & 1) {
5552                        goto illegal_insn;
5553                    }
5554                    gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
5555                    break;
5556#endif
5557#ifdef TARGET_SPARC64
5558                case 0x0e: /* V9 stx */
5559                    gen_address_mask(dc, cpu_addr);
5560                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
5561                    break;
5562                case 0x1e: /* V9 stxa */
5563                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
5564                    break;
5565#endif
5566                default:
5567                    goto illegal_insn;
5568                }
5569            } else if (xop > 0x23 && xop < 0x28) {
5570                if (gen_trap_ifnofpu(dc)) {
5571                    goto jmp_insn;
5572                }
5573                switch (xop) {
5574                case 0x24: /* stf, store fpreg */
5575                    gen_address_mask(dc, cpu_addr);
5576                    cpu_src1_32 = gen_load_fpr_F(dc, rd);
5577                    tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
5578                                        dc->mem_idx, MO_TEUL);
5579                    break;
5580                case 0x25: /* stfsr, V9 stxfsr */
5581                    {
5582#ifdef TARGET_SPARC64
5583                        gen_address_mask(dc, cpu_addr);
5584                        if (rd == 1) {
5585                            tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
5586                            break;
5587                        }
5588#endif
5589                        tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
5590                    }
5591                    break;
5592                case 0x26:
5593#ifdef TARGET_SPARC64
5594                    /* V9 stqf, store quad fpreg */
5595                    CHECK_FPU_FEATURE(dc, FLOAT128);
5596                    gen_address_mask(dc, cpu_addr);
5597                    /* ??? While stqf only requires 4-byte alignment, it is
5598                       legal for the cpu to signal the unaligned exception.
5599                       The OS trap handler is then required to fix it up.
5600                       For qemu, this avoids having to probe the second page
5601                       before performing the first write.  */
5602                    cpu_src1_64 = gen_load_fpr_Q0(dc, rd);
5603                    tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
5604                                        dc->mem_idx, MO_TEQ | MO_ALIGN_16);
5605                    tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
5606                    cpu_src2_64 = gen_load_fpr_Q1(dc, rd);
5607                    tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
5608                                        dc->mem_idx, MO_TEQ);
5609                    break;
5610#else /* !TARGET_SPARC64 */
5611                    /* stdfq, store floating point queue */
5612#if defined(CONFIG_USER_ONLY)
5613                    goto illegal_insn;
5614#else
5615                    if (!supervisor(dc))
5616                        goto priv_insn;
5617                    if (gen_trap_ifnofpu(dc)) {
5618                        goto jmp_insn;
5619                    }
5620                    goto nfq_insn;
5621#endif
5622#endif
5623                case 0x27: /* stdf, store double fpreg */
5624                    gen_address_mask(dc, cpu_addr);
5625                    cpu_src1_64 = gen_load_fpr_D(dc, rd);
5626                    tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
5627                                        MO_TEQ | MO_ALIGN_4);
5628                    break;
5629                default:
5630                    goto illegal_insn;
5631                }
5632            } else if (xop > 0x33 && xop < 0x3f) {
5633                switch (xop) {
5634#ifdef TARGET_SPARC64
5635                case 0x34: /* V9 stfa */
5636                    if (gen_trap_ifnofpu(dc)) {
5637                        goto jmp_insn;
5638                    }
5639                    gen_stf_asi(dc, cpu_addr, insn, 4, rd);
5640                    break;
5641                case 0x36: /* V9 stqfa */
5642                    {
5643                        CHECK_FPU_FEATURE(dc, FLOAT128);
5644                        if (gen_trap_ifnofpu(dc)) {
5645                            goto jmp_insn;
5646                        }
5647                        gen_stf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
5648                    }
5649                    break;
5650                case 0x37: /* V9 stdfa */
5651                    if (gen_trap_ifnofpu(dc)) {
5652                        goto jmp_insn;
5653                    }
5654                    gen_stf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
5655                    break;
5656                case 0x3e: /* V9 casxa */
5657                    rs2 = GET_FIELD(insn, 27, 31);
5658                    cpu_src2 = gen_load_gpr(dc, rs2);
5659                    gen_casx_asi(dc, cpu_addr, cpu_src2, insn, rd);
5660                    break;
5661#else
5662                case 0x34: /* stc */
5663                case 0x35: /* stcsr */
5664                case 0x36: /* stdcq */
5665                case 0x37: /* stdc */
5666                    goto ncp_insn;
5667#endif
5668#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5669                case 0x3c: /* V9 or LEON3 casa */
5670#ifndef TARGET_SPARC64
5671                    CHECK_IU_FEATURE(dc, CASA);
5672#endif
5673                    rs2 = GET_FIELD(insn, 27, 31);
5674                    cpu_src2 = gen_load_gpr(dc, rs2);
5675                    gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
5676                    break;
5677#endif
5678                default:
5679                    goto illegal_insn;
5680                }
5681            } else {
5682                goto illegal_insn;
5683            }
5684        }
5685        break;
5686    }
5687    /* default case for non jump instructions */
5688    if (dc->npc == DYNAMIC_PC) {
5689        dc->pc = DYNAMIC_PC;
5690        gen_op_next_insn();
5691    } else if (dc->npc == JUMP_PC) {
5692        /* we can do a static jump */
5693        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
5694        dc->is_br = 1;
5695    } else {
5696        dc->pc = dc->npc;
5697        dc->npc = dc->npc + 4;
5698    }
5699 jmp_insn:
5700    goto egress;
5701 illegal_insn:
5702    gen_exception(dc, TT_ILL_INSN);
5703    goto egress;
5704 unimp_flush:
5705    gen_exception(dc, TT_UNIMP_FLUSH);
5706    goto egress;
5707#if !defined(CONFIG_USER_ONLY)
5708 priv_insn:
5709    gen_exception(dc, TT_PRIV_INSN);
5710    goto egress;
5711#endif
5712 nfpu_insn:
5713    gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
5714    goto egress;
5715#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
5716 nfq_insn:
5717    gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
5718    goto egress;
5719#endif
5720#ifndef TARGET_SPARC64
5721 ncp_insn:
5722    gen_exception(dc, TT_NCP_INSN);
5723    goto egress;
5724#endif
5725 egress:
5726    if (dc->n_t32 != 0) {
5727        int i;
5728        for (i = dc->n_t32 - 1; i >= 0; --i) {
5729            tcg_temp_free_i32(dc->t32[i]);
5730        }
5731        dc->n_t32 = 0;
5732    }
5733    if (dc->n_ttl != 0) {
5734        int i;
5735        for (i = dc->n_ttl - 1; i >= 0; --i) {
5736            tcg_temp_free(dc->ttl[i]);
5737        }
5738        dc->n_ttl = 0;
5739    }
5740}
5741
5742void gen_intermediate_code(CPUState *cs, TranslationBlock * tb)
5743{
5744    CPUSPARCState *env = cs->env_ptr;
5745    target_ulong pc_start, last_pc;
5746    DisasContext dc1, *dc = &dc1;
5747    int num_insns;
5748    int max_insns;
5749    unsigned int insn;
5750
5751    memset(dc, 0, sizeof(DisasContext));
5752    dc->tb = tb;
5753    pc_start = tb->pc;
5754    dc->pc = pc_start;
5755    last_pc = dc->pc;
5756    dc->npc = (target_ulong) tb->cs_base;
5757    dc->cc_op = CC_OP_DYNAMIC;
5758    dc->mem_idx = tb->flags & TB_FLAG_MMU_MASK;
5759    dc->def = env->def;
5760    dc->fpu_enabled = tb_fpu_enabled(tb->flags);
5761    dc->address_mask_32bit = tb_am_enabled(tb->flags);
5762    dc->singlestep = (cs->singlestep_enabled || singlestep);
5763#ifndef CONFIG_USER_ONLY
5764    dc->supervisor = (tb->flags & TB_FLAG_SUPER) != 0;
5765#endif
5766#ifdef TARGET_SPARC64
5767    dc->fprs_dirty = 0;
5768    dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
5769#ifndef CONFIG_USER_ONLY
5770    dc->hypervisor = (tb->flags & TB_FLAG_HYPER) != 0;
5771#endif
5772#endif
5773
5774    num_insns = 0;
5775    max_insns = tb->cflags & CF_COUNT_MASK;
5776    if (max_insns == 0) {
5777        max_insns = CF_COUNT_MASK;
5778    }
5779    if (max_insns > TCG_MAX_INSNS) {
5780        max_insns = TCG_MAX_INSNS;
5781    }
5782
5783    gen_tb_start(tb);
5784    do {
5785        if (dc->npc & JUMP_PC) {
5786            assert(dc->jump_pc[1] == dc->pc + 4);
5787            tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC);
5788        } else {
5789            tcg_gen_insn_start(dc->pc, dc->npc);
5790        }
5791        num_insns++;
5792        last_pc = dc->pc;
5793
5794        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
5795            if (dc->pc != pc_start) {
5796                save_state(dc);
5797            }
5798            gen_helper_debug(cpu_env);
5799            tcg_gen_exit_tb(0);
5800            dc->is_br = 1;
5801            goto exit_gen_loop;
5802        }
5803
5804        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
5805            gen_io_start();
5806        }
5807
5808        insn = cpu_ldl_code(env, dc->pc);
5809
5810        disas_sparc_insn(dc, insn);
5811
5812        if (dc->is_br)
5813            break;
5814        /* if the next PC is different, we abort now */
5815        if (dc->pc != (last_pc + 4))
5816            break;
5817        /* if we reach a page boundary, we stop generation so that the
5818           PC of a TT_TFAULT exception is always in the right page */
5819        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
5820            break;
5821        /* if single step mode, we generate only one instruction and
5822           generate an exception */
5823        if (dc->singlestep) {
5824            break;
5825        }
5826    } while (!tcg_op_buf_full() &&
5827             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
5828             num_insns < max_insns);
5829
5830 exit_gen_loop:
5831    if (tb->cflags & CF_LAST_IO) {
5832        gen_io_end();
5833    }
5834    if (!dc->is_br) {
5835        if (dc->pc != DYNAMIC_PC &&
5836            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
5837            /* static PC and NPC: we can use direct chaining */
5838            gen_goto_tb(dc, 0, dc->pc, dc->npc);
5839        } else {
5840            if (dc->pc != DYNAMIC_PC) {
5841                tcg_gen_movi_tl(cpu_pc, dc->pc);
5842            }
5843            save_npc(dc);
5844            tcg_gen_exit_tb(0);
5845        }
5846    }
5847    gen_tb_end(tb, num_insns);
5848
5849    tb->size = last_pc + 4 - pc_start;
5850    tb->icount = num_insns;
5851
5852#ifdef DEBUG_DISAS
5853    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
5854        && qemu_log_in_addr_range(pc_start)) {
5855        qemu_log_lock();
5856        qemu_log("--------------\n");
5857        qemu_log("IN: %s\n", lookup_symbol(pc_start));
5858        log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0);
5859        qemu_log("\n");
5860        qemu_log_unlock();
5861    }
5862#endif
5863}
5864
5865void gen_intermediate_code_init(CPUSPARCState *env)
5866{
5867    static int inited;
5868    static const char gregnames[32][4] = {
5869        "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
5870        "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
5871        "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
5872        "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
5873    };
5874    static const char fregnames[32][4] = {
5875        "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
5876        "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30",
5877        "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
5878        "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
5879    };
5880
5881    static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
5882#ifdef TARGET_SPARC64
5883        { &cpu_xcc, offsetof(CPUSPARCState, xcc), "xcc" },
5884        { &cpu_fprs, offsetof(CPUSPARCState, fprs), "fprs" },
5885#else
5886        { &cpu_wim, offsetof(CPUSPARCState, wim), "wim" },
5887#endif
5888        { &cpu_cc_op, offsetof(CPUSPARCState, cc_op), "cc_op" },
5889        { &cpu_psr, offsetof(CPUSPARCState, psr), "psr" },
5890    };
5891
5892    static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
5893#ifdef TARGET_SPARC64
5894        { &cpu_gsr, offsetof(CPUSPARCState, gsr), "gsr" },
5895        { &cpu_tick_cmpr, offsetof(CPUSPARCState, tick_cmpr), "tick_cmpr" },
5896        { &cpu_stick_cmpr, offsetof(CPUSPARCState, stick_cmpr), "stick_cmpr" },
5897        { &cpu_hstick_cmpr, offsetof(CPUSPARCState, hstick_cmpr),
5898          "hstick_cmpr" },
5899        { &cpu_hintp, offsetof(CPUSPARCState, hintp), "hintp" },
5900        { &cpu_htba, offsetof(CPUSPARCState, htba), "htba" },
5901        { &cpu_hver, offsetof(CPUSPARCState, hver), "hver" },
5902        { &cpu_ssr, offsetof(CPUSPARCState, ssr), "ssr" },
5903        { &cpu_ver, offsetof(CPUSPARCState, version), "ver" },
5904#endif
5905        { &cpu_cond, offsetof(CPUSPARCState, cond), "cond" },
5906        { &cpu_cc_src, offsetof(CPUSPARCState, cc_src), "cc_src" },
5907        { &cpu_cc_src2, offsetof(CPUSPARCState, cc_src2), "cc_src2" },
5908        { &cpu_cc_dst, offsetof(CPUSPARCState, cc_dst), "cc_dst" },
5909        { &cpu_fsr, offsetof(CPUSPARCState, fsr), "fsr" },
5910        { &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
5911        { &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
5912        { &cpu_y, offsetof(CPUSPARCState, y), "y" },
5913#ifndef CONFIG_USER_ONLY
5914        { &cpu_tbr, offsetof(CPUSPARCState, tbr), "tbr" },
5915#endif
5916    };
5917
5918    unsigned int i;
5919
5920    /* init various static tables */
5921    if (inited) {
5922        return;
5923    }
5924    inited = 1;
5925
5926    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
5927    tcg_ctx.tcg_env = cpu_env;
5928
5929    cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
5930                                         offsetof(CPUSPARCState, regwptr),
5931                                         "regwptr");
5932
5933    for (i = 0; i < ARRAY_SIZE(r32); ++i) {
5934        *r32[i].ptr = tcg_global_mem_new_i32(cpu_env, r32[i].off, r32[i].name);
5935    }
5936
5937    for (i = 0; i < ARRAY_SIZE(rtl); ++i) {
5938        *rtl[i].ptr = tcg_global_mem_new(cpu_env, rtl[i].off, rtl[i].name);
5939    }
5940
5941    TCGV_UNUSED(cpu_regs[0]);
5942    for (i = 1; i < 8; ++i) {
5943        cpu_regs[i] = tcg_global_mem_new(cpu_env,
5944                                         offsetof(CPUSPARCState, gregs[i]),
5945                                         gregnames[i]);
5946    }
5947
5948    for (i = 8; i < 32; ++i) {
5949        cpu_regs[i] = tcg_global_mem_new(cpu_regwptr,
5950                                         (i - 8) * sizeof(target_ulong),
5951                                         gregnames[i]);
5952    }
5953
5954    for (i = 0; i < TARGET_DPREGS; i++) {
5955        cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
5956                                            offsetof(CPUSPARCState, fpr[i]),
5957                                            fregnames[i]);
5958    }
5959}
5960
5961void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb,
5962                          target_ulong *data)
5963{
5964    target_ulong pc = data[0];
5965    target_ulong npc = data[1];
5966
5967    env->pc = pc;
5968    if (npc == DYNAMIC_PC) {
5969        /* dynamic NPC: already stored */
5970    } else if (npc & JUMP_PC) {
5971        /* jump PC: use 'cond' and the jump targets of the translation */
5972        if (env->cond) {
5973            env->npc = npc & ~3;
5974        } else {
5975            env->npc = pc + 4;
5976        }
5977    } else {
5978        env->npc = npc;
5979    }
5980}
5981