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