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