qemu/tcg/sparc/tcg-target.inc.c
<<
>>
Prefs
   1/*
   2 * Tiny Code Generator for QEMU
   3 *
   4 * Copyright (c) 2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "tcg-be-null.h"
  26
  27#ifdef CONFIG_DEBUG_TCG
  28static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
  29    "%g0",
  30    "%g1",
  31    "%g2",
  32    "%g3",
  33    "%g4",
  34    "%g5",
  35    "%g6",
  36    "%g7",
  37    "%o0",
  38    "%o1",
  39    "%o2",
  40    "%o3",
  41    "%o4",
  42    "%o5",
  43    "%o6",
  44    "%o7",
  45    "%l0",
  46    "%l1",
  47    "%l2",
  48    "%l3",
  49    "%l4",
  50    "%l5",
  51    "%l6",
  52    "%l7",
  53    "%i0",
  54    "%i1",
  55    "%i2",
  56    "%i3",
  57    "%i4",
  58    "%i5",
  59    "%i6",
  60    "%i7",
  61};
  62#endif
  63
  64#ifdef __arch64__
  65# define SPARC64 1
  66#else
  67# define SPARC64 0
  68#endif
  69
  70/* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
  71   registers.  These are saved manually by the kernel in full 64-bit
  72   slots.  The %i and %l registers are saved by the register window
  73   mechanism, which only allocates space for 32 bits.  Given that this
  74   window spill/fill can happen on any signal, we must consider the
  75   high bits of the %i and %l registers garbage at all times.  */
  76#if SPARC64
  77# define ALL_64  0xffffffffu
  78#else
  79# define ALL_64  0xffffu
  80#endif
  81
  82/* Define some temporary registers.  T2 is used for constant generation.  */
  83#define TCG_REG_T1  TCG_REG_G1
  84#define TCG_REG_T2  TCG_REG_O7
  85
  86#ifndef CONFIG_SOFTMMU
  87# define TCG_GUEST_BASE_REG TCG_REG_I5
  88#endif
  89
  90static const int tcg_target_reg_alloc_order[] = {
  91    TCG_REG_L0,
  92    TCG_REG_L1,
  93    TCG_REG_L2,
  94    TCG_REG_L3,
  95    TCG_REG_L4,
  96    TCG_REG_L5,
  97    TCG_REG_L6,
  98    TCG_REG_L7,
  99
 100    TCG_REG_I0,
 101    TCG_REG_I1,
 102    TCG_REG_I2,
 103    TCG_REG_I3,
 104    TCG_REG_I4,
 105    TCG_REG_I5,
 106
 107    TCG_REG_G2,
 108    TCG_REG_G3,
 109    TCG_REG_G4,
 110    TCG_REG_G5,
 111
 112    TCG_REG_O0,
 113    TCG_REG_O1,
 114    TCG_REG_O2,
 115    TCG_REG_O3,
 116    TCG_REG_O4,
 117    TCG_REG_O5,
 118};
 119
 120static const int tcg_target_call_iarg_regs[6] = {
 121    TCG_REG_O0,
 122    TCG_REG_O1,
 123    TCG_REG_O2,
 124    TCG_REG_O3,
 125    TCG_REG_O4,
 126    TCG_REG_O5,
 127};
 128
 129static const int tcg_target_call_oarg_regs[] = {
 130    TCG_REG_O0,
 131    TCG_REG_O1,
 132    TCG_REG_O2,
 133    TCG_REG_O3,
 134};
 135
 136#define INSN_OP(x)  ((x) << 30)
 137#define INSN_OP2(x) ((x) << 22)
 138#define INSN_OP3(x) ((x) << 19)
 139#define INSN_OPF(x) ((x) << 5)
 140#define INSN_RD(x)  ((x) << 25)
 141#define INSN_RS1(x) ((x) << 14)
 142#define INSN_RS2(x) (x)
 143#define INSN_ASI(x) ((x) << 5)
 144
 145#define INSN_IMM10(x) ((1 << 13) | ((x) & 0x3ff))
 146#define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
 147#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
 148#define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20))
 149#define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
 150#define INSN_COND(x) ((x) << 25)
 151
 152#define COND_N     0x0
 153#define COND_E     0x1
 154#define COND_LE    0x2
 155#define COND_L     0x3
 156#define COND_LEU   0x4
 157#define COND_CS    0x5
 158#define COND_NEG   0x6
 159#define COND_VS    0x7
 160#define COND_A     0x8
 161#define COND_NE    0x9
 162#define COND_G     0xa
 163#define COND_GE    0xb
 164#define COND_GU    0xc
 165#define COND_CC    0xd
 166#define COND_POS   0xe
 167#define COND_VC    0xf
 168#define BA         (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
 169
 170#define RCOND_Z    1
 171#define RCOND_LEZ  2
 172#define RCOND_LZ   3
 173#define RCOND_NZ   5
 174#define RCOND_GZ   6
 175#define RCOND_GEZ  7
 176
 177#define MOVCC_ICC  (1 << 18)
 178#define MOVCC_XCC  (1 << 18 | 1 << 12)
 179
 180#define BPCC_ICC   0
 181#define BPCC_XCC   (2 << 20)
 182#define BPCC_PT    (1 << 19)
 183#define BPCC_PN    0
 184#define BPCC_A     (1 << 29)
 185
 186#define BPR_PT     BPCC_PT
 187
 188#define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
 189#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
 190#define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
 191#define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
 192#define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
 193#define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
 194#define ARITH_ORN  (INSN_OP(2) | INSN_OP3(0x06))
 195#define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
 196#define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
 197#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
 198#define ARITH_ADDC (INSN_OP(2) | INSN_OP3(0x08))
 199#define ARITH_SUBC (INSN_OP(2) | INSN_OP3(0x0c))
 200#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
 201#define ARITH_SMUL (INSN_OP(2) | INSN_OP3(0x0b))
 202#define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
 203#define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
 204#define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
 205#define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
 206#define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
 207#define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
 208#define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f))
 209
 210#define ARITH_ADDXC (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x11))
 211#define ARITH_UMULXHI (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x16))
 212
 213#define SHIFT_SLL  (INSN_OP(2) | INSN_OP3(0x25))
 214#define SHIFT_SRL  (INSN_OP(2) | INSN_OP3(0x26))
 215#define SHIFT_SRA  (INSN_OP(2) | INSN_OP3(0x27))
 216
 217#define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
 218#define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
 219#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
 220
 221#define RDY        (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
 222#define WRY        (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
 223#define JMPL       (INSN_OP(2) | INSN_OP3(0x38))
 224#define RETURN     (INSN_OP(2) | INSN_OP3(0x39))
 225#define SAVE       (INSN_OP(2) | INSN_OP3(0x3c))
 226#define RESTORE    (INSN_OP(2) | INSN_OP3(0x3d))
 227#define SETHI      (INSN_OP(0) | INSN_OP2(0x4))
 228#define CALL       INSN_OP(1)
 229#define LDUB       (INSN_OP(3) | INSN_OP3(0x01))
 230#define LDSB       (INSN_OP(3) | INSN_OP3(0x09))
 231#define LDUH       (INSN_OP(3) | INSN_OP3(0x02))
 232#define LDSH       (INSN_OP(3) | INSN_OP3(0x0a))
 233#define LDUW       (INSN_OP(3) | INSN_OP3(0x00))
 234#define LDSW       (INSN_OP(3) | INSN_OP3(0x08))
 235#define LDX        (INSN_OP(3) | INSN_OP3(0x0b))
 236#define STB        (INSN_OP(3) | INSN_OP3(0x05))
 237#define STH        (INSN_OP(3) | INSN_OP3(0x06))
 238#define STW        (INSN_OP(3) | INSN_OP3(0x04))
 239#define STX        (INSN_OP(3) | INSN_OP3(0x0e))
 240#define LDUBA      (INSN_OP(3) | INSN_OP3(0x11))
 241#define LDSBA      (INSN_OP(3) | INSN_OP3(0x19))
 242#define LDUHA      (INSN_OP(3) | INSN_OP3(0x12))
 243#define LDSHA      (INSN_OP(3) | INSN_OP3(0x1a))
 244#define LDUWA      (INSN_OP(3) | INSN_OP3(0x10))
 245#define LDSWA      (INSN_OP(3) | INSN_OP3(0x18))
 246#define LDXA       (INSN_OP(3) | INSN_OP3(0x1b))
 247#define STBA       (INSN_OP(3) | INSN_OP3(0x15))
 248#define STHA       (INSN_OP(3) | INSN_OP3(0x16))
 249#define STWA       (INSN_OP(3) | INSN_OP3(0x14))
 250#define STXA       (INSN_OP(3) | INSN_OP3(0x1e))
 251
 252#ifndef ASI_PRIMARY_LITTLE
 253#define ASI_PRIMARY_LITTLE 0x88
 254#endif
 255
 256#define LDUH_LE    (LDUHA | INSN_ASI(ASI_PRIMARY_LITTLE))
 257#define LDSH_LE    (LDSHA | INSN_ASI(ASI_PRIMARY_LITTLE))
 258#define LDUW_LE    (LDUWA | INSN_ASI(ASI_PRIMARY_LITTLE))
 259#define LDSW_LE    (LDSWA | INSN_ASI(ASI_PRIMARY_LITTLE))
 260#define LDX_LE     (LDXA  | INSN_ASI(ASI_PRIMARY_LITTLE))
 261
 262#define STH_LE     (STHA  | INSN_ASI(ASI_PRIMARY_LITTLE))
 263#define STW_LE     (STWA  | INSN_ASI(ASI_PRIMARY_LITTLE))
 264#define STX_LE     (STXA  | INSN_ASI(ASI_PRIMARY_LITTLE))
 265
 266#ifndef use_vis3_instructions
 267bool use_vis3_instructions;
 268#endif
 269
 270static inline int check_fit_i64(int64_t val, unsigned int bits)
 271{
 272    return val == sextract64(val, 0, bits);
 273}
 274
 275static inline int check_fit_i32(int32_t val, unsigned int bits)
 276{
 277    return val == sextract32(val, 0, bits);
 278}
 279
 280#define check_fit_tl    check_fit_i64
 281#if SPARC64
 282# define check_fit_ptr  check_fit_i64
 283#else
 284# define check_fit_ptr  check_fit_i32
 285#endif
 286
 287static void patch_reloc(tcg_insn_unit *code_ptr, int type,
 288                        intptr_t value, intptr_t addend)
 289{
 290    uint32_t insn;
 291
 292    tcg_debug_assert(addend == 0);
 293    value = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
 294
 295    switch (type) {
 296    case R_SPARC_WDISP16:
 297        if (!check_fit_ptr(value >> 2, 16)) {
 298            tcg_abort();
 299        }
 300        insn = *code_ptr;
 301        insn &= ~INSN_OFF16(-1);
 302        insn |= INSN_OFF16(value);
 303        *code_ptr = insn;
 304        break;
 305    case R_SPARC_WDISP19:
 306        if (!check_fit_ptr(value >> 2, 19)) {
 307            tcg_abort();
 308        }
 309        insn = *code_ptr;
 310        insn &= ~INSN_OFF19(-1);
 311        insn |= INSN_OFF19(value);
 312        *code_ptr = insn;
 313        break;
 314    default:
 315        tcg_abort();
 316    }
 317}
 318
 319/* parse target specific constraints */
 320static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 321{
 322    const char *ct_str;
 323
 324    ct_str = *pct_str;
 325    switch (ct_str[0]) {
 326    case 'r':
 327        ct->ct |= TCG_CT_REG;
 328        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
 329        break;
 330    case 'R':
 331        ct->ct |= TCG_CT_REG;
 332        tcg_regset_set32(ct->u.regs, 0, ALL_64);
 333        break;
 334    case 'A': /* qemu_ld/st address constraint */
 335        ct->ct |= TCG_CT_REG;
 336        tcg_regset_set32(ct->u.regs, 0,
 337                         TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff);
 338    reserve_helpers:
 339        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
 340        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
 341        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
 342        break;
 343    case 's': /* qemu_st data 32-bit constraint */
 344        ct->ct |= TCG_CT_REG;
 345        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
 346        goto reserve_helpers;
 347    case 'S': /* qemu_st data 64-bit constraint */
 348        ct->ct |= TCG_CT_REG;
 349        tcg_regset_set32(ct->u.regs, 0, ALL_64);
 350        goto reserve_helpers;
 351    case 'I':
 352        ct->ct |= TCG_CT_CONST_S11;
 353        break;
 354    case 'J':
 355        ct->ct |= TCG_CT_CONST_S13;
 356        break;
 357    case 'Z':
 358        ct->ct |= TCG_CT_CONST_ZERO;
 359        break;
 360    default:
 361        return -1;
 362    }
 363    ct_str++;
 364    *pct_str = ct_str;
 365    return 0;
 366}
 367
 368/* test if a constant matches the constraint */
 369static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
 370                                         const TCGArgConstraint *arg_ct)
 371{
 372    int ct = arg_ct->ct;
 373
 374    if (ct & TCG_CT_CONST) {
 375        return 1;
 376    }
 377
 378    if (type == TCG_TYPE_I32) {
 379        val = (int32_t)val;
 380    }
 381
 382    if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
 383        return 1;
 384    } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
 385        return 1;
 386    } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
 387        return 1;
 388    } else {
 389        return 0;
 390    }
 391}
 392
 393static inline void tcg_out_arith(TCGContext *s, TCGReg rd, TCGReg rs1,
 394                                 TCGReg rs2, int op)
 395{
 396    tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) | INSN_RS2(rs2));
 397}
 398
 399static inline void tcg_out_arithi(TCGContext *s, TCGReg rd, TCGReg rs1,
 400                                  int32_t offset, int op)
 401{
 402    tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) | INSN_IMM13(offset));
 403}
 404
 405static void tcg_out_arithc(TCGContext *s, TCGReg rd, TCGReg rs1,
 406                           int32_t val2, int val2const, int op)
 407{
 408    tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
 409              | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
 410}
 411
 412static inline void tcg_out_mov(TCGContext *s, TCGType type,
 413                               TCGReg ret, TCGReg arg)
 414{
 415    if (ret != arg) {
 416        tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
 417    }
 418}
 419
 420static inline void tcg_out_sethi(TCGContext *s, TCGReg ret, uint32_t arg)
 421{
 422    tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
 423}
 424
 425static inline void tcg_out_movi_imm13(TCGContext *s, TCGReg ret, int32_t arg)
 426{
 427    tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
 428}
 429
 430static void tcg_out_movi(TCGContext *s, TCGType type,
 431                         TCGReg ret, tcg_target_long arg)
 432{
 433    tcg_target_long hi, lo = (int32_t)arg;
 434
 435    /* Make sure we test 32-bit constants for imm13 properly.  */
 436    if (type == TCG_TYPE_I32) {
 437        arg = lo;
 438    }
 439
 440    /* A 13-bit constant sign-extended to 64-bits.  */
 441    if (check_fit_tl(arg, 13)) {
 442        tcg_out_movi_imm13(s, ret, arg);
 443        return;
 444    }
 445
 446    /* A 32-bit constant, or 32-bit zero-extended to 64-bits.  */
 447    if (type == TCG_TYPE_I32 || arg == (uint32_t)arg) {
 448        tcg_out_sethi(s, ret, arg);
 449        if (arg & 0x3ff) {
 450            tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
 451        }
 452        return;
 453    }
 454
 455    /* A 32-bit constant sign-extended to 64-bits.  */
 456    if (arg == lo) {
 457        tcg_out_sethi(s, ret, ~arg);
 458        tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
 459        return;
 460    }
 461
 462    /* A 64-bit constant decomposed into 2 32-bit pieces.  */
 463    if (check_fit_i32(lo, 13)) {
 464        hi = (arg - lo) >> 32;
 465        tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
 466        tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
 467        tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);
 468    } else {
 469        hi = arg >> 32;
 470        tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
 471        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);
 472        tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
 473        tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);
 474    }
 475}
 476
 477static inline void tcg_out_ldst_rr(TCGContext *s, TCGReg data, TCGReg a1,
 478                                   TCGReg a2, int op)
 479{
 480    tcg_out32(s, op | INSN_RD(data) | INSN_RS1(a1) | INSN_RS2(a2));
 481}
 482
 483static void tcg_out_ldst(TCGContext *s, TCGReg ret, TCGReg addr,
 484                         intptr_t offset, int op)
 485{
 486    if (check_fit_ptr(offset, 13)) {
 487        tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
 488                  INSN_IMM13(offset));
 489    } else {
 490        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, offset);
 491        tcg_out_ldst_rr(s, ret, addr, TCG_REG_T1, op);
 492    }
 493}
 494
 495static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
 496                              TCGReg arg1, intptr_t arg2)
 497{
 498    tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX));
 499}
 500
 501static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 502                              TCGReg arg1, intptr_t arg2)
 503{
 504    tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
 505}
 506
 507static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
 508{
 509    tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
 510    tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
 511}
 512
 513static inline void tcg_out_sety(TCGContext *s, TCGReg rs)
 514{
 515    tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
 516}
 517
 518static inline void tcg_out_rdy(TCGContext *s, TCGReg rd)
 519{
 520    tcg_out32(s, RDY | INSN_RD(rd));
 521}
 522
 523static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
 524                          int32_t val2, int val2const, int uns)
 525{
 526    /* Load Y with the sign/zero extension of RS1 to 64-bits.  */
 527    if (uns) {
 528        tcg_out_sety(s, TCG_REG_G0);
 529    } else {
 530        tcg_out_arithi(s, TCG_REG_T1, rs1, 31, SHIFT_SRA);
 531        tcg_out_sety(s, TCG_REG_T1);
 532    }
 533
 534    tcg_out_arithc(s, rd, rs1, val2, val2const,
 535                   uns ? ARITH_UDIV : ARITH_SDIV);
 536}
 537
 538static inline void tcg_out_nop(TCGContext *s)
 539{
 540    tcg_out_sethi(s, TCG_REG_G0, 0);
 541}
 542
 543static const uint8_t tcg_cond_to_bcond[] = {
 544    [TCG_COND_EQ] = COND_E,
 545    [TCG_COND_NE] = COND_NE,
 546    [TCG_COND_LT] = COND_L,
 547    [TCG_COND_GE] = COND_GE,
 548    [TCG_COND_LE] = COND_LE,
 549    [TCG_COND_GT] = COND_G,
 550    [TCG_COND_LTU] = COND_CS,
 551    [TCG_COND_GEU] = COND_CC,
 552    [TCG_COND_LEU] = COND_LEU,
 553    [TCG_COND_GTU] = COND_GU,
 554};
 555
 556static const uint8_t tcg_cond_to_rcond[] = {
 557    [TCG_COND_EQ] = RCOND_Z,
 558    [TCG_COND_NE] = RCOND_NZ,
 559    [TCG_COND_LT] = RCOND_LZ,
 560    [TCG_COND_GT] = RCOND_GZ,
 561    [TCG_COND_LE] = RCOND_LEZ,
 562    [TCG_COND_GE] = RCOND_GEZ
 563};
 564
 565static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19)
 566{
 567    tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
 568}
 569
 570static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
 571{
 572    int off19;
 573
 574    if (l->has_value) {
 575        off19 = INSN_OFF19(tcg_pcrel_diff(s, l->u.value_ptr));
 576    } else {
 577        /* Make sure to preserve destinations during retranslation.  */
 578        off19 = *s->code_ptr & INSN_OFF19(-1);
 579        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, l, 0);
 580    }
 581    tcg_out_bpcc0(s, scond, flags, off19);
 582}
 583
 584static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
 585{
 586    tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
 587}
 588
 589static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
 590                               int32_t arg2, int const_arg2, TCGLabel *l)
 591{
 592    tcg_out_cmp(s, arg1, arg2, const_arg2);
 593    tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, l);
 594    tcg_out_nop(s);
 595}
 596
 597static void tcg_out_movcc(TCGContext *s, TCGCond cond, int cc, TCGReg ret,
 598                          int32_t v1, int v1const)
 599{
 600    tcg_out32(s, ARITH_MOVCC | cc | INSN_RD(ret)
 601              | INSN_RS1(tcg_cond_to_bcond[cond])
 602              | (v1const ? INSN_IMM11(v1) : INSN_RS2(v1)));
 603}
 604
 605static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
 606                                TCGReg c1, int32_t c2, int c2const,
 607                                int32_t v1, int v1const)
 608{
 609    tcg_out_cmp(s, c1, c2, c2const);
 610    tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
 611}
 612
 613static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
 614                               int32_t arg2, int const_arg2, TCGLabel *l)
 615{
 616    /* For 64-bit signed comparisons vs zero, we can avoid the compare.  */
 617    if (arg2 == 0 && !is_unsigned_cond(cond)) {
 618        int off16;
 619
 620        if (l->has_value) {
 621            off16 = INSN_OFF16(tcg_pcrel_diff(s, l->u.value_ptr));
 622        } else {
 623            /* Make sure to preserve destinations during retranslation.  */
 624            off16 = *s->code_ptr & INSN_OFF16(-1);
 625            tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, l, 0);
 626        }
 627        tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
 628                  | INSN_COND(tcg_cond_to_rcond[cond]) | off16);
 629    } else {
 630        tcg_out_cmp(s, arg1, arg2, const_arg2);
 631        tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
 632    }
 633    tcg_out_nop(s);
 634}
 635
 636static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
 637                         int32_t v1, int v1const)
 638{
 639    tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
 640              | (tcg_cond_to_rcond[cond] << 10)
 641              | (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
 642}
 643
 644static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
 645                                TCGReg c1, int32_t c2, int c2const,
 646                                int32_t v1, int v1const)
 647{
 648    /* For 64-bit signed comparisons vs zero, we can avoid the compare.
 649       Note that the immediate range is one bit smaller, so we must check
 650       for that as well.  */
 651    if (c2 == 0 && !is_unsigned_cond(cond)
 652        && (!v1const || check_fit_i32(v1, 10))) {
 653        tcg_out_movr(s, cond, ret, c1, v1, v1const);
 654    } else {
 655        tcg_out_cmp(s, c1, c2, c2const);
 656        tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
 657    }
 658}
 659
 660static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
 661                                TCGReg c1, int32_t c2, int c2const)
 662{
 663    /* For 32-bit comparisons, we can play games with ADDC/SUBC.  */
 664    switch (cond) {
 665    case TCG_COND_LTU:
 666    case TCG_COND_GEU:
 667        /* The result of the comparison is in the carry bit.  */
 668        break;
 669
 670    case TCG_COND_EQ:
 671    case TCG_COND_NE:
 672        /* For equality, we can transform to inequality vs zero.  */
 673        if (c2 != 0) {
 674            tcg_out_arithc(s, TCG_REG_T1, c1, c2, c2const, ARITH_XOR);
 675            c2 = TCG_REG_T1;
 676        } else {
 677            c2 = c1;
 678        }
 679        c1 = TCG_REG_G0, c2const = 0;
 680        cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
 681        break;
 682
 683    case TCG_COND_GTU:
 684    case TCG_COND_LEU:
 685        /* If we don't need to load a constant into a register, we can
 686           swap the operands on GTU/LEU.  There's no benefit to loading
 687           the constant into a temporary register.  */
 688        if (!c2const || c2 == 0) {
 689            TCGReg t = c1;
 690            c1 = c2;
 691            c2 = t;
 692            c2const = 0;
 693            cond = tcg_swap_cond(cond);
 694            break;
 695        }
 696        /* FALLTHRU */
 697
 698    default:
 699        tcg_out_cmp(s, c1, c2, c2const);
 700        tcg_out_movi_imm13(s, ret, 0);
 701        tcg_out_movcc(s, cond, MOVCC_ICC, ret, 1, 1);
 702        return;
 703    }
 704
 705    tcg_out_cmp(s, c1, c2, c2const);
 706    if (cond == TCG_COND_LTU) {
 707        tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDC);
 708    } else {
 709        tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBC);
 710    }
 711}
 712
 713static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
 714                                TCGReg c1, int32_t c2, int c2const)
 715{
 716    if (use_vis3_instructions) {
 717        switch (cond) {
 718        case TCG_COND_NE:
 719            if (c2 != 0) {
 720                break;
 721            }
 722            c2 = c1, c2const = 0, c1 = TCG_REG_G0;
 723            /* FALLTHRU */
 724        case TCG_COND_LTU:
 725            tcg_out_cmp(s, c1, c2, c2const);
 726            tcg_out_arith(s, ret, TCG_REG_G0, TCG_REG_G0, ARITH_ADDXC);
 727            return;
 728        default:
 729            break;
 730        }
 731    }
 732
 733    /* For 64-bit signed comparisons vs zero, we can avoid the compare
 734       if the input does not overlap the output.  */
 735    if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
 736        tcg_out_movi_imm13(s, ret, 0);
 737        tcg_out_movr(s, cond, ret, c1, 1, 1);
 738    } else {
 739        tcg_out_cmp(s, c1, c2, c2const);
 740        tcg_out_movi_imm13(s, ret, 0);
 741        tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
 742    }
 743}
 744
 745static void tcg_out_addsub2_i32(TCGContext *s, TCGReg rl, TCGReg rh,
 746                                TCGReg al, TCGReg ah, int32_t bl, int blconst,
 747                                int32_t bh, int bhconst, int opl, int oph)
 748{
 749    TCGReg tmp = TCG_REG_T1;
 750
 751    /* Note that the low parts are fully consumed before tmp is set.  */
 752    if (rl != ah && (bhconst || rl != bh)) {
 753        tmp = rl;
 754    }
 755
 756    tcg_out_arithc(s, tmp, al, bl, blconst, opl);
 757    tcg_out_arithc(s, rh, ah, bh, bhconst, oph);
 758    tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
 759}
 760
 761static void tcg_out_addsub2_i64(TCGContext *s, TCGReg rl, TCGReg rh,
 762                                TCGReg al, TCGReg ah, int32_t bl, int blconst,
 763                                int32_t bh, int bhconst, bool is_sub)
 764{
 765    TCGReg tmp = TCG_REG_T1;
 766
 767    /* Note that the low parts are fully consumed before tmp is set.  */
 768    if (rl != ah && (bhconst || rl != bh)) {
 769        tmp = rl;
 770    }
 771
 772    tcg_out_arithc(s, tmp, al, bl, blconst, is_sub ? ARITH_SUBCC : ARITH_ADDCC);
 773
 774    if (use_vis3_instructions && !is_sub) {
 775        /* Note that ADDXC doesn't accept immediates.  */
 776        if (bhconst && bh != 0) {
 777           tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh);
 778           bh = TCG_REG_T2;
 779        }
 780        tcg_out_arith(s, rh, ah, bh, ARITH_ADDXC);
 781    } else if (bh == TCG_REG_G0) {
 782        /* If we have a zero, we can perform the operation in two insns,
 783           with the arithmetic first, and a conditional move into place.  */
 784        if (rh == ah) {
 785            tcg_out_arithi(s, TCG_REG_T2, ah, 1,
 786                           is_sub ? ARITH_SUB : ARITH_ADD);
 787            tcg_out_movcc(s, TCG_COND_LTU, MOVCC_XCC, rh, TCG_REG_T2, 0);
 788        } else {
 789            tcg_out_arithi(s, rh, ah, 1, is_sub ? ARITH_SUB : ARITH_ADD);
 790            tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, rh, ah, 0);
 791        }
 792    } else {
 793        /* Otherwise adjust BH as if there is carry into T2 ... */
 794        if (bhconst) {
 795            tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh + (is_sub ? -1 : 1));
 796        } else {
 797            tcg_out_arithi(s, TCG_REG_T2, bh, 1,
 798                           is_sub ? ARITH_SUB : ARITH_ADD);
 799        }
 800        /* ... smoosh T2 back to original BH if carry is clear ... */
 801        tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, TCG_REG_T2, bh, bhconst);
 802        /* ... and finally perform the arithmetic with the new operand.  */
 803        tcg_out_arith(s, rh, ah, TCG_REG_T2, is_sub ? ARITH_SUB : ARITH_ADD);
 804    }
 805
 806    tcg_out_mov(s, TCG_TYPE_I64, rl, tmp);
 807}
 808
 809static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest)
 810{
 811    ptrdiff_t disp = tcg_pcrel_diff(s, dest);
 812
 813    if (disp == (int32_t)disp) {
 814        tcg_out32(s, CALL | (uint32_t)disp >> 2);
 815    } else {
 816        uintptr_t desti = (uintptr_t)dest;
 817        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, desti & ~0xfff);
 818        tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, desti & 0xfff, JMPL);
 819    }
 820}
 821
 822static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
 823{
 824    tcg_out_call_nodelay(s, dest);
 825    tcg_out_nop(s);
 826}
 827
 828#ifdef CONFIG_SOFTMMU
 829static tcg_insn_unit *qemu_ld_trampoline[16];
 830static tcg_insn_unit *qemu_st_trampoline[16];
 831
 832static void build_trampolines(TCGContext *s)
 833{
 834    static void * const qemu_ld_helpers[16] = {
 835        [MO_UB]   = helper_ret_ldub_mmu,
 836        [MO_SB]   = helper_ret_ldsb_mmu,
 837        [MO_LEUW] = helper_le_lduw_mmu,
 838        [MO_LESW] = helper_le_ldsw_mmu,
 839        [MO_LEUL] = helper_le_ldul_mmu,
 840        [MO_LEQ]  = helper_le_ldq_mmu,
 841        [MO_BEUW] = helper_be_lduw_mmu,
 842        [MO_BESW] = helper_be_ldsw_mmu,
 843        [MO_BEUL] = helper_be_ldul_mmu,
 844        [MO_BEQ]  = helper_be_ldq_mmu,
 845    };
 846    static void * const qemu_st_helpers[16] = {
 847        [MO_UB]   = helper_ret_stb_mmu,
 848        [MO_LEUW] = helper_le_stw_mmu,
 849        [MO_LEUL] = helper_le_stl_mmu,
 850        [MO_LEQ]  = helper_le_stq_mmu,
 851        [MO_BEUW] = helper_be_stw_mmu,
 852        [MO_BEUL] = helper_be_stl_mmu,
 853        [MO_BEQ]  = helper_be_stq_mmu,
 854    };
 855
 856    int i;
 857    TCGReg ra;
 858
 859    for (i = 0; i < 16; ++i) {
 860        if (qemu_ld_helpers[i] == NULL) {
 861            continue;
 862        }
 863
 864        /* May as well align the trampoline.  */
 865        while ((uintptr_t)s->code_ptr & 15) {
 866            tcg_out_nop(s);
 867        }
 868        qemu_ld_trampoline[i] = s->code_ptr;
 869
 870        if (SPARC64 || TARGET_LONG_BITS == 32) {
 871            ra = TCG_REG_O3;
 872        } else {
 873            /* Install the high part of the address.  */
 874            tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
 875            ra = TCG_REG_O4;
 876        }
 877
 878        /* Set the retaddr operand.  */
 879        tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
 880        /* Set the env operand.  */
 881        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
 882        /* Tail call.  */
 883        tcg_out_call_nodelay(s, qemu_ld_helpers[i]);
 884        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
 885    }
 886
 887    for (i = 0; i < 16; ++i) {
 888        if (qemu_st_helpers[i] == NULL) {
 889            continue;
 890        }
 891
 892        /* May as well align the trampoline.  */
 893        while ((uintptr_t)s->code_ptr & 15) {
 894            tcg_out_nop(s);
 895        }
 896        qemu_st_trampoline[i] = s->code_ptr;
 897
 898        if (SPARC64) {
 899            ra = TCG_REG_O4;
 900        } else {
 901            ra = TCG_REG_O1;
 902            if (TARGET_LONG_BITS == 64) {
 903                /* Install the high part of the address.  */
 904                tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
 905                ra += 2;
 906            } else {
 907                ra += 1;
 908            }
 909            if ((i & MO_SIZE) == MO_64) {
 910                /* Install the high part of the data.  */
 911                tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
 912                ra += 2;
 913            } else {
 914                ra += 1;
 915            }
 916            /* Skip the oi argument.  */
 917            ra += 1;
 918        }
 919                
 920        /* Set the retaddr operand.  */
 921        if (ra >= TCG_REG_O6) {
 922            tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
 923                       TCG_TARGET_CALL_STACK_OFFSET);
 924            ra = TCG_REG_G1;
 925        }
 926        tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
 927        /* Set the env operand.  */
 928        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
 929        /* Tail call.  */
 930        tcg_out_call_nodelay(s, qemu_st_helpers[i]);
 931        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
 932    }
 933}
 934#endif
 935
 936/* Generate global QEMU prologue and epilogue code */
 937static void tcg_target_qemu_prologue(TCGContext *s)
 938{
 939    int tmp_buf_size, frame_size;
 940
 941    /* The TCG temp buffer is at the top of the frame, immediately
 942       below the frame pointer.  */
 943    tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
 944    tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
 945                  tmp_buf_size);
 946
 947    /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
 948       otherwise the minimal frame usable by callees.  */
 949    frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
 950    frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
 951    frame_size += TCG_TARGET_STACK_ALIGN - 1;
 952    frame_size &= -TCG_TARGET_STACK_ALIGN;
 953    tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
 954              INSN_IMM13(-frame_size));
 955
 956#ifndef CONFIG_SOFTMMU
 957    if (guest_base != 0) {
 958        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
 959        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
 960    }
 961#endif
 962
 963    tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
 964    /* delay slot */
 965    tcg_out_nop(s);
 966
 967    /* No epilogue required.  We issue ret + restore directly in the TB.  */
 968
 969#ifdef CONFIG_SOFTMMU
 970    build_trampolines(s);
 971#endif
 972}
 973
 974#if defined(CONFIG_SOFTMMU)
 975/* Perform the TLB load and compare.
 976
 977   Inputs:
 978   ADDRLO and ADDRHI contain the possible two parts of the address.
 979
 980   MEM_INDEX and S_BITS are the memory context and log2 size of the load.
 981
 982   WHICH is the offset into the CPUTLBEntry structure of the slot to read.
 983   This should be offsetof addr_read or addr_write.
 984
 985   The result of the TLB comparison is in %[ix]cc.  The sanitized address
 986   is in the returned register, maybe %o0.  The TLB addend is in %o1.  */
 987
 988static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
 989                               TCGMemOp s_bits, int which)
 990{
 991    const TCGReg r0 = TCG_REG_O0;
 992    const TCGReg r1 = TCG_REG_O1;
 993    const TCGReg r2 = TCG_REG_O2;
 994    int tlb_ofs;
 995
 996    /* Shift the page number down.  */
 997    tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);
 998
 999    /* Mask out the page offset, except for the required alignment.  */
