qemu/tcg/mips/tcg-target.inc.c
<<
>>
Prefs
   1/*
   2 * Tiny Code Generator for QEMU
   3 *
   4 * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
   5 * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
   6 * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 */
  26
  27#ifdef HOST_WORDS_BIGENDIAN
  28# define MIPS_BE  1
  29#else
  30# define MIPS_BE  0
  31#endif
  32
  33#if TCG_TARGET_REG_BITS == 32
  34# define LO_OFF  (MIPS_BE * 4)
  35# define HI_OFF  (4 - LO_OFF)
  36#else
  37/* To assert at compile-time that these values are never used
  38   for TCG_TARGET_REG_BITS == 64.  */
  39int link_error(void);
  40# define LO_OFF  link_error()
  41# define HI_OFF  link_error()
  42#endif
  43
  44#ifdef CONFIG_DEBUG_TCG
  45static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
  46    "zero",
  47    "at",
  48    "v0",
  49    "v1",
  50    "a0",
  51    "a1",
  52    "a2",
  53    "a3",
  54    "t0",
  55    "t1",
  56    "t2",
  57    "t3",
  58    "t4",
  59    "t5",
  60    "t6",
  61    "t7",
  62    "s0",
  63    "s1",
  64    "s2",
  65    "s3",
  66    "s4",
  67    "s5",
  68    "s6",
  69    "s7",
  70    "t8",
  71    "t9",
  72    "k0",
  73    "k1",
  74    "gp",
  75    "sp",
  76    "s8",
  77    "ra",
  78};
  79#endif
  80
  81#define TCG_TMP0  TCG_REG_AT
  82#define TCG_TMP1  TCG_REG_T9
  83#define TCG_TMP2  TCG_REG_T8
  84#define TCG_TMP3  TCG_REG_T7
  85
  86#ifndef CONFIG_SOFTMMU
  87#define TCG_GUEST_BASE_REG TCG_REG_S1
  88#endif
  89
  90/* check if we really need so many registers :P */
  91static const int tcg_target_reg_alloc_order[] = {
  92    /* Call saved registers.  */
  93    TCG_REG_S0,
  94    TCG_REG_S1,
  95    TCG_REG_S2,
  96    TCG_REG_S3,
  97    TCG_REG_S4,
  98    TCG_REG_S5,
  99    TCG_REG_S6,
 100    TCG_REG_S7,
 101    TCG_REG_S8,
 102
 103    /* Call clobbered registers.  */
 104    TCG_REG_T4,
 105    TCG_REG_T5,
 106    TCG_REG_T6,
 107    TCG_REG_T7,
 108    TCG_REG_T8,
 109    TCG_REG_T9,
 110    TCG_REG_V1,
 111    TCG_REG_V0,
 112
 113    /* Argument registers, opposite order of allocation.  */
 114    TCG_REG_T3,
 115    TCG_REG_T2,
 116    TCG_REG_T1,
 117    TCG_REG_T0,
 118    TCG_REG_A3,
 119    TCG_REG_A2,
 120    TCG_REG_A1,
 121    TCG_REG_A0,
 122};
 123
 124static const TCGReg tcg_target_call_iarg_regs[] = {
 125    TCG_REG_A0,
 126    TCG_REG_A1,
 127    TCG_REG_A2,
 128    TCG_REG_A3,
 129#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
 130    TCG_REG_T0,
 131    TCG_REG_T1,
 132    TCG_REG_T2,
 133    TCG_REG_T3,
 134#endif
 135};
 136
 137static const TCGReg tcg_target_call_oarg_regs[2] = {
 138    TCG_REG_V0,
 139    TCG_REG_V1
 140};
 141
 142static tcg_insn_unit *tb_ret_addr;
 143static tcg_insn_unit *bswap32_addr;
 144static tcg_insn_unit *bswap32u_addr;
 145static tcg_insn_unit *bswap64_addr;
 146
 147static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
 148{
 149    /* Let the compiler perform the right-shift as part of the arithmetic.  */
 150    ptrdiff_t disp = target - (pc + 1);
 151    tcg_debug_assert(disp == (int16_t)disp);
 152    return disp & 0xffff;
 153}
 154
 155static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
 156{
 157    *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
 158}
 159
 160static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target)
 161{
 162    tcg_debug_assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0);
 163    return ((uintptr_t)target >> 2) & 0x3ffffff;
 164}
 165
 166static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
 167{
 168    *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
 169}
 170
 171static void patch_reloc(tcg_insn_unit *code_ptr, int type,
 172                        intptr_t value, intptr_t addend)
 173{
 174    tcg_debug_assert(type == R_MIPS_PC16);
 175    tcg_debug_assert(addend == 0);
 176    reloc_pc16(code_ptr, (tcg_insn_unit *)value);
 177}
 178
 179#define TCG_CT_CONST_ZERO 0x100
 180#define TCG_CT_CONST_U16  0x200    /* Unsigned 16-bit: 0 - 0xffff.  */
 181#define TCG_CT_CONST_S16  0x400    /* Signed 16-bit: -32768 - 32767 */
 182#define TCG_CT_CONST_P2M1 0x800    /* Power of 2 minus 1.  */
 183#define TCG_CT_CONST_N16  0x1000   /* "Negatable" 16-bit: -32767 - 32767 */
 184#define TCG_CT_CONST_WSZ  0x2000   /* word size */
 185
 186static inline bool is_p2m1(tcg_target_long val)
 187{
 188    return val && ((val + 1) & val) == 0;
 189}
 190
 191/* parse target specific constraints */
 192static const char *target_parse_constraint(TCGArgConstraint *ct,
 193                                           const char *ct_str, TCGType type)
 194{
 195    switch(*ct_str++) {
 196    case 'r':
 197        ct->ct |= TCG_CT_REG;
 198        ct->u.regs = 0xffffffff;
 199        break;
 200    case 'L': /* qemu_ld input arg constraint */
 201        ct->ct |= TCG_CT_REG;
 202        ct->u.regs = 0xffffffff;
 203        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 204#if defined(CONFIG_SOFTMMU)
 205        if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
 206            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 207        }
 208#endif
 209        break;
 210    case 'S': /* qemu_st constraint */
 211        ct->ct |= TCG_CT_REG;
 212        ct->u.regs = 0xffffffff;
 213        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 214#if defined(CONFIG_SOFTMMU)
 215        if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
 216            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 217            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
 218        } else {
 219            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
 220        }
 221#endif
 222        break;
 223    case 'I':
 224        ct->ct |= TCG_CT_CONST_U16;
 225        break;
 226    case 'J':
 227        ct->ct |= TCG_CT_CONST_S16;
 228        break;
 229    case 'K':
 230        ct->ct |= TCG_CT_CONST_P2M1;
 231        break;
 232    case 'N':
 233        ct->ct |= TCG_CT_CONST_N16;
 234        break;
 235    case 'W':
 236        ct->ct |= TCG_CT_CONST_WSZ;
 237        break;
 238    case 'Z':
 239        /* We are cheating a bit here, using the fact that the register
 240           ZERO is also the register number 0. Hence there is no need
 241           to check for const_args in each instruction. */
 242        ct->ct |= TCG_CT_CONST_ZERO;
 243        break;
 244    default:
 245        return NULL;
 246    }
 247    return ct_str;
 248}
 249
 250/* test if a constant matches the constraint */
 251static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
 252                                         const TCGArgConstraint *arg_ct)
 253{
 254    int ct;
 255    ct = arg_ct->ct;
 256    if (ct & TCG_CT_CONST) {
 257        return 1;
 258    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
 259        return 1;
 260    } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
 261        return 1;
 262    } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
 263        return 1;
 264    } else if ((ct & TCG_CT_CONST_N16) && val >= -32767 && val <= 32767) {
 265        return 1;
 266    } else if ((ct & TCG_CT_CONST_P2M1)
 267               && use_mips32r2_instructions && is_p2m1(val)) {
 268        return 1;
 269    } else if ((ct & TCG_CT_CONST_WSZ)
 270               && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
 271        return 1;
 272    }
 273    return 0;
 274}
 275
 276/* instruction opcodes */
 277typedef enum {
 278    OPC_J        = 002 << 26,
 279    OPC_JAL      = 003 << 26,
 280    OPC_BEQ      = 004 << 26,
 281    OPC_BNE      = 005 << 26,
 282    OPC_BLEZ     = 006 << 26,
 283    OPC_BGTZ     = 007 << 26,
 284    OPC_ADDIU    = 011 << 26,
 285    OPC_SLTI     = 012 << 26,
 286    OPC_SLTIU    = 013 << 26,
 287    OPC_ANDI     = 014 << 26,
 288    OPC_ORI      = 015 << 26,
 289    OPC_XORI     = 016 << 26,
 290    OPC_LUI      = 017 << 26,
 291    OPC_DADDIU   = 031 << 26,
 292    OPC_LB       = 040 << 26,
 293    OPC_LH       = 041 << 26,
 294    OPC_LW       = 043 << 26,
 295    OPC_LBU      = 044 << 26,
 296    OPC_LHU      = 045 << 26,
 297    OPC_LWU      = 047 << 26,
 298    OPC_SB       = 050 << 26,
 299    OPC_SH       = 051 << 26,
 300    OPC_SW       = 053 << 26,
 301    OPC_LD       = 067 << 26,
 302    OPC_SD       = 077 << 26,
 303
 304    OPC_SPECIAL  = 000 << 26,
 305    OPC_SLL      = OPC_SPECIAL | 000,
 306    OPC_SRL      = OPC_SPECIAL | 002,
 307    OPC_ROTR     = OPC_SPECIAL | 002 | (1 << 21),
 308    OPC_SRA      = OPC_SPECIAL | 003,
 309    OPC_SLLV     = OPC_SPECIAL | 004,
 310    OPC_SRLV     = OPC_SPECIAL | 006,
 311    OPC_ROTRV    = OPC_SPECIAL | 006 | 0100,
 312    OPC_SRAV     = OPC_SPECIAL | 007,
 313    OPC_JR_R5    = OPC_SPECIAL | 010,
 314    OPC_JALR     = OPC_SPECIAL | 011,
 315    OPC_MOVZ     = OPC_SPECIAL | 012,
 316    OPC_MOVN     = OPC_SPECIAL | 013,
 317    OPC_SYNC     = OPC_SPECIAL | 017,
 318    OPC_MFHI     = OPC_SPECIAL | 020,
 319    OPC_MFLO     = OPC_SPECIAL | 022,
 320    OPC_DSLLV    = OPC_SPECIAL | 024,
 321    OPC_DSRLV    = OPC_SPECIAL | 026,
 322    OPC_DROTRV   = OPC_SPECIAL | 026 | 0100,
 323    OPC_DSRAV    = OPC_SPECIAL | 027,
 324    OPC_MULT     = OPC_SPECIAL | 030,
 325    OPC_MUL_R6   = OPC_SPECIAL | 030 | 0200,
 326    OPC_MUH      = OPC_SPECIAL | 030 | 0300,
 327    OPC_MULTU    = OPC_SPECIAL | 031,
 328    OPC_MULU     = OPC_SPECIAL | 031 | 0200,
 329    OPC_MUHU     = OPC_SPECIAL | 031 | 0300,
 330    OPC_DIV      = OPC_SPECIAL | 032,
 331    OPC_DIV_R6   = OPC_SPECIAL | 032 | 0200,
 332    OPC_MOD      = OPC_SPECIAL | 032 | 0300,
 333    OPC_DIVU     = OPC_SPECIAL | 033,
 334    OPC_DIVU_R6  = OPC_SPECIAL | 033 | 0200,
 335    OPC_MODU     = OPC_SPECIAL | 033 | 0300,
 336    OPC_DMULT    = OPC_SPECIAL | 034,
 337    OPC_DMUL     = OPC_SPECIAL | 034 | 0200,
 338    OPC_DMUH     = OPC_SPECIAL | 034 | 0300,
 339    OPC_DMULTU   = OPC_SPECIAL | 035,
 340    OPC_DMULU    = OPC_SPECIAL | 035 | 0200,
 341    OPC_DMUHU    = OPC_SPECIAL | 035 | 0300,
 342    OPC_DDIV     = OPC_SPECIAL | 036,
 343    OPC_DDIV_R6  = OPC_SPECIAL | 036 | 0200,
 344    OPC_DMOD     = OPC_SPECIAL | 036 | 0300,
 345    OPC_DDIVU    = OPC_SPECIAL | 037,
 346    OPC_DDIVU_R6 = OPC_SPECIAL | 037 | 0200,
 347    OPC_DMODU    = OPC_SPECIAL | 037 | 0300,
 348    OPC_ADDU     = OPC_SPECIAL | 041,
 349    OPC_SUBU     = OPC_SPECIAL | 043,
 350    OPC_AND      = OPC_SPECIAL | 044,
 351    OPC_OR       = OPC_SPECIAL | 045,
 352    OPC_XOR      = OPC_SPECIAL | 046,
 353    OPC_NOR      = OPC_SPECIAL | 047,
 354    OPC_SLT      = OPC_SPECIAL | 052,
 355    OPC_SLTU     = OPC_SPECIAL | 053,
 356    OPC_DADDU    = OPC_SPECIAL | 055,
 357    OPC_DSUBU    = OPC_SPECIAL | 057,
 358    OPC_SELEQZ   = OPC_SPECIAL | 065,
 359    OPC_SELNEZ   = OPC_SPECIAL | 067,
 360    OPC_DSLL     = OPC_SPECIAL | 070,
 361    OPC_DSRL     = OPC_SPECIAL | 072,
 362    OPC_DROTR    = OPC_SPECIAL | 072 | (1 << 21),
 363    OPC_DSRA     = OPC_SPECIAL | 073,
 364    OPC_DSLL32   = OPC_SPECIAL | 074,
 365    OPC_DSRL32   = OPC_SPECIAL | 076,
 366    OPC_DROTR32  = OPC_SPECIAL | 076 | (1 << 21),
 367    OPC_DSRA32   = OPC_SPECIAL | 077,
 368    OPC_CLZ_R6   = OPC_SPECIAL | 0120,
 369    OPC_DCLZ_R6  = OPC_SPECIAL | 0122,
 370
 371    OPC_REGIMM   = 001 << 26,
 372    OPC_BLTZ     = OPC_REGIMM | (000 << 16),
 373    OPC_BGEZ     = OPC_REGIMM | (001 << 16),
 374
 375    OPC_SPECIAL2 = 034 << 26,
 376    OPC_MUL_R5   = OPC_SPECIAL2 | 002,
 377    OPC_CLZ      = OPC_SPECIAL2 | 040,
 378    OPC_DCLZ     = OPC_SPECIAL2 | 044,
 379
 380    OPC_SPECIAL3 = 037 << 26,
 381    OPC_EXT      = OPC_SPECIAL3 | 000,
 382    OPC_DEXTM    = OPC_SPECIAL3 | 001,
 383    OPC_DEXTU    = OPC_SPECIAL3 | 002,
 384    OPC_DEXT     = OPC_SPECIAL3 | 003,
 385    OPC_INS      = OPC_SPECIAL3 | 004,
 386    OPC_DINSM    = OPC_SPECIAL3 | 005,
 387    OPC_DINSU    = OPC_SPECIAL3 | 006,
 388    OPC_DINS     = OPC_SPECIAL3 | 007,
 389    OPC_WSBH     = OPC_SPECIAL3 | 00240,
 390    OPC_DSBH     = OPC_SPECIAL3 | 00244,
 391    OPC_DSHD     = OPC_SPECIAL3 | 00544,
 392    OPC_SEB      = OPC_SPECIAL3 | 02040,
 393    OPC_SEH      = OPC_SPECIAL3 | 03040,
 394
 395    /* MIPS r6 doesn't have JR, JALR should be used instead */
 396    OPC_JR       = use_mips32r6_instructions ? OPC_JALR : OPC_JR_R5,
 397
 398    /*
 399     * MIPS r6 replaces MUL with an alternative encoding which is
 400     * backwards-compatible at the assembly level.
 401     */
 402    OPC_MUL      = use_mips32r6_instructions ? OPC_MUL_R6 : OPC_MUL_R5,
 403
 404    /* MIPS r6 introduced names for weaker variants of SYNC.  These are
 405       backward compatible to previous architecture revisions.  */
 406    OPC_SYNC_WMB     = OPC_SYNC | 0x04 << 5,
 407    OPC_SYNC_MB      = OPC_SYNC | 0x10 << 5,
 408    OPC_SYNC_ACQUIRE = OPC_SYNC | 0x11 << 5,
 409    OPC_SYNC_RELEASE = OPC_SYNC | 0x12 << 5,
 410    OPC_SYNC_RMB     = OPC_SYNC | 0x13 << 5,
 411
 412    /* Aliases for convenience.  */
 413    ALIAS_PADD     = sizeof(void *) == 4 ? OPC_ADDU : OPC_DADDU,
 414    ALIAS_PADDI    = sizeof(void *) == 4 ? OPC_ADDIU : OPC_DADDIU,
 415    ALIAS_TSRL     = TARGET_LONG_BITS == 32 || TCG_TARGET_REG_BITS == 32
 416                     ? OPC_SRL : OPC_DSRL,
 417} MIPSInsn;
 418
 419/*
 420 * Type reg
 421 */
 422static inline void tcg_out_opc_reg(TCGContext *s, MIPSInsn opc,
 423                                   TCGReg rd, TCGReg rs, TCGReg rt)
 424{
 425    int32_t inst;
 426
 427    inst = opc;
 428    inst |= (rs & 0x1F) << 21;
 429    inst |= (rt & 0x1F) << 16;
 430    inst |= (rd & 0x1F) << 11;
 431    tcg_out32(s, inst);
 432}
 433
 434/*
 435 * Type immediate
 436 */
 437static inline void tcg_out_opc_imm(TCGContext *s, MIPSInsn opc,
 438                                   TCGReg rt, TCGReg rs, TCGArg imm)
 439{
 440    int32_t inst;
 441
 442    inst = opc;
 443    inst |= (rs & 0x1F) << 21;
 444    inst |= (rt & 0x1F) << 16;
 445    inst |= (imm & 0xffff);
 446    tcg_out32(s, inst);
 447}
 448
 449/*
 450 * Type bitfield
 451 */
 452static inline void tcg_out_opc_bf(TCGContext *s, MIPSInsn opc, TCGReg rt,
 453                                  TCGReg rs, int msb, int lsb)
 454{
 455    int32_t inst;
 456
 457    inst = opc;
 458    inst |= (rs & 0x1F) << 21;
 459    inst |= (rt & 0x1F) << 16;
 460    inst |= (msb & 0x1F) << 11;
 461    inst |= (lsb & 0x1F) << 6;
 462    tcg_out32(s, inst);
 463}
 464
 465static inline void tcg_out_opc_bf64(TCGContext *s, MIPSInsn opc, MIPSInsn opm,
 466                                    MIPSInsn oph, TCGReg rt, TCGReg rs,
 467                                    int msb, int lsb)
 468{
 469    if (lsb >= 32) {
 470        opc = oph;
 471        msb -= 32;
 472        lsb -= 32;
 473    } else if (msb >= 32) {
 474        opc = opm;
 475        msb -= 32;
 476    }
 477    tcg_out_opc_bf(s, opc, rt, rs, msb, lsb);
 478}
 479
 480/*
 481 * Type branch
 482 */
 483static inline void tcg_out_opc_br(TCGContext *s, MIPSInsn opc,
 484                                  TCGReg rt, TCGReg rs)
 485{
 486    /* We pay attention here to not modify the branch target by reading
 487       the existing value and using it again. This ensure that caches and
 488       memory are kept coherent during retranslation. */
 489    uint16_t offset = (uint16_t)*s->code_ptr;
 490
 491    tcg_out_opc_imm(s, opc, rt, rs, offset);
 492}
 493
 494/*
 495 * Type sa
 496 */
 497static inline void tcg_out_opc_sa(TCGContext *s, MIPSInsn opc,
 498                                  TCGReg rd, TCGReg rt, TCGArg sa)
 499{
 500    int32_t inst;
 501
 502    inst = opc;
 503    inst |= (rt & 0x1F) << 16;
 504    inst |= (rd & 0x1F) << 11;
 505    inst |= (sa & 0x1F) <<  6;
 506    tcg_out32(s, inst);
 507
 508}
 509
 510static void tcg_out_opc_sa64(TCGContext *s, MIPSInsn opc1, MIPSInsn opc2,
 511                             TCGReg rd, TCGReg rt, TCGArg sa)
 512{
 513    int32_t inst;
 514
 515    inst = (sa & 32 ? opc2 : opc1);
 516    inst |= (rt & 0x1F) << 16;
 517    inst |= (rd & 0x1F) << 11;
 518    inst |= (sa & 0x1F) <<  6;
 519    tcg_out32(s, inst);
 520}
 521
 522/*
 523 * Type jump.
 524 * Returns true if the branch was in range and the insn was emitted.
 525 */
 526static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
 527{
 528    uintptr_t dest = (uintptr_t)target;
 529    uintptr_t from = (uintptr_t)s->code_ptr + 4;
 530    int32_t inst;
 531
 532    /* The pc-region branch happens within the 256MB region of
 533       the delay slot (thus the +4).  */
 534    if ((from ^ dest) & -(1 << 28)) {
 535        return false;
 536    }
 537    tcg_debug_assert((dest & 3) == 0);
 538
 539    inst = opc;
 540    inst |= (dest >> 2) & 0x3ffffff;
 541    tcg_out32(s, inst);
 542    return true;
 543}
 544
 545static inline void tcg_out_nop(TCGContext *s)
 546{
 547    tcg_out32(s, 0);
 548}
 549
 550static inline void tcg_out_dsll(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
 551{
 552    tcg_out_opc_sa64(s, OPC_DSLL, OPC_DSLL32, rd, rt, sa);
 553}
 554
 555static inline void tcg_out_dsrl(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
 556{
 557    tcg_out_opc_sa64(s, OPC_DSRL, OPC_DSRL32, rd, rt, sa);
 558}
 559
 560static inline void tcg_out_dsra(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
 561{
 562    tcg_out_opc_sa64(s, OPC_DSRA, OPC_DSRA32, rd, rt, sa);
 563}
 564
 565static inline void tcg_out_mov(TCGContext *s, TCGType type,
 566                               TCGReg ret, TCGReg arg)
 567{
 568    /* Simple reg-reg move, optimising out the 'do nothing' case */
 569    if (ret != arg) {
 570        tcg_out_opc_reg(s, OPC_OR, ret, arg, TCG_REG_ZERO);
 571    }
 572}
 573
 574static void tcg_out_movi(TCGContext *s, TCGType type,
 575                         TCGReg ret, tcg_target_long arg)
 576{
 577    if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
 578        arg = (int32_t)arg;
 579    }
 580    if (arg == (int16_t)arg) {
 581        tcg_out_opc_imm(s, OPC_ADDIU, ret, TCG_REG_ZERO, arg);
 582        return;
 583    }
 584    if (arg == (uint16_t)arg) {
 585        tcg_out_opc_imm(s, OPC_ORI, ret, TCG_REG_ZERO, arg);
 586        return;
 587    }
 588    if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) {
 589        tcg_out_opc_imm(s, OPC_LUI, ret, TCG_REG_ZERO, arg >> 16);
 590    } else {
 591        tcg_out_movi(s, TCG_TYPE_I32, ret, arg >> 31 >> 1);
 592        if (arg & 0xffff0000ull) {
 593            tcg_out_dsll(s, ret, ret, 16);
 594            tcg_out_opc_imm(s, OPC_ORI, ret, ret, arg >> 16);
 595            tcg_out_dsll(s, ret, ret, 16);
 596        } else {
 597            tcg_out_dsll(s, ret, ret, 32);
 598        }
 599    }
 600    if (arg & 0xffff) {
 601        tcg_out_opc_imm(s, OPC_ORI, ret, ret, arg & 0xffff);
 602    }
 603}
 604
 605static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
 606{
 607    if (use_mips32r2_instructions) {
 608        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 609    } else {
 610        /* ret and arg can't be register at */
 611        if (ret == TCG_TMP0 || arg == TCG_TMP0) {
 612            tcg_abort();
 613        }
 614
 615        tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
 616        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
 617        tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
 618        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 619    }
 620}
 621
 622static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
 623{
 624    if (use_mips32r2_instructions) {
 625        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 626        tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
 627    } else {
 628        /* ret and arg can't be register at */
 629        if (ret == TCG_TMP0 || arg == TCG_TMP0) {
 630            tcg_abort();
 631        }
 632
 633        tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
 634        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 635        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 636        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 637    }
 638}
 639
 640static void tcg_out_bswap_subr(TCGContext *s, tcg_insn_unit *sub)
 641{
 642    bool ok = tcg_out_opc_jmp(s, OPC_JAL, sub);
 643    tcg_debug_assert(ok);
 644}
 645
 646static void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
 647{
 648    if (use_mips32r2_instructions) {
 649        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 650        tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
 651    } else {
 652        tcg_out_bswap_subr(s, bswap32_addr);
 653        /* delay slot -- never omit the insn, like tcg_out_mov might.  */
 654        tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
 655        tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
 656    }
 657}
 658
 659static void tcg_out_bswap32u(TCGContext *s, TCGReg ret, TCGReg arg)
 660{
 661    if (use_mips32r2_instructions) {
 662        tcg_out_opc_reg(s, OPC_DSBH, ret, 0, arg);
 663        tcg_out_opc_reg(s, OPC_DSHD, ret, 0, ret);
 664        tcg_out_dsrl(s, ret, ret, 32);
 665    } else {
 666        tcg_out_bswap_subr(s, bswap32u_addr);
 667        /* delay slot -- never omit the insn, like tcg_out_mov might.  */
 668        tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
 669        tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
 670    }
 671}
 672
 673static void tcg_out_bswap64(TCGContext *s, TCGReg ret, TCGReg arg)
 674{
 675    if (use_mips32r2_instructions) {
 676        tcg_out_opc_reg(s, OPC_DSBH, ret, 0, arg);
 677        tcg_out_opc_reg(s, OPC_DSHD, ret, 0, ret);
 678    } else {
 679        tcg_out_bswap_subr(s, bswap64_addr);
 680        /* delay slot -- never omit the insn, like tcg_out_mov might.  */
 681        tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
 682        tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
 683    }
 684}
 685
 686static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
 687{
 688    if (use_mips32r2_instructions) {
 689        tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
 690    } else {
 691        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 692        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
 693    }
 694}
 695
 696static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
 697{
 698    if (use_mips32r2_instructions) {
 699        tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
 700    } else {
 701        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
 702        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 703    }
 704}
 705
 706static inline void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
 707{
 708    if (use_mips32r2_instructions) {
 709        tcg_out_opc_bf(s, OPC_DEXT, ret, arg, 31, 0);
 710    } else {
 711        tcg_out_dsll(s, ret, arg, 32);
 712        tcg_out_dsrl(s, ret, ret, 32);
 713    }
 714}
 715
 716static void tcg_out_ldst(TCGContext *s, MIPSInsn opc, TCGReg data,
 717                         TCGReg addr, intptr_t ofs)
 718{
 719    int16_t lo = ofs;
 720    if (ofs != lo) {
 721        tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - lo);
 722        if (addr != TCG_REG_ZERO) {
 723            tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP0, TCG_TMP0, addr);
 724        }
 725        addr = TCG_TMP0;
 726    }
 727    tcg_out_opc_imm(s, opc, data, addr, lo);
 728}
 729
 730static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
 731                              TCGReg arg1, intptr_t arg2)
 732{
 733    MIPSInsn opc = OPC_LD;
 734    if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
 735        opc = OPC_LW;
 736    }
 737    tcg_out_ldst(s, opc, arg, arg1, arg2);
 738}
 739
 740static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 741                              TCGReg arg1, intptr_t arg2)
 742{
 743    MIPSInsn opc = OPC_SD;
 744    if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
 745        opc = OPC_SW;
 746    }
 747    tcg_out_ldst(s, opc, arg, arg1, arg2);
 748}
 749
 750static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
 751                               TCGReg base, intptr_t ofs)
 752{
 753    if (val == 0) {
 754        tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
 755        return true;
 756    }
 757    return false;
 758}
 759
 760static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al,
 761                            TCGReg ah, TCGArg bl, TCGArg bh, bool cbl,
 762                            bool cbh, bool is_sub)
 763{
 764    TCGReg th = TCG_TMP1;
 765
 766    /* If we have a negative constant such that negating it would
 767       make the high part zero, we can (usually) eliminate one insn.  */
 768    if (cbl && cbh && bh == -1 && bl != 0) {
 769        bl = -bl;
 770        bh = 0;
 771        is_sub = !is_sub;
 772    }
 773
 774    /* By operating on the high part first, we get to use the final
 775       carry operation to move back from the temporary.  */
 776    if (!cbh) {
 777        tcg_out_opc_reg(s, (is_sub ? OPC_SUBU : OPC_ADDU), th, ah, bh);
 778    } else if (bh != 0 || ah == rl) {
 779        tcg_out_opc_imm(s, OPC_ADDIU, th, ah, (is_sub ? -bh : bh));
 780    } else {
 781        th = ah;
 782    }
 783
 784    /* Note that tcg optimization should eliminate the bl == 0 case.  */
 785    if (is_sub) {
 786        if (cbl) {
 787            tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, al, bl);
 788            tcg_out_opc_imm(s, OPC_ADDIU, rl, al, -bl);
 789        } else {
 790            tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, al, bl);
 791            tcg_out_opc_reg(s, OPC_SUBU, rl, al, bl);
 792        }
 793        tcg_out_opc_reg(s, OPC_SUBU, rh, th, TCG_TMP0);
 794    } else {
 795        if (cbl) {
 796            tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl);
 797            tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl);
 798        } else if (rl == al && rl == bl) {
 799            tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, al, 31);
 800            tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
 801        } else {
 802            tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
 803            tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl));
 804        }
 805        tcg_out_opc_reg(s, OPC_ADDU, rh, th, TCG_TMP0);
 806    }
 807}
 808
 809/* Bit 0 set if inversion required; bit 1 set if swapping required.  */
 810#define MIPS_CMP_INV  1
 811#define MIPS_CMP_SWAP 2
 812
 813static const uint8_t mips_cmp_map[16] = {
 814    [TCG_COND_LT]  = 0,
 815    [TCG_COND_LTU] = 0,
 816    [TCG_COND_GE]  = MIPS_CMP_INV,
 817    [TCG_COND_GEU] = MIPS_CMP_INV,
 818    [TCG_COND_LE]  = MIPS_CMP_INV | MIPS_CMP_SWAP,
 819    [TCG_COND_LEU] = MIPS_CMP_INV | MIPS_CMP_SWAP,
 820    [TCG_COND_GT]  = MIPS_CMP_SWAP,
 821    [TCG_COND_GTU] = MIPS_CMP_SWAP,
 822};
 823
 824static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
 825                            TCGReg arg1, TCGReg arg2)
 826{
 827    MIPSInsn s_opc = OPC_SLTU;
 828    int cmp_map;
 829
 830    switch (cond) {
 831    case TCG_COND_EQ:
 832        if (arg2 != 0) {
 833            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 834            arg1 = ret;
 835        }
 836        tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
 837        break;
 838
 839    case TCG_COND_NE:
 840        if (arg2 != 0) {
 841            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 842            arg1 = ret;
 843        }
 844        tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
 845        break;
 846
 847    case TCG_COND_LT:
 848    case TCG_COND_GE:
 849    case TCG_COND_LE:
 850    case TCG_COND_GT:
 851        s_opc = OPC_SLT;
 852        /* FALLTHRU */
 853
 854    case TCG_COND_LTU:
 855    case TCG_COND_GEU:
 856    case TCG_COND_LEU:
 857    case TCG_COND_GTU:
 858        cmp_map = mips_cmp_map[cond];
 859        if (cmp_map & MIPS_CMP_SWAP) {
 860            TCGReg t = arg1;
 861            arg1 = arg2;
 862            arg2 = t;
 863        }
 864        tcg_out_opc_reg(s, s_opc, ret, arg1, arg2);
 865        if (cmp_map & MIPS_CMP_INV) {
 866            tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 867        }
 868        break;
 869
 870     default:
 871         tcg_abort();
 872         break;
 873     }
 874}
 875
 876static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
 877                           TCGReg arg2, TCGLabel *l)
 878{
 879    static const MIPSInsn b_zero[16] = {
 880        [TCG_COND_LT] = OPC_BLTZ,
 881        [TCG_COND_GT] = OPC_BGTZ,
 882        [TCG_COND_LE] = OPC_BLEZ,
 883        [TCG_COND_GE] = OPC_BGEZ,
 884    };
 885
 886    MIPSInsn s_opc = OPC_SLTU;
 887    MIPSInsn b_opc;
 888    int cmp_map;
 889
 890    switch (cond) {
 891    case TCG_COND_EQ:
 892        b_opc = OPC_BEQ;
 893        break;
 894    case TCG_COND_NE:
 895        b_opc = OPC_BNE;
 896        break;
 897
 898    case TCG_COND_LT:
 899    case TCG_COND_GT:
 900    case TCG_COND_LE:
 901    case TCG_COND_GE:
 902        if (arg2 == 0) {
 903            b_opc = b_zero[cond];
 904            arg2 = arg1;
 905            arg1 = 0;
 906            break;
 907        }
 908        s_opc = OPC_SLT;
 909        /* FALLTHRU */
 910
 911    case TCG_COND_LTU:
 912    case TCG_COND_GTU:
 913    case TCG_COND_LEU:
 914    case TCG_COND_GEU:
 915        cmp_map = mips_cmp_map[cond];
 916        if (cmp_map & MIPS_CMP_SWAP) {
 917            TCGReg t = arg1;
 918            arg1 = arg2;
 919            arg2 = t;
 920        }
 921        tcg_out_opc_reg(s, s_opc, TCG_TMP0, arg1, arg2);
 922        b_opc = (cmp_map & MIPS_CMP_INV ? OPC_BEQ : OPC_BNE);
 923        arg1 = TCG_TMP0;
 924        arg2 = TCG_REG_ZERO;
 925        break;
 926
 927    default:
 928        tcg_abort();
 929        break;
 930    }
 931
 932    tcg_out_opc_br(s, b_opc, arg1, arg2);
 933    if (l->has_value) {
 934        reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
 935    } else {
 936        tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
 937    }
 938    tcg_out_nop(s);
 939}
 940
 941static TCGReg tcg_out_reduce_eq2(TCGContext *s, TCGReg tmp0, TCGReg tmp1,
 942                                 TCGReg al, TCGReg ah,
 943                                 TCGReg bl, TCGReg bh)
 944{
 945    /* Merge highpart comparison into AH.  */
 946    if (bh != 0) {
 947        if (ah != 0) {
 948            tcg_out_opc_reg(s, OPC_XOR, tmp0, ah, bh);
 949            ah = tmp0;
 950        } else {
 951            ah = bh;
 952        }
 953    }
 954    /* Merge lowpart comparison into AL.  */
 955    if (bl != 0) {
 956        if (al != 0) {
 957            tcg_out_opc_reg(s, OPC_XOR, tmp1, al, bl);
 958            al = tmp1;
 959        } else {
 960            al = bl;
 961        }
 962    }
 963    /* Merge high and low part comparisons into AL.  */
 964    if (ah != 0) {
 965        if (al != 0) {
 966            tcg_out_opc_reg(s, OPC_OR, tmp0, ah, al);
 967            al = tmp0;
 968        } else {
 969            al = ah;
 970        }
 971    }
 972    return al;
 973}
 974
 975static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
 976                             TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
 977{
 978    TCGReg tmp0 = TCG_TMP0;
 979    TCGReg tmp1 = ret;
 980
 981    tcg_debug_assert(ret != TCG_TMP0);
 982    if (ret == ah || ret == bh) {
 983        tcg_debug_assert(ret != TCG_TMP1);
 984        tmp1 = TCG_TMP1;
 985    }
 986
 987    switch (cond) {
 988    case TCG_COND_EQ:
 989    case TCG_COND_NE:
 990        tmp1 = tcg_out_reduce_eq2(s, tmp0, tmp1, al, ah, bl, bh);
 991        tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
 992        break;
 993
 994    default:
 995        tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);
 996        tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);
 997        tcg_out_opc_reg(s, OPC_AND, tmp1, tmp1, tmp0);
 998        tcg_out_setcond(s, tcg_high_cond(cond), tmp0, ah, bh);
 999        tcg_out_opc_reg(s, OPC_OR, ret, tmp1, tmp0);