1000    tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
1001                 TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1002
1003    /* Mask the tlb index.  */
1004    tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
1005    
1006    /* Mask page, part 2.  */
1007    tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
1008
1009    /* Shift the tlb index into place.  */
1010    tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
1011
1012    /* Relative to the current ENV.  */
1013    tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
1014
1015    /* Find a base address that can load both tlb comparator and addend.  */
1016    tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
1017    if (!check_fit_ptr(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
1018        if (tlb_ofs & ~0x3ff) {
1019            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, tlb_ofs & ~0x3ff);
1020            tcg_out_arith(s, r1, r1, TCG_REG_T1, ARITH_ADD);
1021        }
1022        tlb_ofs &= 0x3ff;
1023    }
1024
1025    /* Load the tlb comparator and the addend.  */
1026    tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
1027    tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
1028
1029    /* subcc arg0, arg2, %g0 */
1030    tcg_out_cmp(s, r0, r2, 0);
1031
1032    /* If the guest address must be zero-extended, do so now.  */
1033    if (SPARC64 && TARGET_LONG_BITS == 32) {
1034        tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
1035        return r0;
1036    }
1037    return addr;
1038}
1039#endif /* CONFIG_SOFTMMU */
1040
1041static const int qemu_ld_opc[16] = {
1042    [MO_UB]   = LDUB,
1043    [MO_SB]   = LDSB,
1044
1045    [MO_BEUW] = LDUH,
1046    [MO_BESW] = LDSH,
1047    [MO_BEUL] = LDUW,
1048    [MO_BESL] = LDSW,
1049    [MO_BEQ]  = LDX,
1050
1051    [MO_LEUW] = LDUH_LE,
1052    [MO_LESW] = LDSH_LE,
1053    [MO_LEUL] = LDUW_LE,
1054    [MO_LESL] = LDSW_LE,
1055    [MO_LEQ]  = LDX_LE,
1056};
1057
1058static const int qemu_st_opc[16] = {
1059    [MO_UB]   = STB,
1060
1061    [MO_BEUW] = STH,
1062    [MO_BEUL] = STW,
1063    [MO_BEQ]  = STX,
1064
1065    [MO_LEUW] = STH_LE,
1066    [MO_LEUL] = STW_LE,
1067    [MO_LEQ]  = STX_LE,
1068};
1069
1070static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
1071                            TCGMemOpIdx oi, bool is_64)
1072{
1073    TCGMemOp memop = get_memop(oi);
1074#ifdef CONFIG_SOFTMMU
1075    unsigned memi = get_mmuidx(oi);
1076    TCGReg addrz, param;
1077    tcg_insn_unit *func;
1078    tcg_insn_unit *label_ptr;
1079
1080    addrz = tcg_out_tlb_load(s, addr, memi, memop & MO_SIZE,
1081                             offsetof(CPUTLBEntry, addr_read));
1082
1083    /* The fast path is exactly one insn.  Thus we can perform the
1084       entire TLB Hit in the (annulled) delay slot of the branch
1085       over the TLB Miss case.  */
1086
1087    /* beq,a,pt %[xi]cc, label0 */
1088    label_ptr = s->code_ptr;
1089    tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1090                  | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1091    /* delay slot */
1092    tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1,
1093                    qemu_ld_opc[memop & (MO_BSWAP | MO_SSIZE)]);
1094
1095    /* TLB Miss.  */
1096
1097    param = TCG_REG_O1;
1098    if (!SPARC64 && TARGET_LONG_BITS == 64) {
1099        /* Skip the high-part; we'll perform the extract in the trampoline.  */
1100        param++;
1101    }
1102    tcg_out_mov(s, TCG_TYPE_REG, param++, addr);
1103
1104    /* We use the helpers to extend SB and SW data, leaving the case
1105       of SL needing explicit extending below.  */
1106    if ((memop & MO_SSIZE) == MO_SL) {
1107        func = qemu_ld_trampoline[memop & (MO_BSWAP | MO_SIZE)];
1108    } else {
1109        func = qemu_ld_trampoline[memop & (MO_BSWAP | MO_SSIZE)];
1110    }
1111    tcg_debug_assert(func != NULL);
1112    tcg_out_call_nodelay(s, func);
1113    /* delay slot */
1114    tcg_out_movi(s, TCG_TYPE_I32, param, oi);
1115
1116    /* Recall that all of the helpers return 64-bit results.
1117       Which complicates things for sparcv8plus.  */
1118    if (SPARC64) {
1119        /* We let the helper sign-extend SB and SW, but leave SL for here.  */
1120        if (is_64 && (memop & MO_SSIZE) == MO_SL) {
1121            tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
1122        } else {
1123            tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
1124        }
1125    } else {
1126        if ((memop & MO_SIZE) == MO_64) {
1127            tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
1128            tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
1129            tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
1130        } else if (is_64) {
1131            /* Re-extend from 32-bit rather than reassembling when we
1132               know the high register must be an extension.  */
1133            tcg_out_arithi(s, data, TCG_REG_O1, 0,
1134                           memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
1135        } else {
1136            tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
1137        }
1138    }
1139
1140    *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
1141#else
1142    if (SPARC64 && TARGET_LONG_BITS == 32) {
1143        tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1144        addr = TCG_REG_T1;
1145    }
1146    tcg_out_ldst_rr(s, data, addr,
1147                    (guest_base ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1148                    qemu_ld_opc[memop & (MO_BSWAP | MO_SSIZE)]);
1149#endif /* CONFIG_SOFTMMU */
1150}
1151
1152static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
1153                            TCGMemOpIdx oi)
1154{
1155    TCGMemOp memop = get_memop(oi);
1156#ifdef CONFIG_SOFTMMU
1157    unsigned memi = get_mmuidx(oi);
1158    TCGReg addrz, param;
1159    tcg_insn_unit *func;
1160    tcg_insn_unit *label_ptr;
1161
1162    addrz = tcg_out_tlb_load(s, addr, memi, memop & MO_SIZE,
1163                             offsetof(CPUTLBEntry, addr_write));
1164
1165    /* The fast path is exactly one insn.  Thus we can perform the entire
1166       TLB Hit in the (annulled) delay slot of the branch over TLB Miss.  */
1167    /* beq,a,pt %[xi]cc, label0 */
1168    label_ptr = s->code_ptr;
1169    tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1170                  | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1171    /* delay slot */
1172    tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1,
1173                    qemu_st_opc[memop & (MO_BSWAP | MO_SIZE)]);
1174
1175    /* TLB Miss.  */
1176
1177    param = TCG_REG_O1;
1178    if (!SPARC64 && TARGET_LONG_BITS == 64) {
1179        /* Skip the high-part; we'll perform the extract in the trampoline.  */
1180        param++;
1181    }
1182    tcg_out_mov(s, TCG_TYPE_REG, param++, addr);
1183    if (!SPARC64 && (memop & MO_SIZE) == MO_64) {
1184        /* Skip the high-part; we'll perform the extract in the trampoline.  */
1185        param++;
1186    }
1187    tcg_out_mov(s, TCG_TYPE_REG, param++, data);
1188
1189    func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)];
1190    tcg_debug_assert(func != NULL);
1191    tcg_out_call_nodelay(s, func);
1192    /* delay slot */
1193    tcg_out_movi(s, TCG_TYPE_I32, param, oi);
1194
1195    *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
1196#else
1197    if (SPARC64 && TARGET_LONG_BITS == 32) {
1198        tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1199        addr = TCG_REG_T1;
1200    }
1201    tcg_out_ldst_rr(s, data, addr,
1202                    (guest_base ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1203                    qemu_st_opc[memop & (MO_BSWAP | MO_SIZE)]);
1204#endif /* CONFIG_SOFTMMU */
1205}
1206
1207static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1208                       const TCGArg args[TCG_MAX_OP_ARGS],
1209                       const int const_args[TCG_MAX_OP_ARGS])
1210{
1211    TCGArg a0, a1, a2;
1212    int c, c2;
1213
1214    /* Hoist the loads of the most common arguments.  */
1215    a0 = args[0];
1216    a1 = args[1];
1217    a2 = args[2];
1218    c2 = const_args[2];
1219
1220    switch (opc) {
1221    case INDEX_op_exit_tb:
1222        if (check_fit_ptr(a0, 13)) {
1223            tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1224            tcg_out_movi_imm13(s, TCG_REG_O0, a0);
1225        } else {
1226            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, a0 & ~0x3ff);
1227            tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1228            tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, a0 & 0x3ff, ARITH_OR);
1229        }
1230        break;
1231    case INDEX_op_goto_tb:
1232        if (s->tb_jmp_offset) {
1233            /* direct jump method */
1234            s->tb_jmp_offset[a0] = tcg_current_code_size(s);
1235            /* Make sure to preserve links during retranslation.  */
1236            tcg_out32(s, CALL | (*s->code_ptr & ~INSN_OP(-1)));
1237        } else {
1238            /* indirect jump method */
1239            tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + a0));
1240            tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
1241        }
1242        tcg_out_nop(s);
1243        s->tb_next_offset[a0] = tcg_current_code_size(s);
1244        break;
1245    case INDEX_op_br:
1246        tcg_out_bpcc(s, COND_A, BPCC_PT, arg_label(a0));
1247        tcg_out_nop(s);
1248        break;
1249
1250#define OP_32_64(x)                             \
1251        glue(glue(case INDEX_op_, x), _i32):    \
1252        glue(glue(case INDEX_op_, x), _i64)
1253
1254    OP_32_64(ld8u):
1255        tcg_out_ldst(s, a0, a1, a2, LDUB);
1256        break;
1257    OP_32_64(ld8s):
1258        tcg_out_ldst(s, a0, a1, a2, LDSB);
1259        break;
1260    OP_32_64(ld16u):
1261        tcg_out_ldst(s, a0, a1, a2, LDUH);
1262        break;
1263    OP_32_64(ld16s):
1264        tcg_out_ldst(s, a0, a1, a2, LDSH);
1265        break;
1266    case INDEX_op_ld_i32:
1267    case INDEX_op_ld32u_i64:
1268        tcg_out_ldst(s, a0, a1, a2, LDUW);
1269        break;
1270    OP_32_64(st8):
1271        tcg_out_ldst(s, a0, a1, a2, STB);
1272        break;
1273    OP_32_64(st16):
1274        tcg_out_ldst(s, a0, a1, a2, STH);
1275        break;
1276    case INDEX_op_st_i32:
1277    case INDEX_op_st32_i64:
1278        tcg_out_ldst(s, a0, a1, a2, STW);
1279        break;
1280    OP_32_64(add):
1281        c = ARITH_ADD;
1282        goto gen_arith;
1283    OP_32_64(sub):
1284        c = ARITH_SUB;
1285        goto gen_arith;
1286    OP_32_64(and):
1287        c = ARITH_AND;
1288        goto gen_arith;
1289    OP_32_64(andc):
1290        c = ARITH_ANDN;
1291        goto gen_arith;
1292    OP_32_64(or):
1293        c = ARITH_OR;
1294        goto gen_arith;
1295    OP_32_64(orc):
1296        c = ARITH_ORN;
1297        goto gen_arith;
1298    OP_32_64(xor):
1299        c = ARITH_XOR;
1300        goto gen_arith;
1301    case INDEX_op_shl_i32:
1302        c = SHIFT_SLL;
1303    do_shift32:
1304        /* Limit immediate shift count lest we create an illegal insn.  */
1305        tcg_out_arithc(s, a0, a1, a2 & 31, c2, c);
1306        break;
1307    case INDEX_op_shr_i32:
1308        c = SHIFT_SRL;
1309        goto do_shift32;
1310    case INDEX_op_sar_i32:
1311        c = SHIFT_SRA;
1312        goto do_shift32;
1313    case INDEX_op_mul_i32:
1314        c = ARITH_UMUL;
1315        goto gen_arith;
1316
1317    OP_32_64(neg):
1318        c = ARITH_SUB;
1319        goto gen_arith1;
1320    OP_32_64(not):
1321        c = ARITH_ORN;
1322        goto gen_arith1;
1323
1324    case INDEX_op_div_i32:
1325        tcg_out_div32(s, a0, a1, a2, c2, 0);
1326        break;
1327    case INDEX_op_divu_i32:
1328        tcg_out_div32(s, a0, a1, a2, c2, 1);
1329        break;
1330
1331    case INDEX_op_brcond_i32:
1332        tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], arg_label(args[3]));
1333        break;
1334    case INDEX_op_setcond_i32:
1335        tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
1336        break;
1337    case INDEX_op_movcond_i32:
1338        tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
1339        break;
1340
1341    case INDEX_op_add2_i32:
1342        tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1343                            args[4], const_args[4], args[5], const_args[5],
1344                            ARITH_ADDCC, ARITH_ADDC);
1345        break;
1346    case INDEX_op_sub2_i32:
1347        tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1348                            args[4], const_args[4], args[5], const_args[5],
1349                            ARITH_SUBCC, ARITH_SUBC);
1350        break;
1351    case INDEX_op_mulu2_i32:
1352        c = ARITH_UMUL;
1353        goto do_mul2;
1354    case INDEX_op_muls2_i32:
1355        c = ARITH_SMUL;
1356    do_mul2:
1357        /* The 32-bit multiply insns produce a full 64-bit result.  If the
1358           destination register can hold it, we can avoid the slower RDY.  */
1359        tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
1360        if (SPARC64 || a0 <= TCG_REG_O7) {
1361            tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
1362        } else {
1363            tcg_out_rdy(s, a1);
1364        }
1365        break;
1366
1367    case INDEX_op_qemu_ld_i32:
1368        tcg_out_qemu_ld(s, a0, a1, a2, false);
1369        break;
1370    case INDEX_op_qemu_ld_i64:
1371        tcg_out_qemu_ld(s, a0, a1, a2, true);
1372        break;
1373    case INDEX_op_qemu_st_i32:
1374    case INDEX_op_qemu_st_i64:
1375        tcg_out_qemu_st(s, a0, a1, a2);
1376        break;
1377
1378    case INDEX_op_ld32s_i64:
1379        tcg_out_ldst(s, a0, a1, a2, LDSW);
1380        break;
1381    case INDEX_op_ld_i64:
1382        tcg_out_ldst(s, a0, a1, a2, LDX);
1383        break;
1384    case INDEX_op_st_i64:
1385        tcg_out_ldst(s, a0, a1, a2, STX);
1386        break;
1387    case INDEX_op_shl_i64:
1388        c = SHIFT_SLLX;
1389    do_shift64:
1390        /* Limit immediate shift count lest we create an illegal insn.  */
1391        tcg_out_arithc(s, a0, a1, a2 & 63, c2, c);
1392        break;
1393    case INDEX_op_shr_i64:
1394        c = SHIFT_SRLX;
1395        goto do_shift64;
1396    case INDEX_op_sar_i64:
1397        c = SHIFT_SRAX;
1398        goto do_shift64;
1399    case INDEX_op_mul_i64:
1400        c = ARITH_MULX;
1401        goto gen_arith;
1402    case INDEX_op_div_i64:
1403        c = ARITH_SDIVX;
1404        goto gen_arith;
1405    case INDEX_op_divu_i64:
1406        c = ARITH_UDIVX;
1407        goto gen_arith;
1408    case INDEX_op_ext_i32_i64:
1409    case INDEX_op_ext32s_i64:
1410        tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA);
1411        break;
1412    case INDEX_op_extu_i32_i64:
1413    case INDEX_op_ext32u_i64:
1414        tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL);
1415        break;
1416    case INDEX_op_extrl_i64_i32:
1417        tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1418        break;
1419    case INDEX_op_extrh_i64_i32:
1420        tcg_out_arithi(s, a0, a1, 32, SHIFT_SRLX);
1421        break;
1422
1423    case INDEX_op_brcond_i64:
1424        tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(args[3]));
1425        break;
1426    case INDEX_op_setcond_i64:
1427        tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
1428        break;
1429    case INDEX_op_movcond_i64:
1430        tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
1431        break;
1432    case INDEX_op_add2_i64:
1433        tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1434                            const_args[4], args[5], const_args[5], false);
1435        break;
1436    case INDEX_op_sub2_i64:
1437        tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1438                            const_args[4], args[5], const_args[5], true);
1439        break;
1440    case INDEX_op_muluh_i64:
1441        tcg_out_arith(s, args[0], args[1], args[2], ARITH_UMULXHI);
1442        break;
1443
1444    gen_arith:
1445        tcg_out_arithc(s, a0, a1, a2, c2, c);
1446        break;
1447
1448    gen_arith1:
1449        tcg_out_arithc(s, a0, TCG_REG_G0, a1, const_args[1], c);
1450        break;
1451
1452    case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
1453    case INDEX_op_mov_i64:
1454    case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
1455    case INDEX_op_movi_i64:
1456    case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1457    default:
1458        tcg_abort();
1459    }
1460}
1461
1462static const TCGTargetOpDef sparc_op_defs[] = {
1463    { INDEX_op_exit_tb, { } },
1464    { INDEX_op_goto_tb, { } },
1465    { INDEX_op_br, { } },
1466
1467    { INDEX_op_ld8u_i32, { "r", "r" } },
1468    { INDEX_op_ld8s_i32, { "r", "r" } },
1469    { INDEX_op_ld16u_i32, { "r", "r" } },
1470    { INDEX_op_ld16s_i32, { "r", "r" } },
1471    { INDEX_op_ld_i32, { "r", "r" } },
1472    { INDEX_op_st8_i32, { "rZ", "r" } },
1473    { INDEX_op_st16_i32, { "rZ", "r" } },
1474    { INDEX_op_st_i32, { "rZ", "r" } },
1475
1476    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1477    { INDEX_op_mul_i32, { "r", "rZ", "rJ" } },
1478    { INDEX_op_div_i32, { "r", "rZ", "rJ" } },
1479    { INDEX_op_divu_i32, { "r", "rZ", "rJ" } },
1480    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1481    { INDEX_op_and_i32, { "r", "rZ", "rJ" } },
1482    { INDEX_op_andc_i32, { "r", "rZ", "rJ" } },
1483    { INDEX_op_or_i32, { "r", "rZ", "rJ" } },
1484    { INDEX_op_orc_i32, { "r", "rZ", "rJ" } },
1485    { INDEX_op_xor_i32, { "r", "rZ", "rJ" } },
1486
1487    { INDEX_op_shl_i32, { "r", "rZ", "rJ" } },
1488    { INDEX_op_shr_i32, { "r", "rZ", "rJ" } },
1489    { INDEX_op_sar_i32, { "r", "rZ", "rJ" } },
1490
1491    { INDEX_op_neg_i32, { "r", "rJ" } },
1492    { INDEX_op_not_i32, { "r", "rJ" } },
1493
1494    { INDEX_op_brcond_i32, { "rZ", "rJ" } },
1495    { INDEX_op_setcond_i32, { "r", "rZ", "rJ" } },
1496    { INDEX_op_movcond_i32, { "r", "rZ", "rJ", "rI", "0" } },
1497
1498    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1499    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1500    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rJ" } },
1501    { INDEX_op_muls2_i32, { "r", "r", "rZ", "rJ" } },
1502
1503    { INDEX_op_ld8u_i64, { "R", "r" } },
1504    { INDEX_op_ld8s_i64, { "R", "r" } },
1505    { INDEX_op_ld16u_i64, { "R", "r" } },
1506    { INDEX_op_ld16s_i64, { "R", "r" } },
1507    { INDEX_op_ld32u_i64, { "R", "r" } },
1508    { INDEX_op_ld32s_i64, { "R", "r" } },
1509    { INDEX_op_ld_i64, { "R", "r" } },
1510    { INDEX_op_st8_i64, { "RZ", "r" } },
1511    { INDEX_op_st16_i64, { "RZ", "r" } },
1512    { INDEX_op_st32_i64, { "RZ", "r" } },
1513    { INDEX_op_st_i64, { "RZ", "r" } },
1514
1515    { INDEX_op_add_i64, { "R", "RZ", "RJ" } },
1516    { INDEX_op_mul_i64, { "R", "RZ", "RJ" } },
1517    { INDEX_op_div_i64, { "R", "RZ", "RJ" } },
1518    { INDEX_op_divu_i64, { "R", "RZ", "RJ" } },
1519    { INDEX_op_sub_i64, { "R", "RZ", "RJ" } },
1520    { INDEX_op_and_i64, { "R", "RZ", "RJ" } },
1521    { INDEX_op_andc_i64, { "R", "RZ", "RJ" } },
1522    { INDEX_op_or_i64, { "R", "RZ", "RJ" } },
1523    { INDEX_op_orc_i64, { "R", "RZ", "RJ" } },
1524    { INDEX_op_xor_i64, { "R", "RZ", "RJ" } },
1525
1526    { INDEX_op_shl_i64, { "R", "RZ", "RJ" } },
1527    { INDEX_op_shr_i64, { "R", "RZ", "RJ" } },
1528    { INDEX_op_sar_i64, { "R", "RZ", "RJ" } },
1529
1530    { INDEX_op_neg_i64, { "R", "RJ" } },
1531    { INDEX_op_not_i64, { "R", "RJ" } },
1532
1533    { INDEX_op_ext32s_i64, { "R", "R" } },
1534    { INDEX_op_ext32u_i64, { "R", "R" } },
1535    { INDEX_op_ext_i32_i64, { "R", "r" } },
1536    { INDEX_op_extu_i32_i64, { "R", "r" } },
1537    { INDEX_op_extrl_i64_i32,  { "r", "R" } },
1538    { INDEX_op_extrh_i64_i32,  { "r", "R" } },
1539
1540    { INDEX_op_brcond_i64, { "RZ", "RJ" } },
1541    { INDEX_op_setcond_i64, { "R", "RZ", "RJ" } },
1542    { INDEX_op_movcond_i64, { "R", "RZ", "RJ", "RI", "0" } },
1543
1544    { INDEX_op_add2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } },
1545    { INDEX_op_sub2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } },
1546    { INDEX_op_muluh_i64, { "R", "RZ", "RZ" } },
1547
1548    { INDEX_op_qemu_ld_i32, { "r", "A" } },
1549    { INDEX_op_qemu_ld_i64, { "R", "A" } },
1550    { INDEX_op_qemu_st_i32, { "sZ", "A" } },
1551    { INDEX_op_qemu_st_i64, { "SZ", "A" } },
1552
1553    { -1 },
1554};
1555
1556static void tcg_target_init(TCGContext *s)
1557{
1558    /* Only probe for the platform and capabilities if we havn't already
1559       determined maximum values at compile time.  */
1560#ifndef use_vis3_instructions
1561    {
1562        unsigned long hwcap = qemu_getauxval(AT_HWCAP);
1563        use_vis3_instructions = (hwcap & HWCAP_SPARC_VIS3) != 0;
1564    }
1565#endif
1566
1567    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1568    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, ALL_64);
1569
1570    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1571                     (1 << TCG_REG_G1) |
1572                     (1 << TCG_REG_G2) |
1573                     (1 << TCG_REG_G3) |
1574                     (1 << TCG_REG_G4) |
1575                     (1 << TCG_REG_G5) |
1576                     (1 << TCG_REG_G6) |
1577                     (1 << TCG_REG_G7) |
1578                     (1 << TCG_REG_O0) |
1579                     (1 << TCG_REG_O1) |
1580                     (1 << TCG_REG_O2) |
1581                     (1 << TCG_REG_O3) |
1582                     (1 << TCG_REG_O4) |
1583                     (1 << TCG_REG_O5) |
1584                     (1 << TCG_REG_O7));
1585
1586    tcg_regset_clear(s->reserved_regs);
1587    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
1588    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
1589    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
1590    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
1591    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
1592    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
1593    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
1594    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
1595
1596    tcg_add_target_add_op_defs(sparc_op_defs);
1597}
1598
1599#if SPARC64
1600# define ELF_HOST_MACHINE  EM_SPARCV9
1601#else
1602# define ELF_HOST_MACHINE  EM_SPARC32PLUS
1603# define ELF_HOST_FLAGS    EF_SPARC_32PLUS
1604#endif
1605
1606typedef struct {
1607    DebugFrameHeader h;
1608    uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
1609    uint8_t fde_win_save;
1610    uint8_t fde_ret_save[3];
1611} DebugFrame;
1612
1613static const DebugFrame debug_frame = {
1614    .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1615    .h.cie.id = -1,
1616    .h.cie.version = 1,
1617    .h.cie.code_align = 1,
1618    .h.cie.data_align = -sizeof(void *) & 0x7f,
1619    .h.cie.return_column = 15,            /* o7 */
1620
1621    /* Total FDE size does not include the "len" member.  */
1622    .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
1623
1624    .fde_def_cfa = {
1625#if SPARC64
1626        12, 30,                         /* DW_CFA_def_cfa i6, 2047 */
1627        (2047 & 0x7f) | 0x80, (2047 >> 7)
1628#else
1629        13, 30                          /* DW_CFA_def_cfa_register i6 */
1630#endif
1631    },
1632    .fde_win_save = 0x2d,               /* DW_CFA_GNU_window_save */
1633    .fde_ret_save = { 9, 15, 31 },      /* DW_CFA_register o7, i7 */
1634};
1635
1636void tcg_register_jit(void *buf, size_t buf_size)
1637{
1638    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1639}
1640
1641void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
1642{
1643    uint32_t *ptr = (uint32_t *)jmp_addr;
1644    uintptr_t disp = addr - jmp_addr;
1645
1646    /* We can reach the entire address space for 32-bit.  For 64-bit
1647       the code_gen_buffer can't be larger than 2GB.  */
1648    tcg_debug_assert(disp == (int32_t)disp);
1649
1650    *ptr = CALL | (uint32_t)disp >> 2;
1651    flush_icache_range(jmp_addr, jmp_addr + 4);
1652}
1653