1000        break;
1001    }
1002}
1003
1004static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
1005                            TCGReg bl, TCGReg bh, TCGLabel *l)
1006{
1007    TCGCond b_cond = TCG_COND_NE;
1008    TCGReg tmp = TCG_TMP1;
1009
1010    /* With branches, we emit between 4 and 9 insns with 2 or 3 branches.
1011       With setcond, we emit between 3 and 10 insns and only 1 branch,
1012       which ought to get better branch prediction.  */
1013     switch (cond) {
1014     case TCG_COND_EQ:
1015     case TCG_COND_NE:
1016        b_cond = cond;
1017        tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh);
1018        break;
1019
1020    default:
1021        /* Minimize code size by preferring a compare not requiring INV.  */
1022        if (mips_cmp_map[cond] & MIPS_CMP_INV) {
1023            cond = tcg_invert_cond(cond);
1024            b_cond = TCG_COND_EQ;
1025        }
1026        tcg_out_setcond2(s, cond, tmp, al, ah, bl, bh);
1027        break;
1028    }
1029
1030    tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, l);
1031}
1032
1033static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
1034                            TCGReg c1, TCGReg c2, TCGReg v1, TCGReg v2)
1035{
1036    bool eqz = false;
1037
1038    /* If one of the values is zero, put it last to match SEL*Z instructions */
1039    if (use_mips32r6_instructions && v1 == 0) {
1040        v1 = v2;
1041        v2 = 0;
1042        cond = tcg_invert_cond(cond);
1043    }
1044
1045    switch (cond) {
1046    case TCG_COND_EQ:
1047        eqz = true;
1048        /* FALLTHRU */
1049    case TCG_COND_NE:
1050        if (c2 != 0) {
1051            tcg_out_opc_reg(s, OPC_XOR, TCG_TMP0, c1, c2);
1052            c1 = TCG_TMP0;
1053        }
1054        break;
1055
1056    default:
1057        /* Minimize code size by preferring a compare not requiring INV.  */
1058        if (mips_cmp_map[cond] & MIPS_CMP_INV) {
1059            cond = tcg_invert_cond(cond);
1060            eqz = true;
1061        }
1062        tcg_out_setcond(s, cond, TCG_TMP0, c1, c2);
1063        c1 = TCG_TMP0;
1064        break;
1065    }
1066
1067    if (use_mips32r6_instructions) {
1068        MIPSInsn m_opc_t = eqz ? OPC_SELEQZ : OPC_SELNEZ;
1069        MIPSInsn m_opc_f = eqz ? OPC_SELNEZ : OPC_SELEQZ;
1070
1071        if (v2 != 0) {
1072            tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
1073        }
1074        tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
1075        if (v2 != 0) {
1076            tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
1077        }
1078    } else {
1079        MIPSInsn m_opc = eqz ? OPC_MOVZ : OPC_MOVN;
1080
1081        tcg_out_opc_reg(s, m_opc, ret, v1, c1);
1082
1083        /* This should be guaranteed via constraints */
1084        tcg_debug_assert(v2 == ret);
1085    }
1086}
1087
1088static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
1089{
1090    /* Note that the ABI requires the called function's address to be
1091       loaded into T9, even if a direct branch is in range.  */
1092    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T9, (uintptr_t)arg);
1093
1094    /* But do try a direct branch, allowing the cpu better insn prefetch.  */
1095    if (tail) {
1096        if (!tcg_out_opc_jmp(s, OPC_J, arg)) {
1097            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_T9, 0);
1098        }
1099    } else {
1100        if (!tcg_out_opc_jmp(s, OPC_JAL, arg)) {
1101            tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1102        }
1103    }
1104}
1105
1106static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
1107{
1108    tcg_out_call_int(s, arg, false);
1109    tcg_out_nop(s);
1110}
1111
1112#if defined(CONFIG_SOFTMMU)
1113#include "tcg-ldst.inc.c"
1114
1115static void * const qemu_ld_helpers[16] = {
1116    [MO_UB]   = helper_ret_ldub_mmu,
1117    [MO_SB]   = helper_ret_ldsb_mmu,
1118    [MO_LEUW] = helper_le_lduw_mmu,
1119    [MO_LESW] = helper_le_ldsw_mmu,
1120    [MO_LEUL] = helper_le_ldul_mmu,
1121    [MO_LEQ]  = helper_le_ldq_mmu,
1122    [MO_BEUW] = helper_be_lduw_mmu,
1123    [MO_BESW] = helper_be_ldsw_mmu,
1124    [MO_BEUL] = helper_be_ldul_mmu,
1125    [MO_BEQ]  = helper_be_ldq_mmu,
1126#if TCG_TARGET_REG_BITS == 64
1127    [MO_LESL] = helper_le_ldsl_mmu,
1128    [MO_BESL] = helper_be_ldsl_mmu,
1129#endif
1130};
1131
1132static void * const qemu_st_helpers[16] = {
1133    [MO_UB]   = helper_ret_stb_mmu,
1134    [MO_LEUW] = helper_le_stw_mmu,
1135    [MO_LEUL] = helper_le_stl_mmu,
1136    [MO_LEQ]  = helper_le_stq_mmu,
1137    [MO_BEUW] = helper_be_stw_mmu,
1138    [MO_BEUL] = helper_be_stl_mmu,
1139    [MO_BEQ]  = helper_be_stq_mmu,
1140};
1141
1142/* Helper routines for marshalling helper function arguments into
1143 * the correct registers and stack.
1144 * I is where we want to put this argument, and is updated and returned
1145 * for the next call. ARG is the argument itself.
1146 *
1147 * We provide routines for arguments which are: immediate, 32 bit
1148 * value in register, 16 and 8 bit values in register (which must be zero
1149 * extended before use) and 64 bit value in a lo:hi register pair.
1150 */
1151
1152static int tcg_out_call_iarg_reg(TCGContext *s, int i, TCGReg arg)
1153{
1154    if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1155        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[i], arg);
1156    } else {
1157        /* For N32 and N64, the initial offset is different.  But there
1158           we also have 8 argument register so we don't run out here.  */
1159        tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
1160        tcg_out_st(s, TCG_TYPE_REG, arg, TCG_REG_SP, 4 * i);
1161    }
1162    return i + 1;
1163}
1164
1165static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg)
1166{
1167    TCGReg tmp = TCG_TMP0;
1168    if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1169        tmp = tcg_target_call_iarg_regs[i];
1170    }
1171    tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff);
1172    return tcg_out_call_iarg_reg(s, i, tmp);
1173}
1174
1175static int tcg_out_call_iarg_reg16(TCGContext *s, int i, TCGReg arg)
1176{
1177    TCGReg tmp = TCG_TMP0;
1178    if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1179        tmp = tcg_target_call_iarg_regs[i];
1180    }
1181    tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xffff);
1182    return tcg_out_call_iarg_reg(s, i, tmp);
1183}
1184
1185static int tcg_out_call_iarg_imm(TCGContext *s, int i, TCGArg arg)
1186{
1187    TCGReg tmp = TCG_TMP0;
1188    if (arg == 0) {
1189        tmp = TCG_REG_ZERO;
1190    } else {
1191        if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1192            tmp = tcg_target_call_iarg_regs[i];
1193        }
1194        tcg_out_movi(s, TCG_TYPE_REG, tmp, arg);
1195    }
1196    return tcg_out_call_iarg_reg(s, i, tmp);
1197}
1198
1199static int tcg_out_call_iarg_reg2(TCGContext *s, int i, TCGReg al, TCGReg ah)
1200{
1201    tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
1202    i = (i + 1) & ~1;
1203    i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? ah : al));
1204    i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? al : ah));
1205    return i;
1206}
1207
1208/* Perform the tlb comparison operation.  The complete host address is
1209   placed in BASE.  Clobbers TMP0, TMP1, TMP2, A0.  */
1210static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl,
1211                             TCGReg addrh, TCGMemOpIdx oi,
1212                             tcg_insn_unit *label_ptr[2], bool is_load)
1213{
1214    TCGMemOp opc = get_memop(oi);
1215    unsigned s_bits = opc & MO_SIZE;
1216    unsigned a_bits = get_alignment_bits(opc);
1217    target_ulong mask;
1218    int mem_index = get_mmuidx(oi);
1219    int cmp_off
1220        = (is_load
1221           ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1222           : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1223    int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1224
1225    tcg_out_opc_sa(s, ALIAS_TSRL, TCG_REG_A0, addrl,
1226                   TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1227    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0,
1228                    (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1229    tcg_out_opc_reg(s, ALIAS_PADD, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1230
1231    /* Compensate for very large offsets.  */
1232    while (add_off >= 0x8000) {
1233        /* Most target env are smaller than 32k, but a few are larger than 64k,
1234         * so handle an arbitrarily large offset.
1235         */
1236        tcg_out_opc_imm(s, ALIAS_PADDI, TCG_REG_A0, TCG_REG_A0, 0x7ff0);
1237        cmp_off -= 0x7ff0;
1238        add_off -= 0x7ff0;
1239    }
1240
1241    /* We don't currently support unaligned accesses.
1242       We could do so with mips32r6.  */
1243    if (a_bits < s_bits) {
1244        a_bits = s_bits;
1245    }
1246
1247    mask = (target_ulong)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
1248
1249    /* Load the (low half) tlb comparator.  Mask the page bits, keeping the
1250       alignment bits to compare against.  */
1251    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1252        tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_REG_A0, cmp_off + LO_OFF);
1253        tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1, mask);
1254    } else {
1255        tcg_out_ldst(s,
1256                    (TARGET_LONG_BITS == 64 ? OPC_LD
1257                    : TCG_TARGET_REG_BITS == 64 ? OPC_LWU : OPC_LW),
1258                    TCG_TMP0, TCG_REG_A0, cmp_off);
1259        tcg_out_movi(s, TCG_TYPE_TL, TCG_TMP1, mask);
1260        /* No second compare is required here;
1261           load the tlb addend for the fast path.  */
1262        tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_REG_A0, add_off);
1263    }
1264    tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl);
1265
1266    /* Zero extend a 32-bit guest address for a 64-bit host. */
1267    if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1268        tcg_out_ext32u(s, base, addrl);
1269        addrl = base;
1270    }
1271
1272    label_ptr[0] = s->code_ptr;
1273    tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
1274
1275    /* Load and test the high half tlb comparator.  */
1276    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1277        /* delay slot */
1278        tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_REG_A0, cmp_off + HI_OFF);
1279
1280        /* Load the tlb addend for the fast path.  */
1281        tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_REG_A0, add_off);
1282
1283        label_ptr[1] = s->code_ptr;
1284        tcg_out_opc_br(s, OPC_BNE, addrh, TCG_TMP0);
1285    }
1286
1287    /* delay slot */
1288    tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP2, addrl);
1289}
1290
1291static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
1292                                TCGType ext,
1293                                TCGReg datalo, TCGReg datahi,
1294                                TCGReg addrlo, TCGReg addrhi,
1295                                void *raddr, tcg_insn_unit *label_ptr[2])
1296{
1297    TCGLabelQemuLdst *label = new_ldst_label(s);
1298
1299    label->is_ld = is_ld;
1300    label->oi = oi;
1301    label->type = ext;
1302    label->datalo_reg = datalo;
1303    label->datahi_reg = datahi;
1304    label->addrlo_reg = addrlo;
1305    label->addrhi_reg = addrhi;
1306    label->raddr = raddr;
1307    label->label_ptr[0] = label_ptr[0];
1308    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1309        label->label_ptr[1] = label_ptr[1];
1310    }
1311}
1312
1313static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1314{
1315    TCGMemOpIdx oi = l->oi;
1316    TCGMemOp opc = get_memop(oi);
1317    TCGReg v0;
1318    int i;
1319
1320    /* resolve label address */
1321    reloc_pc16(l->label_ptr[0], s->code_ptr);
1322    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1323        reloc_pc16(l->label_ptr[1], s->code_ptr);
1324    }
1325
1326    i = 1;
1327    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1328        i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1329    } else {
1330        i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1331    }
1332    i = tcg_out_call_iarg_imm(s, i, oi);
1333    i = tcg_out_call_iarg_imm(s, i, (intptr_t)l->raddr);
1334    tcg_out_call_int(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)], false);
1335    /* delay slot */
1336    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1337
1338    v0 = l->datalo_reg;
1339    if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
1340        /* We eliminated V0 from the possible output registers, so it
1341           cannot be clobbered here.  So we must move V1 first.  */
1342        if (MIPS_BE) {
1343            tcg_out_mov(s, TCG_TYPE_I32, v0, TCG_REG_V1);
1344            v0 = l->datahi_reg;
1345        } else {
1346            tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_V1);
1347        }
1348    }
1349
1350    reloc_pc16(s->code_ptr, l->raddr);
1351    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1352    /* delay slot */
1353    if (TCG_TARGET_REG_BITS == 64 && l->type == TCG_TYPE_I32) {
1354        /* we always sign-extend 32-bit loads */
1355        tcg_out_opc_sa(s, OPC_SLL, v0, TCG_REG_V0, 0);
1356    } else {
1357        tcg_out_opc_reg(s, OPC_OR, v0, TCG_REG_V0, TCG_REG_ZERO);
1358    }
1359}
1360
1361static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1362{
1363    TCGMemOpIdx oi = l->oi;
1364    TCGMemOp opc = get_memop(oi);
1365    TCGMemOp s_bits = opc & MO_SIZE;
1366    int i;
1367
1368    /* resolve label address */
1369    reloc_pc16(l->label_ptr[0], s->code_ptr);
1370    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1371        reloc_pc16(l->label_ptr[1], s->code_ptr);
1372    }
1373
1374    i = 1;
1375    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1376        i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1377    } else {
1378        i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1379    }
1380    switch (s_bits) {
1381    case MO_8:
1382        i = tcg_out_call_iarg_reg8(s, i, l->datalo_reg);
1383        break;
1384    case MO_16:
1385        i = tcg_out_call_iarg_reg16(s, i, l->datalo_reg);
1386        break;
1387    case MO_32:
1388        i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1389        break;
1390    case MO_64:
1391        if (TCG_TARGET_REG_BITS == 32) {
1392            i = tcg_out_call_iarg_reg2(s, i, l->datalo_reg, l->datahi_reg);
1393        } else {
1394            i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1395        }
1396        break;
1397    default:
1398        tcg_abort();
1399    }
1400    i = tcg_out_call_iarg_imm(s, i, oi);
1401
1402    /* Tail call to the store helper.  Thus force the return address
1403       computation to take place in the return address register.  */
1404    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)l->raddr);
1405    i = tcg_out_call_iarg_reg(s, i, TCG_REG_RA);
1406    tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
1407    /* delay slot */
1408    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1409}
1410#endif
1411
1412static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1413                                   TCGReg base, TCGMemOp opc, bool is_64)
1414{
1415    switch (opc & (MO_SSIZE | MO_BSWAP)) {
1416    case MO_UB:
1417        tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
1418        break;
1419    case MO_SB:
1420        tcg_out_opc_imm(s, OPC_LB, lo, base, 0);
1421        break;
1422    case MO_UW | MO_BSWAP:
1423        tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1424        tcg_out_bswap16(s, lo, TCG_TMP1);
1425        break;
1426    case MO_UW:
1427        tcg_out_opc_imm(s, OPC_LHU, lo, base, 0);
1428        break;
1429    case MO_SW | MO_BSWAP:
1430        tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1431        tcg_out_bswap16s(s, lo, TCG_TMP1);
1432        break;
1433    case MO_SW:
1434        tcg_out_opc_imm(s, OPC_LH, lo, base, 0);
1435        break;
1436    case MO_UL | MO_BSWAP:
1437        if (TCG_TARGET_REG_BITS == 64 && is_64) {
1438            if (use_mips32r2_instructions) {
1439                tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
1440                tcg_out_bswap32u(s, lo, lo);
1441            } else {
1442                tcg_out_bswap_subr(s, bswap32u_addr);
1443                /* delay slot */
1444                tcg_out_opc_imm(s, OPC_LWU, TCG_TMP0, base, 0);
1445                tcg_out_mov(s, TCG_TYPE_I64, lo, TCG_TMP3);
1446            }
1447            break;
1448        }
1449        /* FALLTHRU */
1450    case MO_SL | MO_BSWAP:
1451        if (use_mips32r2_instructions) {
1452            tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1453            tcg_out_bswap32(s, lo, lo);
1454        } else {
1455            tcg_out_bswap_subr(s, bswap32_addr);
1456            /* delay slot */
1457            tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1458            tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_TMP3);
1459        }
1460        break;
1461    case MO_UL:
1462        if (TCG_TARGET_REG_BITS == 64 && is_64) {
1463            tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
1464            break;
1465        }
1466        /* FALLTHRU */
1467    case MO_SL:
1468        tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1469        break;
1470    case MO_Q | MO_BSWAP:
1471        if (TCG_TARGET_REG_BITS == 64) {
1472            if (use_mips32r2_instructions) {
1473                tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
1474                tcg_out_bswap64(s, lo, lo);
1475            } else {
1476                tcg_out_bswap_subr(s, bswap64_addr);
1477                /* delay slot */
1478                tcg_out_opc_imm(s, OPC_LD, TCG_TMP0, base, 0);
1479                tcg_out_mov(s, TCG_TYPE_I64, lo, TCG_TMP3);
1480            }
1481        } else if (use_mips32r2_instructions) {
1482            tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1483            tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, 4);
1484            tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, TCG_TMP0);
1485            tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, TCG_TMP1);
1486            tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? lo : hi, TCG_TMP0, 16);
1487            tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? hi : lo, TCG_TMP1, 16);
1488        } else {
1489            tcg_out_bswap_subr(s, bswap32_addr);
1490            /* delay slot */
1491            tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1492            tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 4);
1493            tcg_out_bswap_subr(s, bswap32_addr);
1494            /* delay slot */
1495            tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? lo : hi, TCG_TMP3);
1496            tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? hi : lo, TCG_TMP3);
1497        }
1498        break;
1499    case MO_Q:
1500        /* Prefer to load from offset 0 first, but allow for overlap.  */
1501        if (TCG_TARGET_REG_BITS == 64) {
1502            tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
1503        } else if (MIPS_BE ? hi != base : lo == base) {
1504            tcg_out_opc_imm(s, OPC_LW, hi, base, HI_OFF);
1505            tcg_out_opc_imm(s, OPC_LW, lo, base, LO_OFF);
1506        } else {
1507            tcg_out_opc_imm(s, OPC_LW, lo, base, LO_OFF);
1508            tcg_out_opc_imm(s, OPC_LW, hi, base, HI_OFF);
1509        }
1510        break;
1511    default:
1512        tcg_abort();
1513    }
1514}
1515
1516static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1517{
1518    TCGReg addr_regl, addr_regh __attribute__((unused));
1519    TCGReg data_regl, data_regh;
1520    TCGMemOpIdx oi;
1521    TCGMemOp opc;
1522#if defined(CONFIG_SOFTMMU)
1523    tcg_insn_unit *label_ptr[2];
1524#endif
1525    TCGReg base = TCG_REG_A0;
1526
1527    data_regl = *args++;
1528    data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1529    addr_regl = *args++;
1530    addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1531    oi = *args++;
1532    opc = get_memop(oi);
1533
1534#if defined(CONFIG_SOFTMMU)
1535    tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 1);
1536    tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
1537    add_qemu_ldst_label(s, 1, oi,
1538                        (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1539                        data_regl, data_regh, addr_regl, addr_regh,
1540                        s->code_ptr, label_ptr);
1541#else
1542    if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1543        tcg_out_ext32u(s, base, addr_regl);
1544        addr_regl = base;
1545    }
1546    if (guest_base == 0 && data_regl != addr_regl) {
1547        base = addr_regl;
1548    } else if (guest_base == (int16_t)guest_base) {
1549        tcg_out_opc_imm(s, ALIAS_PADDI, base, addr_regl, guest_base);
1550    } else {
1551        tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl);
1552    }
1553    tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
1554#endif
1555}
1556
1557static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1558                                   TCGReg base, TCGMemOp opc)
1559{
1560    /* Don't clutter the code below with checks to avoid bswapping ZERO.  */
1561    if ((lo | hi) == 0) {
1562        opc &= ~MO_BSWAP;
1563    }
1564
1565    switch (opc & (MO_SIZE | MO_BSWAP)) {
1566    case MO_8:
1567        tcg_out_opc_imm(s, OPC_SB, lo, base, 0);
1568        break;
1569
1570    case MO_16 | MO_BSWAP:
1571        tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, lo, 0xffff);
1572        tcg_out_bswap16(s, TCG_TMP1, TCG_TMP1);
1573        lo = TCG_TMP1;
1574        /* FALLTHRU */
1575    case MO_16:
1576        tcg_out_opc_imm(s, OPC_SH, lo, base, 0);
1577        break;
1578
1579    case MO_32 | MO_BSWAP:
1580        tcg_out_bswap32(s, TCG_TMP3, lo);
1581        lo = TCG_TMP3;
1582        /* FALLTHRU */
1583    case MO_32:
1584        tcg_out_opc_imm(s, OPC_SW, lo, base, 0);
1585        break;
1586
1587    case MO_64 | MO_BSWAP:
1588        if (TCG_TARGET_REG_BITS == 64) {
1589            tcg_out_bswap64(s, TCG_TMP3, lo);
1590            tcg_out_opc_imm(s, OPC_SD, TCG_TMP3, base, 0);
1591        } else if (use_mips32r2_instructions) {
1592            tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, MIPS_BE ? lo : hi);
1593            tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, MIPS_BE ? hi : lo);
1594            tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP0, TCG_TMP0, 16);
1595            tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP1, TCG_TMP1, 16);
1596            tcg_out_opc_imm(s, OPC_SW, TCG_TMP0, base, 0);
1597            tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, 4);
1598        } else {
1599            tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? lo : hi);
1600            tcg_out_opc_imm(s, OPC_SW, TCG_TMP3, base, 0);
1601            tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? hi : lo);
1602            tcg_out_opc_imm(s, OPC_SW, TCG_TMP3, base, 4);
1603        }
1604        break;
1605    case MO_64:
1606        if (TCG_TARGET_REG_BITS == 64) {
1607            tcg_out_opc_imm(s, OPC_SD, lo, base, 0);
1608        } else {
1609            tcg_out_opc_imm(s, OPC_SW, MIPS_BE ? hi : lo, base, 0);
1610            tcg_out_opc_imm(s, OPC_SW, MIPS_BE ? lo : hi, base, 4);
1611        }
1612        break;
1613
1614    default:
1615        tcg_abort();
1616    }
1617}
1618
1619static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1620{
1621    TCGReg addr_regl, addr_regh __attribute__((unused));
1622    TCGReg data_regl, data_regh;
1623    TCGMemOpIdx oi;
1624    TCGMemOp opc;
1625#if defined(CONFIG_SOFTMMU)
1626    tcg_insn_unit *label_ptr[2];
1627#endif
1628    TCGReg base = TCG_REG_A0;
1629
1630    data_regl = *args++;
1631    data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1632    addr_regl = *args++;
1633    addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1634    oi = *args++;
1635    opc = get_memop(oi);
1636
1637#if defined(CONFIG_SOFTMMU)
1638    tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 0);
1639    tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1640    add_qemu_ldst_label(s, 0, oi,
1641                        (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1642                        data_regl, data_regh, addr_regl, addr_regh,
1643                        s->code_ptr, label_ptr);
1644#else
1645    base = TCG_REG_A0;
1646    if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1647        tcg_out_ext32u(s, base, addr_regl);
1648        addr_regl = base;
1649    }
1650    if (guest_base == 0) {
1651        base = addr_regl;
1652    } else if (guest_base == (int16_t)guest_base) {
1653        tcg_out_opc_imm(s, ALIAS_PADDI, base, addr_regl, guest_base);
1654    } else {
1655        tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl);
1656    }
1657    tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1658#endif
1659}
1660
1661static void tcg_out_mb(TCGContext *s, TCGArg a0)
1662{
1663    static const MIPSInsn sync[] = {
1664        /* Note that SYNC_MB is a slightly weaker than SYNC 0,
1665           as the former is an ordering barrier and the latter
1666           is a completion barrier.  */
1667        [0 ... TCG_MO_ALL]            = OPC_SYNC_MB,
1668        [TCG_MO_LD_LD]                = OPC_SYNC_RMB,
1669        [TCG_MO_ST_ST]                = OPC_SYNC_WMB,
1670        [TCG_MO_LD_ST]                = OPC_SYNC_RELEASE,
1671        [TCG_MO_LD_ST | TCG_MO_ST_ST] = OPC_SYNC_RELEASE,
1672        [TCG_MO_LD_ST | TCG_MO_LD_LD] = OPC_SYNC_ACQUIRE,
1673    };
1674    tcg_out32(s, sync[a0 & TCG_MO_ALL]);
1675}
1676
1677static void tcg_out_clz(TCGContext *s, MIPSInsn opcv2, MIPSInsn opcv6,
1678                        int width, TCGReg a0, TCGReg a1, TCGArg a2)
1679{
1680    if (use_mips32r6_instructions) {
1681        if (a2 == width) {
1682            tcg_out_opc_reg(s, opcv6, a0, a1, 0);
1683        } else {
1684            tcg_out_opc_reg(s, opcv6, TCG_TMP0, a1, 0);
1685            tcg_out_movcond(s, TCG_COND_EQ, a0, a1, 0, a2, TCG_TMP0);
1686        }
1687    } else {
1688        if (a2 == width) {
1689            tcg_out_opc_reg(s, opcv2, a0, a1, a1);
1690        } else if (a0 == a2) {
1691            tcg_out_opc_reg(s, opcv2, TCG_TMP0, a1, a1);
1692            tcg_out_opc_reg(s, OPC_MOVN, a0, TCG_TMP0, a1);
1693        } else if (a0 != a1) {
1694            tcg_out_opc_reg(s, opcv2, a0, a1, a1);
1695            tcg_out_opc_reg(s, OPC_MOVZ, a0, a2, a1);
1696        } else {
1697            tcg_out_opc_reg(s, opcv2, TCG_TMP0, a1, a1);
1698            tcg_out_opc_reg(s, OPC_MOVZ, TCG_TMP0, a2, a1);
1699            tcg_out_mov(s, TCG_TYPE_REG, a0, TCG_TMP0);
1700        }
1701    }
1702}
1703
1704static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1705                              const TCGArg *args, const int *const_args)
1706{
1707    MIPSInsn i1, i2;
1708    TCGArg a0, a1, a2;
1709    int c2;
1710
1711    a0 = args[0];
1712    a1 = args[1];
1713    a2 = args[2];
1714    c2 = const_args[2];
1715
1716    switch (opc) {
1717    case INDEX_op_exit_tb:
1718        {
1719            TCGReg b0 = TCG_REG_ZERO;
1720
1721            a0 = (intptr_t)a0;
1722            if (a0 & ~0xffff) {
1723                tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, a0 & ~0xffff);
1724                b0 = TCG_REG_V0;
1725            }
1726            if (!tcg_out_opc_jmp(s, OPC_J, tb_ret_addr)) {
1727                tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0,
1728                             (uintptr_t)tb_ret_addr);
1729                tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1730            }
1731            tcg_out_opc_imm(s, OPC_ORI, TCG_REG_V0, b0, a0 & 0xffff);
1732        }
1733        break;
1734    case INDEX_op_goto_tb:
1735        if (s->tb_jmp_insn_offset) {
1736            /* direct jump method */
1737            s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1738            /* Avoid clobbering the address during retranslation.  */
1739            tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff));
1740        } else {
1741            /* indirect jump method */
1742            tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
1743                       (uintptr_t)(s->tb_jmp_target_addr + a0));
1744            tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1745        }
1746        tcg_out_nop(s);
1747        set_jmp_reset_offset(s, a0);
1748        break;
1749    case INDEX_op_goto_ptr:
1750        /* jmp to the given host address (could be epilogue) */
1751        tcg_out_opc_reg(s, OPC_JR, 0, a0, 0);
1752        tcg_out_nop(s);
1753        break;
1754    case INDEX_op_br:
1755        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
1756                       arg_label(a0));
1757        break;
1758
1759    case INDEX_op_ld8u_i32:
1760    case INDEX_op_ld8u_i64:
1761        i1 = OPC_LBU;
1762        goto do_ldst;
1763    case INDEX_op_ld8s_i32:
1764    case INDEX_op_ld8s_i64:
1765        i1 = OPC_LB;
1766        goto do_ldst;
1767    case INDEX_op_ld16u_i32:
1768    case INDEX_op_ld16u_i64:
1769        i1 = OPC_LHU;
1770        goto do_ldst;
1771    case INDEX_op_ld16s_i32:
1772    case INDEX_op_ld16s_i64:
1773        i1 = OPC_LH;
1774        goto do_ldst;
1775    case INDEX_op_ld_i32:
1776    case INDEX_op_ld32s_i64:
1777        i1 = OPC_LW;
1778        goto do_ldst;
1779    case INDEX_op_ld32u_i64:
1780        i1 = OPC_LWU;
1781        goto do_ldst;
1782    case INDEX_op_ld_i64:
1783        i1 = OPC_LD;
1784        goto do_ldst;
1785    case INDEX_op_st8_i32:
1786    case INDEX_op_st8_i64:
1787        i1 = OPC_SB;
1788        goto do_ldst;
1789    case INDEX_op_st16_i32:
1790    case INDEX_op_st16_i64:
1791        i1 = OPC_SH;
1792        goto do_ldst;
1793    case INDEX_op_st_i32:
1794    case INDEX_op_st32_i64:
1795        i1 = OPC_SW;
1796        goto do_ldst;
1797    case INDEX_op_st_i64:
1798        i1 = OPC_SD;
1799    do_ldst:
1800        tcg_out_ldst(s, i1, a0, a1, a2);
1801        break;
1802
1803    case INDEX_op_add_i32:
1804        i1 = OPC_ADDU, i2 = OPC_ADDIU;
1805        goto do_binary;
1806    case INDEX_op_add_i64:
1807        i1 = OPC_DADDU, i2 = OPC_DADDIU;
1808        goto do_binary;
1809    case INDEX_op_or_i32:
1810    case INDEX_op_or_i64:
1811        i1 = OPC_OR, i2 = OPC_ORI;
1812        goto do_binary;
1813    case INDEX_op_xor_i32:
1814    case INDEX_op_xor_i64:
1815        i1 = OPC_XOR, i2 = OPC_XORI;
1816    do_binary:
1817        if (c2) {
1818            tcg_out_opc_imm(s, i2, a0, a1, a2);
1819            break;
1820        }
1821    do_binaryv:
1822        tcg_out_opc_reg(s, i1, a0, a1, a2);
1823        break;
1824
1825    case INDEX_op_sub_i32:
1826        i1 = OPC_SUBU, i2 = OPC_ADDIU;
1827        goto do_subtract;
1828    case INDEX_op_sub_i64:
1829        i1 = OPC_DSUBU, i2 = OPC_DADDIU;
1830    do_subtract:
1831        if (c2) {
1832            tcg_out_opc_imm(s, i2, a0, a1, -a2);
1833            break;
1834        }
1835        goto do_binaryv;
1836    case INDEX_op_and_i32:
1837        if (c2 && a2 != (uint16_t)a2) {
1838            int msb = ctz32(~a2) - 1;
1839            tcg_debug_assert(use_mips32r2_instructions);
1840            tcg_debug_assert(is_p2m1(a2));
1841            tcg_out_opc_bf(s, OPC_EXT, a0, a1, msb, 0);
1842            break;
1843        }
1844        i1 = OPC_AND, i2 = OPC_ANDI;
1845        goto do_binary;
1846    case INDEX_op_and_i64:
1847        if (c2 && a2 != (uint16_t)a2) {
1848            int msb = ctz64(~a2) - 1;
1849            tcg_debug_assert(use_mips32r2_instructions);
1850            tcg_debug_assert(is_p2m1(a2));
1851            tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU, a0, a1, msb, 0);
1852            break;
1853        }
1854        i1 = OPC_AND, i2 = OPC_ANDI;
1855        goto do_binary;
1856    case INDEX_op_nor_i32:
1857    case INDEX_op_nor_i64:
1858        i1 = OPC_NOR;
1859        goto do_binaryv;
1860
1861    case INDEX_op_mul_i32:
1862        if (use_mips32_instructions) {
1863            tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2);
1864            break;
1865        }
1866        i1 = OPC_MULT, i2 = OPC_MFLO;
1867        goto do_hilo1;
1868    case INDEX_op_mulsh_i32:
1869        if (use_mips32r6_instructions) {
1870            tcg_out_opc_reg(s, OPC_MUH, a0, a1, a2);
1871            break;
1872        }
1873        i1 = OPC_MULT, i2 = OPC_MFHI;
1874        goto do_hilo1;
1875    case INDEX_op_muluh_i32:
1876        if (use_mips32r6_instructions) {
1877            tcg_out_opc_reg(s, OPC_MUHU, a0, a1, a2);
1878            break;
1879        }
1880        i1 = OPC_MULTU, i2 = OPC_MFHI;
1881        goto do_hilo1;
1882    case INDEX_op_div_i32:
1883        if (use_mips32r6_instructions) {
1884            tcg_out_opc_reg(s, OPC_DIV_R6, a0, a1, a2);
1885            break;
1886        }
1887        i1 = OPC_DIV, i2 = OPC_MFLO;
1888        goto do_hilo1;
1889    case INDEX_op_divu_i32:
1890        if (use_mips32r6_instructions) {
1891            tcg_out_opc_reg(s, OPC_DIVU_R6, a0, a1, a2);
1892            break;
1893        }
1894        i1 = OPC_DIVU, i2 = OPC_MFLO;
1895        goto do_hilo1;
1896    case INDEX_op_rem_i32:
1897        if (use_mips32r6_instructions) {
1898            tcg_out_opc_reg(s, OPC_MOD, a0, a1, a2);
1899            break;
1900        }
1901        i1 = OPC_DIV, i2 = OPC_MFHI;
1902        goto do_hilo1;
1903    case INDEX_op_remu_i32:
1904        if (use_mips32r6_instructions) {
1905            tcg_out_opc_reg(s, OPC_MODU, a0, a1, a2);
1906            break;
1907        }
1908        i1 = OPC_DIVU, i2 = OPC_MFHI;
1909        goto do_hilo1;
1910    case INDEX_op_mul_i64:
1911        if (use_mips32r6_instructions) {
1912            tcg_out_opc_reg(s, OPC_DMUL, a0, a1, a2);
1913            break;
1914        }
1915        i1 = OPC_DMULT, i2 = OPC_MFLO;
1916        goto do_hilo1;
1917    case INDEX_op_mulsh_i64:
1918        if (use_mips32r6_instructions) {
1919            tcg_out_opc_reg(s, OPC_DMUH, a0, a1, a2);
1920            break;
1921        }
1922        i1 = OPC_DMULT, i2 = OPC_MFHI;
1923        goto do_hilo1;
1924    case INDEX_op_muluh_i64:
1925        if (use_mips32r6_instructions) {
1926            tcg_out_opc_reg(s, OPC_DMUHU, a0, a1, a2);
1927            break;
1928        }
1929        i1 = OPC_DMULTU, i2 = OPC_MFHI;
1930        goto do_hilo1;
1931    case INDEX_op_div_i64:
1932        if (use_mips32r6_instructions) {
1933            tcg_out_opc_reg(s, OPC_DDIV_R6, a0, a1, a2);
1934            break;
1935        }
1936        i1 = OPC_DDIV, i2 = OPC_MFLO;
1937        goto do_hilo1;
1938    case INDEX_op_divu_i64:
1939        if (use_mips32r6_instructions) {
1940            tcg_out_opc_reg(s, OPC_DDIVU_R6, a0, a1, a2);
1941            break;
1942        }
1943        i1 = OPC_DDIVU, i2 = OPC_MFLO;
1944        goto do_hilo1;
1945    case INDEX_op_rem_i64:
1946        if (use_mips32r6_instructions) {
1947            tcg_out_opc_reg(s, OPC_DMOD, a0, a1, a2);
1948            break;
1949        }
1950        i1 = OPC_DDIV, i2 = OPC_MFHI;
1951        goto do_hilo1;
1952    case INDEX_op_remu_i64:
1953        if (use_mips32r6_instructions) {
1954            tcg_out_opc_reg(s, OPC_DMODU, a0, a1, a2);
1955            break;
1956        }
1957        i1 = OPC_DDIVU, i2 = OPC_MFHI;
1958    do_hilo1:
1959        tcg_out_opc_reg(s, i1, 0, a1, a2);
1960        tcg_out_opc_reg(s, i2, a0, 0, 0);
1961        break;
1962
1963    case INDEX_op_muls2_i32:
1964        i1 = OPC_MULT;
1965        goto do_hilo2;
1966    case INDEX_op_mulu2_i32:
1967        i1 = OPC_MULTU;
1968        goto do_hilo2;
1969    case INDEX_op_muls2_i64:
1970        i1 = OPC_DMULT;
1971        goto do_hilo2;
1972    case INDEX_op_mulu2_i64:
1973        i1 = OPC_DMULTU;
1974    do_hilo2:
1975        tcg_out_opc_reg(s, i1, 0, a2, args[3]);
1976        tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1977        tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1978        break;
1979
1980    case INDEX_op_not_i32:
1981    case INDEX_op_not_i64:
1982        i1 = OPC_NOR;
1983        goto do_unary;
1984    case INDEX_op_bswap16_i32:
1985    case INDEX_op_bswap16_i64:
1986        i1 = OPC_WSBH;
1987        goto do_unary;
1988    case INDEX_op_ext8s_i32:
1989    case INDEX_op_ext8s_i64:
1990        i1 = OPC_SEB;
1991        goto do_unary;
1992    case INDEX_op_ext16s_i32:
1993    case INDEX_op_ext16s_i64:
1994        i1 = OPC_SEH;
1995    do_unary:
1996        tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1);
1997        break;
1998
1999    case INDEX_op_bswap32_i32:
2000        tcg_out_bswap32(s, a0, a1);
2001        break;
2002    case INDEX_op_bswap32_i64:
2003        tcg_out_bswap32u(s, a0, a1);
2004        break;
2005    case INDEX_op_bswap64_i64:
2006        tcg_out_bswap64(s, a0, a1);
2007        break;
2008    case INDEX_op_extrh_i64_i32:
2009        tcg_out_dsra(s, a0, a1, 32);
2010        break;
2011    case INDEX_op_ext32s_i64:
2012    case INDEX_op_ext_i32_i64:
2013    case INDEX_op_extrl_i64_i32:
2014        tcg_out_opc_sa(s, OPC_SLL, a0, a1, 0);
2015        break;
2016    case INDEX_op_ext32u_i64:
2017    case INDEX_op_extu_i32_i64:
2018        tcg_out_ext32u(s, a0, a1);
2019        break;
2020
2021    case INDEX_op_sar_i32:
2022        i1 = OPC_SRAV, i2 = OPC_SRA;
2023        goto do_shift;
2024    case INDEX_op_shl_i32:
2025        i1 = OPC_SLLV, i2 = OPC_SLL;
2026        goto do_shift;
2027    case INDEX_op_shr_i32:
2028        i1 = OPC_SRLV, i2 = OPC_SRL;
2029        goto do_shift;
2030    case INDEX_op_rotr_i32:
2031        i1 = OPC_ROTRV, i2 = OPC_ROTR;
2032    do_shift:
2033        if (c2) {
2034            tcg_out_opc_sa(s, i2, a0, a1, a2);
2035            break;
2036        }
2037    do_shiftv:
2038        tcg_out_opc_reg(s, i1, a0, a2, a1);
2039        break;
2040    case INDEX_op_rotl_i32:
2041        if (c2) {
2042            tcg_out_opc_sa(s, OPC_ROTR, a0, a1, 32 - a2);
2043        } else {
2044            tcg_out_opc_reg(s, OPC_SUBU, TCG_TMP0, TCG_REG_ZERO, a2);
2045            tcg_out_opc_reg(s, OPC_ROTRV, a0, TCG_TMP0, a1);
2046        }
2047        break;
2048    case INDEX_op_sar_i64:
2049        if (c2) {
2050            tcg_out_dsra(s, a0, a1, a2);
2051            break;
2052        }
2053        i1 = OPC_DSRAV;
2054        goto do_shiftv;
2055    case INDEX_op_shl_i64:
2056        if (c2) {
2057            tcg_out_dsll(s, a0, a1, a2);
2058            break;
2059        }
2060        i1 = OPC_DSLLV;
2061        goto do_shiftv;
2062    case INDEX_op_shr_i64:
2063        if (c2) {
2064            tcg_out_dsrl(s, a0, a1, a2);
2065            break;
2066        }
2067        i1 = OPC_DSRLV;
2068        goto do_shiftv;
2069    case INDEX_op_rotr_i64:
2070        if (c2) {
2071            tcg_out_opc_sa64(s, OPC_DROTR, OPC_DROTR32, a0, a1, a2);
2072            break;
2073        }
2074        i1 = OPC_DROTRV;
2075        goto do_shiftv;
2076    case INDEX_op_rotl_i64:
2077        if (c2) {
2078            tcg_out_opc_sa64(s, OPC_DROTR, OPC_DROTR32, a0, a1, 64 - a2);
2079        } else {
2080            tcg_out_opc_reg(s, OPC_DSUBU, TCG_TMP0, TCG_REG_ZERO, a2);
2081            tcg_out_opc_reg(s, OPC_DROTRV, a0, TCG_TMP0, a1);
2082        }
2083        break;
2084
2085    case INDEX_op_clz_i32:
2086        tcg_out_clz(s, OPC_CLZ, OPC_CLZ_R6, 32, a0, a1, a2);
2087        break;
2088    case INDEX_op_clz_i64:
2089        tcg_out_clz(s, OPC_DCLZ, OPC_DCLZ_R6, 64, a0, a1, a2);
2090        break;
2091
2092    case INDEX_op_deposit_i32:
2093        tcg_out_opc_bf(s, OPC_INS, a0, a2, args[3] + args[4] - 1, args[3]);
2094        break;
2095    case INDEX_op_deposit_i64:
2096        tcg_out_opc_bf64(s, OPC_DINS, OPC_DINSM, OPC_DINSU, a0, a2,
2097                         args[3] + args[4] - 1, args[3]);
2098        break;
2099    case INDEX_op_extract_i32:
2100        tcg_out_opc_bf(s, OPC_EXT, a0, a1, args[3] - 1, a2);
2101        break;
2102    case INDEX_op_extract_i64:
2103        tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU, a0, a1,
2104                         args[3] - 1, a2);
2105        break;
2106
2107    case INDEX_op_brcond_i32:
2108    case INDEX_op_brcond_i64:
2109        tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
2110        break;
2111    case INDEX_op_brcond2_i32:
2112        tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
2113        break;
2114
2115    case INDEX_op_movcond_i32:
2116    case INDEX_op_movcond_i64:
2117        tcg_out_movcond(s, args[5], a0, a1, a2, args[3], args[4]);
2118        break;
2119
2120    case INDEX_op_setcond_i32:
2121    case INDEX_op_setcond_i64:
2122        tcg_out_setcond(s, args[3], a0, a1, a2);
2123        break;
2124    case INDEX_op_setcond2_i32:
2125        tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
2126        break;
2127
2128    case INDEX_op_qemu_ld_i32:
2129        tcg_out_qemu_ld(s, args, false);
2130        break;
2131    case INDEX_op_qemu_ld_i64:
2132        tcg_out_qemu_ld(s, args, true);
2133        break;
2134    case INDEX_op_qemu_st_i32:
2135        tcg_out_qemu_st(s, args, false);
2136        break;
2137    case INDEX_op_qemu_st_i64:
2138        tcg_out_qemu_st(s, args, true);
2139        break;
2140
2141    case INDEX_op_add2_i32:
2142        tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
2143                        const_args[4], const_args[5], false);
2144        break;
2145    case INDEX_op_sub2_i32:
2146        tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
2147                        const_args[4], const_args[5], true);
2148        break;
2149
2150    case INDEX_op_mb:
2151        tcg_out_mb(s, a0);
2152        break;
2153    case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
2154    case INDEX_op_mov_i64:
2155    case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
2156    case INDEX_op_movi_i64:
2157    case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
2158    default:
2159        tcg_abort();
2160    }
2161}
2162
2163static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2164{
2165    static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
2166    static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
2167    static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
2168    static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
2169    static const TCGTargetOpDef SZ_S = { .args_ct_str = { "SZ", "S" } };
2170    static const TCGTargetOpDef rZ_rZ = { .args_ct_str = { "rZ", "rZ" } };
2171    static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } };
2172    static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
2173    static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
2174    static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
2175    static const TCGTargetOpDef r_r_rJ = { .args_ct_str = { "r", "r", "rJ" } };
2176    static const TCGTargetOpDef SZ_S_S = { .args_ct_str = { "SZ", "S", "S" } };
2177    static const TCGTargetOpDef SZ_SZ_S
2178        = { .args_ct_str = { "SZ", "SZ", "S" } };
2179    static const TCGTargetOpDef SZ_SZ_S_S
2180        = { .args_ct_str = { "SZ", "SZ", "S", "S" } };
2181    static const TCGTargetOpDef r_rZ_rN
2182        = { .args_ct_str = { "r", "rZ", "rN" } };
2183    static const TCGTargetOpDef r_rZ_rZ
2184        = { .args_ct_str = { "r", "rZ", "rZ" } };
2185    static const TCGTargetOpDef r_r_rIK
2186        = { .args_ct_str = { "r", "r", "rIK" } };
2187    static const TCGTargetOpDef r_r_rWZ
2188        = { .args_ct_str = { "r", "r", "rWZ" } };
2189    static const TCGTargetOpDef r_r_r_r
2190        = { .args_ct_str = { "r", "r", "r", "r" } };
2191    static const TCGTargetOpDef r_r_L_L
2192        = { .args_ct_str = { "r", "r", "L", "L" } };
2193    static const TCGTargetOpDef dep
2194        = { .args_ct_str = { "r", "0", "rZ" } };
2195    static const TCGTargetOpDef movc
2196        = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "0" } };
2197    static const TCGTargetOpDef movc_r6
2198        = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
2199    static const TCGTargetOpDef add2
2200        = { .args_ct_str = { "r", "r", "rZ", "rZ", "rN", "rN" } };
2201    static const TCGTargetOpDef br2
2202        = { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } };
2203    static const TCGTargetOpDef setc2
2204        = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
2205
2206    switch (op) {
2207    case INDEX_op_goto_ptr:
2208        return &r;
2209
2210    case INDEX_op_ld8u_i32:
2211    case INDEX_op_ld8s_i32:
2212    case INDEX_op_ld16u_i32:
2213    case INDEX_op_ld16s_i32:
2214    case INDEX_op_ld_i32:
2215    case INDEX_op_not_i32:
2216    case INDEX_op_bswap16_i32:
2217    case INDEX_op_bswap32_i32:
2218    case INDEX_op_ext8s_i32:
2219    case INDEX_op_ext16s_i32:
2220    case INDEX_op_extract_i32:
2221    case INDEX_op_ld8u_i64:
2222    case INDEX_op_ld8s_i64:
2223    case INDEX_op_ld16u_i64:
2224    case INDEX_op_ld16s_i64:
2225    case INDEX_op_ld32s_i64:
2226    case INDEX_op_ld32u_i64:
2227    case INDEX_op_ld_i64:
2228    case INDEX_op_not_i64:
2229    case INDEX_op_bswap16_i64:
2230    case INDEX_op_bswap32_i64:
2231    case INDEX_op_bswap64_i64:
2232    case INDEX_op_ext8s_i64:
2233    case INDEX_op_ext16s_i64:
2234    case INDEX_op_ext32s_i64:
2235    case INDEX_op_ext32u_i64:
2236    case INDEX_op_ext_i32_i64:
2237    case INDEX_op_extu_i32_i64:
2238    case INDEX_op_extrl_i64_i32:
2239    case INDEX_op_extrh_i64_i32:
2240    case INDEX_op_extract_i64:
2241        return &r_r;
2242
2243    case INDEX_op_st8_i32:
2244    case INDEX_op_st16_i32:
2245    case INDEX_op_st_i32:
2246    case INDEX_op_st8_i64:
2247    case INDEX_op_st16_i64:
2248    case INDEX_op_st32_i64:
2249    case INDEX_op_st_i64:
2250        return &rZ_r;
2251
2252    case INDEX_op_add_i32:
2253    case INDEX_op_add_i64:
2254        return &r_r_rJ;
2255    case INDEX_op_sub_i32:
2256    case INDEX_op_sub_i64:
2257        return &r_rZ_rN;
2258    case INDEX_op_mul_i32:
2259    case INDEX_op_mulsh_i32:
2260    case INDEX_op_muluh_i32:
2261    case INDEX_op_div_i32:
2262    case INDEX_op_divu_i32:
2263    case INDEX_op_rem_i32:
2264    case INDEX_op_remu_i32:
2265    case INDEX_op_nor_i32:
2266    case INDEX_op_setcond_i32:
2267    case INDEX_op_mul_i64:
2268    case INDEX_op_mulsh_i64:
2269    case INDEX_op_muluh_i64:
2270    case INDEX_op_div_i64:
2271    case INDEX_op_divu_i64:
2272    case INDEX_op_rem_i64:
2273    case INDEX_op_remu_i64:
2274    case INDEX_op_nor_i64:
2275    case INDEX_op_setcond_i64:
2276        return &r_rZ_rZ;
2277    case INDEX_op_muls2_i32:
2278    case INDEX_op_mulu2_i32:
2279    case INDEX_op_muls2_i64:
2280    case INDEX_op_mulu2_i64:
2281        return &r_r_r_r;
2282    case INDEX_op_and_i32:
2283    case INDEX_op_and_i64:
2284        return &r_r_rIK;
2285    case INDEX_op_or_i32:
2286    case INDEX_op_xor_i32:
2287    case INDEX_op_or_i64:
2288    case INDEX_op_xor_i64:
2289        return &r_r_rI;
2290    case INDEX_op_shl_i32:
2291    case INDEX_op_shr_i32:
2292    case INDEX_op_sar_i32:
2293    case INDEX_op_rotr_i32:
2294    case INDEX_op_rotl_i32:
2295    case INDEX_op_shl_i64:
2296    case INDEX_op_shr_i64:
2297    case INDEX_op_sar_i64:
2298    case INDEX_op_rotr_i64:
2299    case INDEX_op_rotl_i64:
2300        return &r_r_ri;
2301    case INDEX_op_clz_i32:
2302    case INDEX_op_clz_i64:
2303        return &r_r_rWZ;
2304
2305    case INDEX_op_deposit_i32:
2306    case INDEX_op_deposit_i64:
2307        return &dep;
2308    case INDEX_op_brcond_i32:
2309    case INDEX_op_brcond_i64:
2310        return &rZ_rZ;
2311    case INDEX_op_movcond_i32:
2312    case INDEX_op_movcond_i64:
2313        return use_mips32r6_instructions ? &movc_r6 : &movc;
2314
2315    case INDEX_op_add2_i32:
2316    case INDEX_op_sub2_i32:
2317        return &add2;
2318    case INDEX_op_setcond2_i32:
2319        return &setc2;
2320    case INDEX_op_brcond2_i32:
2321        return &br2;
2322
2323    case INDEX_op_qemu_ld_i32:
2324        return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
2325                ? &r_L : &r_L_L);
2326    case INDEX_op_qemu_st_i32:
2327        return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
2328                ? &SZ_S : &SZ_S_S);
2329    case INDEX_op_qemu_ld_i64:
2330        return (TCG_TARGET_REG_BITS == 64 ? &r_L
2331                : TARGET_LONG_BITS == 32 ? &r_r_L : &r_r_L_L);
2332    case INDEX_op_qemu_st_i64:
2333        return (TCG_TARGET_REG_BITS == 64 ? &SZ_S
2334                : TARGET_LONG_BITS == 32 ? &SZ_SZ_S : &SZ_SZ_S_S);
2335
2336    default:
2337        return NULL;
2338    }
2339}
2340
2341static const int tcg_target_callee_save_regs[] = {
2342    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
2343    TCG_REG_S1,
2344    TCG_REG_S2,
2345    TCG_REG_S3,
2346    TCG_REG_S4,
2347    TCG_REG_S5,
2348    TCG_REG_S6,
2349    TCG_REG_S7,
2350    TCG_REG_S8,
2351    TCG_REG_RA,       /* should be last for ABI compliance */
2352};
2353
2354/* The Linux kernel doesn't provide any information about the available
2355   instruction set. Probe it using a signal handler. */
2356
2357
2358#ifndef use_movnz_instructions
2359bool use_movnz_instructions = false;
2360#endif
2361
2362#ifndef use_mips32_instructions
2363bool use_mips32_instructions = false;
2364#endif
2365
2366#ifndef use_mips32r2_instructions
2367bool use_mips32r2_instructions = false;
2368#endif
2369
2370static volatile sig_atomic_t got_sigill;
2371
2372static void sigill_handler(int signo, siginfo_t *si, void *data)
2373{
2374    /* Skip the faulty instruction */
2375    ucontext_t *uc = (ucontext_t *)data;
2376    uc->uc_mcontext.pc += 4;
2377
2378    got_sigill = 1;
2379}
2380
2381static void tcg_target_detect_isa(void)
2382{
2383    struct sigaction sa_old, sa_new;
2384
2385    memset(&sa_new, 0, sizeof(sa_new));
2386    sa_new.sa_flags = SA_SIGINFO;
2387    sa_new.sa_sigaction = sigill_handler;
2388    sigaction(SIGILL, &sa_new, &sa_old);
2389
2390    /* Probe for movn/movz, necessary to implement movcond. */
2391#ifndef use_movnz_instructions
2392    got_sigill = 0;
2393    asm volatile(".set push\n"
2394                 ".set mips32\n"
2395                 "movn $zero, $zero, $zero\n"
2396                 "movz $zero, $zero, $zero\n"
2397                 ".set pop\n"
2398                 : : : );
2399    use_movnz_instructions = !got_sigill;
2400#endif
2401
2402    /* Probe for MIPS32 instructions. As no subsetting is allowed
2403       by the specification, it is only necessary to probe for one
2404       of the instructions. */
2405#ifndef use_mips32_instructions
2406    got_sigill = 0;
2407    asm volatile(".set push\n"
2408                 ".set mips32\n"
2409                 "mul $zero, $zero\n"
2410                 ".set pop\n"
2411                 : : : );
2412    use_mips32_instructions = !got_sigill;
2413#endif
2414
2415    /* Probe for MIPS32r2 instructions if MIPS32 instructions are
2416       available. As no subsetting is allowed by the specification,
2417       it is only necessary to probe for one of the instructions. */
2418#ifndef use_mips32r2_instructions
2419    if (use_mips32_instructions) {
2420        got_sigill = 0;
2421        asm volatile(".set push\n"
2422                     ".set mips32r2\n"
2423                     "seb $zero, $zero\n"
2424                     ".set pop\n"
2425                     : : : );
2426        use_mips32r2_instructions = !got_sigill;
2427    }
2428#endif
2429
2430    sigaction(SIGILL, &sa_old, NULL);
2431}
2432
2433static tcg_insn_unit *align_code_ptr(TCGContext *s)
2434{
2435    uintptr_t p = (uintptr_t)s->code_ptr;
2436    if (p & 15) {
2437        p = (p + 15) & -16;
2438        s->code_ptr = (void *)p;
2439    }
2440    return s->code_ptr;
2441}
2442
2443/* Stack frame parameters.  */
2444#define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
2445#define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
2446#define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
2447
2448#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
2449                     + TCG_TARGET_STACK_ALIGN - 1) \
2450                    & -TCG_TARGET_STACK_ALIGN)
2451#define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
2452
2453/* We're expecting to be able to use an immediate for frame allocation.  */
2454QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7fff);
2455
2456/* Generate global QEMU prologue and epilogue code */
2457static void tcg_target_qemu_prologue(TCGContext *s)
2458{
2459    int i;
2460
2461    tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
2462
2463    /* TB prologue */
2464    tcg_out_opc_imm(s, ALIAS_PADDI, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
2465    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2466        tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2467                   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
2468    }
2469
2470#ifndef CONFIG_SOFTMMU
2471    if (guest_base) {
2472        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
2473        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2474    }
2475#endif
2476
2477    /* Call generated code */
2478    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
2479    /* delay slot */
2480    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2481
2482    /*
2483     * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2484     * and fall through to the rest of the epilogue.
2485     */
2486    s->code_gen_epilogue = s->code_ptr;
2487    tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_V0, TCG_REG_ZERO);
2488
2489    /* TB epilogue */
2490    tb_ret_addr = s->code_ptr;
2491    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2492        tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2493                   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
2494    }
2495
2496    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2497    /* delay slot */
2498    tcg_out_opc_imm(s, ALIAS_PADDI, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
2499
2500    if (use_mips32r2_instructions) {
2501        return;
2502    }
2503
2504    /* Bswap subroutines: Input in TCG_TMP0, output in TCG_TMP3;
2505       clobbers TCG_TMP1, TCG_TMP2.  */
2506
2507    /*
2508     * bswap32 -- 32-bit swap (signed result for mips64).  a0 = abcd.
2509     */
2510    bswap32_addr = align_code_ptr(s);
2511    /* t3 = (ssss)d000 */
2512    tcg_out_opc_sa(s, OPC_SLL, TCG_TMP3, TCG_TMP0, 24);
2513    /* t1 = 000a */
2514    tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 24);
2515    /* t2 = 00c0 */
2516    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2517    /* t3 = d00a */
2518    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2519    /* t1 = 0abc */
2520    tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
2521    /* t2 = 0c00 */
2522    tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
2523    /* t1 = 00b0 */
2524    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2525    /* t3 = dc0a */
2526    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2527    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2528    /* t3 = dcba -- delay slot */
2529    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2530
2531    if (TCG_TARGET_REG_BITS == 32) {
2532        return;
2533    }
2534
2535    /*
2536     * bswap32u -- unsigned 32-bit swap.  a0 = ....abcd.
2537     */
2538    bswap32u_addr = align_code_ptr(s);
2539    /* t1 = (0000)000d */
2540    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP0, 0xff);
2541    /* t3 = 000a */
2542    tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, TCG_TMP0, 24);
2543    /* t1 = (0000)d000 */
2544    tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 24);
2545    /* t2 = 00c0 */
2546    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2547    /* t3 = d00a */
2548    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2549    /* t1 = 0abc */
2550    tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
2551    /* t2 = 0c00 */
2552    tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
2553    /* t1 = 00b0 */
2554    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2555    /* t3 = dc0a */
2556    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2557    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2558    /* t3 = dcba -- delay slot */
2559    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2560
2561    /*
2562     * bswap64 -- 64-bit swap.  a0 = abcdefgh
2563     */
2564    bswap64_addr = align_code_ptr(s);
2565    /* t3 = h0000000 */
2566    tcg_out_dsll(s, TCG_TMP3, TCG_TMP0, 56);
2567    /* t1 = 0000000a */
2568    tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 56);
2569
2570    /* t2 = 000000g0 */
2571    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2572    /* t3 = h000000a */
2573    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2574    /* t1 = 00000abc */
2575    tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 40);
2576    /* t2 = 0g000000 */
2577    tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 40);
2578    /* t1 = 000000b0 */
2579    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2580
2581    /* t3 = hg00000a */
2582    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2583    /* t2 = 0000abcd */
2584    tcg_out_dsrl(s, TCG_TMP2, TCG_TMP0, 32);
2585    /* t3 = hg0000ba */
2586    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2587
2588    /* t1 = 000000c0 */
2589    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP2, 0xff00);
2590    /* t2 = 0000000d */
2591    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP2, 0x00ff);
2592    /* t1 = 00000c00 */
2593    tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 8);
2594    /* t2 = 0000d000 */
2595    tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 24);
2596
2597    /* t3 = hg000cba */
2598    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2599    /* t1 = 00abcdef */
2600    tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 16);
2601    /* t3 = hg00dcba */
2602    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2603
2604    /* t2 = 0000000f */
2605    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP1, 0x00ff);
2606    /* t1 = 000000e0 */
2607    tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2608    /* t2 = 00f00000 */
2609    tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 40);
2610    /* t1 = 000e0000 */
2611    tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 24);
2612
2613    /* t3 = hgf0dcba */
2614    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2615    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2616    /* t3 = hgfedcba -- delay slot */
2617    tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2618}
2619
2620static void tcg_target_init(TCGContext *s)
2621{
2622    tcg_target_detect_isa();
2623    tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
2624    if (TCG_TARGET_REG_BITS == 64) {
2625        tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
2626    }
2627
2628    tcg_target_call_clobber_regs = 0;
2629    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0);
2630    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1);
2631    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A0);
2632    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A1);
2633    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A2);
2634    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A3);
2635    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T0);
2636    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T1);
2637    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T2);
2638    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T3);
2639    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T4);
2640    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T5);
2641    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T6);
2642    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T7);
2643    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T8);
2644    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T9);
2645
2646    s->reserved_regs = 0;
2647    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
2648    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
2649    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
2650    tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);     /* internal use */
2651    tcg_regset_set_reg(s->reserved_regs, TCG_TMP1);     /* internal use */
2652    tcg_regset_set_reg(s->reserved_regs, TCG_TMP2);     /* internal use */
2653    tcg_regset_set_reg(s->reserved_regs, TCG_TMP3);     /* internal use */
2654    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
2655    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
2656    tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
2657}
2658
2659void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
2660                              uintptr_t addr)
2661{
2662    atomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
2663    flush_icache_range(jmp_addr, jmp_addr + 4);
2664}
2665
2666typedef struct {
2667    DebugFrameHeader h;
2668    uint8_t fde_def_cfa[4];
2669    uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
2670} DebugFrame;
2671
2672#define ELF_HOST_MACHINE EM_MIPS
2673/* GDB doesn't appear to require proper setting of ELF_HOST_FLAGS,
2674   which is good because they're really quite complicated for MIPS.  */
2675
2676static const DebugFrame debug_frame = {
2677    .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
2678    .h.cie.id = -1,
2679    .h.cie.version = 1,
2680    .h.cie.code_align = 1,
2681    .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
2682    .h.cie.return_column = TCG_REG_RA,
2683
2684    /* Total FDE size does not include the "len" member.  */
2685    .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2686
2687    .fde_def_cfa = {
2688        12, TCG_REG_SP,                 /* DW_CFA_def_cfa sp, ... */
2689        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2690        (FRAME_SIZE >> 7)
2691    },
2692    .fde_reg_ofs = {
2693        0x80 + 16, 9,                   /* DW_CFA_offset, s0, -72 */
2694        0x80 + 17, 8,                   /* DW_CFA_offset, s2, -64 */
2695        0x80 + 18, 7,                   /* DW_CFA_offset, s3, -56 */
2696        0x80 + 19, 6,                   /* DW_CFA_offset, s4, -48 */
2697        0x80 + 20, 5,                   /* DW_CFA_offset, s5, -40 */
2698        0x80 + 21, 4,                   /* DW_CFA_offset, s6, -32 */
2699        0x80 + 22, 3,                   /* DW_CFA_offset, s7, -24 */
2700        0x80 + 30, 2,                   /* DW_CFA_offset, s8, -16 */
2701        0x80 + 31, 1,                   /* DW_CFA_offset, ra,  -8 */
2702    }
2703};
2704
2705void tcg_register_jit(void *buf, size_t buf_size)
2706{
2707    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2708}
2709