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#define LO_OFF    (MIPS_BE * 4)
  36#define HI_OFF    (4 - LO_OFF)
  37
  38#ifdef CONFIG_DEBUG_TCG
  39static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
  40    "zero",
  41    "at",
  42    "v0",
  43    "v1",
  44    "a0",
  45    "a1",
  46    "a2",
  47    "a3",
  48    "t0",
  49    "t1",
  50    "t2",
  51    "t3",
  52    "t4",
  53    "t5",
  54    "t6",
  55    "t7",
  56    "s0",
  57    "s1",
  58    "s2",
  59    "s3",
  60    "s4",
  61    "s5",
  62    "s6",
  63    "s7",
  64    "t8",
  65    "t9",
  66    "k0",
  67    "k1",
  68    "gp",
  69    "sp",
  70    "s8",
  71    "ra",
  72};
  73#endif
  74
  75#define TCG_TMP0  TCG_REG_AT
  76#define TCG_TMP1  TCG_REG_T9
  77
  78/* check if we really need so many registers :P */
  79static const int tcg_target_reg_alloc_order[] = {
  80    /* Call saved registers.  */
  81    TCG_REG_S0,
  82    TCG_REG_S1,
  83    TCG_REG_S2,
  84    TCG_REG_S3,
  85    TCG_REG_S4,
  86    TCG_REG_S5,
  87    TCG_REG_S6,
  88    TCG_REG_S7,
  89    TCG_REG_S8,
  90
  91    /* Call clobbered registers.  */
  92    TCG_REG_T0,
  93    TCG_REG_T1,
  94    TCG_REG_T2,
  95    TCG_REG_T3,
  96    TCG_REG_T4,
  97    TCG_REG_T5,
  98    TCG_REG_T6,
  99    TCG_REG_T7,
 100    TCG_REG_T8,
 101    TCG_REG_T9,
 102    TCG_REG_V1,
 103    TCG_REG_V0,
 104
 105    /* Argument registers, opposite order of allocation.  */
 106    TCG_REG_A3,
 107    TCG_REG_A2,
 108    TCG_REG_A1,
 109    TCG_REG_A0,
 110};
 111
 112static const TCGReg tcg_target_call_iarg_regs[4] = {
 113    TCG_REG_A0,
 114    TCG_REG_A1,
 115    TCG_REG_A2,
 116    TCG_REG_A3
 117};
 118
 119static const TCGReg tcg_target_call_oarg_regs[2] = {
 120    TCG_REG_V0,
 121    TCG_REG_V1
 122};
 123
 124static tcg_insn_unit *tb_ret_addr;
 125
 126static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
 127{
 128    /* Let the compiler perform the right-shift as part of the arithmetic.  */
 129    ptrdiff_t disp = target - (pc + 1);
 130    tcg_debug_assert(disp == (int16_t)disp);
 131    return disp & 0xffff;
 132}
 133
 134static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
 135{
 136    *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
 137}
 138
 139static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target)
 140{
 141    tcg_debug_assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0);
 142    return ((uintptr_t)target >> 2) & 0x3ffffff;
 143}
 144
 145static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
 146{
 147    *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
 148}
 149
 150static void patch_reloc(tcg_insn_unit *code_ptr, int type,
 151                        intptr_t value, intptr_t addend)
 152{
 153    tcg_debug_assert(type == R_MIPS_PC16);
 154    tcg_debug_assert(addend == 0);
 155    reloc_pc16(code_ptr, (tcg_insn_unit *)value);
 156}
 157
 158#define TCG_CT_CONST_ZERO 0x100
 159#define TCG_CT_CONST_U16  0x200    /* Unsigned 16-bit: 0 - 0xffff.  */
 160#define TCG_CT_CONST_S16  0x400    /* Signed 16-bit: -32768 - 32767 */
 161#define TCG_CT_CONST_P2M1 0x800    /* Power of 2 minus 1.  */
 162#define TCG_CT_CONST_N16  0x1000   /* "Negatable" 16-bit: -32767 - 32767 */
 163
 164static inline bool is_p2m1(tcg_target_long val)
 165{
 166    return val && ((val + 1) & val) == 0;
 167}
 168
 169/* parse target specific constraints */
 170static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 171{
 172    const char *ct_str;
 173
 174    ct_str = *pct_str;
 175    switch(ct_str[0]) {
 176    case 'r':
 177        ct->ct |= TCG_CT_REG;
 178        tcg_regset_set(ct->u.regs, 0xffffffff);
 179        break;
 180    case 'L': /* qemu_ld output arg constraint */
 181        ct->ct |= TCG_CT_REG;
 182        tcg_regset_set(ct->u.regs, 0xffffffff);
 183        tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
 184        break;
 185    case 'l': /* qemu_ld input arg constraint */
 186        ct->ct |= TCG_CT_REG;
 187        tcg_regset_set(ct->u.regs, 0xffffffff);
 188        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 189#if defined(CONFIG_SOFTMMU)
 190        if (TARGET_LONG_BITS == 64) {
 191            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 192        }
 193#endif
 194        break;
 195    case 'S': /* qemu_st constraint */
 196        ct->ct |= TCG_CT_REG;
 197        tcg_regset_set(ct->u.regs, 0xffffffff);
 198        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 199#if defined(CONFIG_SOFTMMU)
 200        if (TARGET_LONG_BITS == 32) {
 201            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
 202        } else {
 203            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 204            tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
 205        }
 206#endif
 207        break;
 208    case 'I':
 209        ct->ct |= TCG_CT_CONST_U16;
 210        break;
 211    case 'J':
 212        ct->ct |= TCG_CT_CONST_S16;
 213        break;
 214    case 'K':
 215        ct->ct |= TCG_CT_CONST_P2M1;
 216        break;
 217    case 'N':
 218        ct->ct |= TCG_CT_CONST_N16;
 219        break;
 220    case 'Z':
 221        /* We are cheating a bit here, using the fact that the register
 222           ZERO is also the register number 0. Hence there is no need
 223           to check for const_args in each instruction. */
 224        ct->ct |= TCG_CT_CONST_ZERO;
 225        break;
 226    default:
 227        return -1;
 228    }
 229    ct_str++;
 230    *pct_str = ct_str;
 231    return 0;
 232}
 233
 234/* test if a constant matches the constraint */
 235static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
 236                                         const TCGArgConstraint *arg_ct)
 237{
 238    int ct;
 239    ct = arg_ct->ct;
 240    if (ct & TCG_CT_CONST) {
 241        return 1;
 242    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
 243        return 1;
 244    } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
 245        return 1;
 246    } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
 247        return 1;
 248    } else if ((ct & TCG_CT_CONST_N16) && val >= -32767 && val <= 32767) {
 249        return 1;
 250    } else if ((ct & TCG_CT_CONST_P2M1)
 251               && use_mips32r2_instructions && is_p2m1(val)) {
 252        return 1;
 253    }
 254    return 0;
 255}
 256
 257/* instruction opcodes */
 258typedef enum {
 259    OPC_J        = 0x02 << 26,
 260    OPC_JAL      = 0x03 << 26,
 261    OPC_BEQ      = 0x04 << 26,
 262    OPC_BNE      = 0x05 << 26,
 263    OPC_BLEZ     = 0x06 << 26,
 264    OPC_BGTZ     = 0x07 << 26,
 265    OPC_ADDIU    = 0x09 << 26,
 266    OPC_SLTI     = 0x0A << 26,
 267    OPC_SLTIU    = 0x0B << 26,
 268    OPC_ANDI     = 0x0C << 26,
 269    OPC_ORI      = 0x0D << 26,
 270    OPC_XORI     = 0x0E << 26,
 271    OPC_LUI      = 0x0F << 26,
 272    OPC_LB       = 0x20 << 26,
 273    OPC_LH       = 0x21 << 26,
 274    OPC_LW       = 0x23 << 26,
 275    OPC_LBU      = 0x24 << 26,
 276    OPC_LHU      = 0x25 << 26,
 277    OPC_LWU      = 0x27 << 26,
 278    OPC_SB       = 0x28 << 26,
 279    OPC_SH       = 0x29 << 26,
 280    OPC_SW       = 0x2B << 26,
 281
 282    OPC_SPECIAL  = 0x00 << 26,
 283    OPC_SLL      = OPC_SPECIAL | 0x00,
 284    OPC_SRL      = OPC_SPECIAL | 0x02,
 285    OPC_ROTR     = OPC_SPECIAL | (0x01 << 21) | 0x02,
 286    OPC_SRA      = OPC_SPECIAL | 0x03,
 287    OPC_SLLV     = OPC_SPECIAL | 0x04,
 288    OPC_SRLV     = OPC_SPECIAL | 0x06,
 289    OPC_ROTRV    = OPC_SPECIAL | (0x01 <<  6) | 0x06,
 290    OPC_SRAV     = OPC_SPECIAL | 0x07,
 291    OPC_JR_R5    = OPC_SPECIAL | 0x08,
 292    OPC_JALR     = OPC_SPECIAL | 0x09,
 293    OPC_MOVZ     = OPC_SPECIAL | 0x0A,
 294    OPC_MOVN     = OPC_SPECIAL | 0x0B,
 295    OPC_MFHI     = OPC_SPECIAL | 0x10,
 296    OPC_MFLO     = OPC_SPECIAL | 0x12,
 297    OPC_MULT     = OPC_SPECIAL | 0x18,
 298    OPC_MUL_R6   = OPC_SPECIAL | (0x02 <<  6) | 0x18,
 299    OPC_MUH      = OPC_SPECIAL | (0x03 <<  6) | 0x18,
 300    OPC_MULTU    = OPC_SPECIAL | 0x19,
 301    OPC_MULU     = OPC_SPECIAL | (0x02 <<  6) | 0x19,
 302    OPC_MUHU     = OPC_SPECIAL | (0x03 <<  6) | 0x19,
 303    OPC_DIV      = OPC_SPECIAL | 0x1A,
 304    OPC_DIV_R6   = OPC_SPECIAL | (0x02 <<  6) | 0x1A,
 305    OPC_MOD      = OPC_SPECIAL | (0x03 <<  6) | 0x1A,
 306    OPC_DIVU     = OPC_SPECIAL | 0x1B,
 307    OPC_DIVU_R6  = OPC_SPECIAL | (0x02 <<  6) | 0x1B,
 308    OPC_MODU     = OPC_SPECIAL | (0x03 <<  6) | 0x1B,
 309    OPC_ADDU     = OPC_SPECIAL | 0x21,
 310    OPC_SUBU     = OPC_SPECIAL | 0x23,
 311    OPC_AND      = OPC_SPECIAL | 0x24,
 312    OPC_OR       = OPC_SPECIAL | 0x25,
 313    OPC_XOR      = OPC_SPECIAL | 0x26,
 314    OPC_NOR      = OPC_SPECIAL | 0x27,
 315    OPC_SLT      = OPC_SPECIAL | 0x2A,
 316    OPC_SLTU     = OPC_SPECIAL | 0x2B,
 317    OPC_SELEQZ   = OPC_SPECIAL | 0x35,
 318    OPC_SELNEZ   = OPC_SPECIAL | 0x37,
 319
 320    OPC_REGIMM   = 0x01 << 26,
 321    OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
 322    OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
 323
 324    OPC_SPECIAL2 = 0x1c << 26,
 325    OPC_MUL_R5   = OPC_SPECIAL2 | 0x002,
 326
 327    OPC_SPECIAL3 = 0x1f << 26,
 328    OPC_EXT      = OPC_SPECIAL3 | 0x000,
 329    OPC_INS      = OPC_SPECIAL3 | 0x004,
 330    OPC_WSBH     = OPC_SPECIAL3 | 0x0a0,
 331    OPC_SEB      = OPC_SPECIAL3 | 0x420,
 332    OPC_SEH      = OPC_SPECIAL3 | 0x620,
 333
 334    /* MIPS r6 doesn't have JR, JALR should be used instead */
 335    OPC_JR       = use_mips32r6_instructions ? OPC_JALR : OPC_JR_R5,
 336
 337    /*
 338     * MIPS r6 replaces MUL with an alternative encoding which is
 339     * backwards-compatible at the assembly level.
 340     */
 341    OPC_MUL      = use_mips32r6_instructions ? OPC_MUL_R6 : OPC_MUL_R5,
 342} MIPSInsn;
 343
 344/*
 345 * Type reg
 346 */
 347static inline void tcg_out_opc_reg(TCGContext *s, MIPSInsn opc,
 348                                   TCGReg rd, TCGReg rs, TCGReg rt)
 349{
 350    int32_t inst;
 351
 352    inst = opc;
 353    inst |= (rs & 0x1F) << 21;
 354    inst |= (rt & 0x1F) << 16;
 355    inst |= (rd & 0x1F) << 11;
 356    tcg_out32(s, inst);
 357}
 358
 359/*
 360 * Type immediate
 361 */
 362static inline void tcg_out_opc_imm(TCGContext *s, MIPSInsn opc,
 363                                   TCGReg rt, TCGReg rs, TCGArg imm)
 364{
 365    int32_t inst;
 366
 367    inst = opc;
 368    inst |= (rs & 0x1F) << 21;
 369    inst |= (rt & 0x1F) << 16;
 370    inst |= (imm & 0xffff);
 371    tcg_out32(s, inst);
 372}
 373
 374/*
 375 * Type bitfield
 376 */
 377static inline void tcg_out_opc_bf(TCGContext *s, MIPSInsn opc, TCGReg rt,
 378                                  TCGReg rs, int msb, int lsb)
 379{
 380    int32_t inst;
 381
 382    inst = opc;
 383    inst |= (rs & 0x1F) << 21;
 384    inst |= (rt & 0x1F) << 16;
 385    inst |= (msb & 0x1F) << 11;
 386    inst |= (lsb & 0x1F) << 6;
 387    tcg_out32(s, inst);
 388}
 389
 390/*
 391 * Type branch
 392 */
 393static inline void tcg_out_opc_br(TCGContext *s, MIPSInsn opc,
 394                                  TCGReg rt, TCGReg rs)
 395{
 396    /* We pay attention here to not modify the branch target by reading
 397       the existing value and using it again. This ensure that caches and
 398       memory are kept coherent during retranslation. */
 399    uint16_t offset = (uint16_t)*s->code_ptr;
 400
 401    tcg_out_opc_imm(s, opc, rt, rs, offset);
 402}
 403
 404/*
 405 * Type sa
 406 */
 407static inline void tcg_out_opc_sa(TCGContext *s, MIPSInsn opc,
 408                                  TCGReg rd, TCGReg rt, TCGArg sa)
 409{
 410    int32_t inst;
 411
 412    inst = opc;
 413    inst |= (rt & 0x1F) << 16;
 414    inst |= (rd & 0x1F) << 11;
 415    inst |= (sa & 0x1F) <<  6;
 416    tcg_out32(s, inst);
 417
 418}
 419
 420/*
 421 * Type jump.
 422 * Returns true if the branch was in range and the insn was emitted.
 423 */
 424static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
 425{
 426    uintptr_t dest = (uintptr_t)target;
 427    uintptr_t from = (uintptr_t)s->code_ptr + 4;
 428    int32_t inst;
 429
 430    /* The pc-region branch happens within the 256MB region of
 431       the delay slot (thus the +4).  */
 432    if ((from ^ dest) & -(1 << 28)) {
 433        return false;
 434    }
 435    tcg_debug_assert((dest & 3) == 0);
 436
 437    inst = opc;
 438    inst |= (dest >> 2) & 0x3ffffff;
 439    tcg_out32(s, inst);
 440    return true;
 441}
 442
 443static inline void tcg_out_nop(TCGContext *s)
 444{
 445    tcg_out32(s, 0);
 446}
 447
 448static inline void tcg_out_mov(TCGContext *s, TCGType type,
 449                               TCGReg ret, TCGReg arg)
 450{
 451    /* Simple reg-reg move, optimising out the 'do nothing' case */
 452    if (ret != arg) {
 453        tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
 454    }
 455}
 456
 457static inline void tcg_out_movi(TCGContext *s, TCGType type,
 458                                TCGReg reg, tcg_target_long arg)
 459{
 460    if (arg == (int16_t)arg) {
 461        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
 462    } else if (arg == (uint16_t)arg) {
 463        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
 464    } else {
 465        tcg_out_opc_imm(s, OPC_LUI, reg, TCG_REG_ZERO, arg >> 16);
 466        if (arg & 0xffff) {
 467            tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
 468        }
 469    }
 470}
 471
 472static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
 473{
 474    if (use_mips32r2_instructions) {
 475        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 476    } else {
 477        /* ret and arg can't be register at */
 478        if (ret == TCG_TMP0 || arg == TCG_TMP0) {
 479            tcg_abort();
 480        }
 481
 482        tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
 483        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
 484        tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
 485        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 486    }
 487}
 488
 489static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
 490{
 491    if (use_mips32r2_instructions) {
 492        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 493        tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
 494    } else {
 495        /* ret and arg can't be register at */
 496        if (ret == TCG_TMP0 || arg == TCG_TMP0) {
 497            tcg_abort();
 498        }
 499
 500        tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
 501        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 502        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 503        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 504    }
 505}
 506
 507static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
 508{
 509    if (use_mips32r2_instructions) {
 510        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 511        tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
 512    } else {
 513        /* ret and arg must be different and can't be register at */
 514        if (ret == arg || ret == TCG_TMP0 || arg == TCG_TMP0) {
 515            tcg_abort();
 516        }
 517
 518        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 519
 520        tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 24);
 521        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 522
 523        tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, arg, 0xff00);
 524        tcg_out_opc_sa(s, OPC_SLL, TCG_TMP0, TCG_TMP0, 8);
 525        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 526
 527        tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
 528        tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0xff00);
 529        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
 530    }
 531}
 532
 533static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
 534{
 535    if (use_mips32r2_instructions) {
 536        tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
 537    } else {
 538        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 539        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
 540    }
 541}
 542
 543static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
 544{
 545    if (use_mips32r2_instructions) {
 546        tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
 547    } else {
 548        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
 549        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 550    }
 551}
 552
 553static void tcg_out_ldst(TCGContext *s, MIPSInsn opc, TCGReg data,
 554                         TCGReg addr, intptr_t ofs)
 555{
 556    int16_t lo = ofs;
 557    if (ofs != lo) {
 558        tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - lo);
 559        if (addr != TCG_REG_ZERO) {
 560            tcg_out_opc_reg(s, OPC_ADDU, TCG_TMP0, TCG_TMP0, addr);
 561        }
 562        addr = TCG_TMP0;
 563    }
 564    tcg_out_opc_imm(s, opc, data, addr, lo);
 565}
 566
 567static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
 568                              TCGReg arg1, intptr_t arg2)
 569{
 570    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
 571}
 572
 573static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 574                              TCGReg arg1, intptr_t arg2)
 575{
 576    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
 577}
 578
 579static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
 580{
 581    if (val == (int16_t)val) {
 582        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
 583    } else {
 584        tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, val);
 585        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_TMP0);
 586    }
 587}
 588
 589static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al,
 590                            TCGReg ah, TCGArg bl, TCGArg bh, bool cbl,
 591                            bool cbh, bool is_sub)
 592{
 593    TCGReg th = TCG_TMP1;
 594
 595    /* If we have a negative constant such that negating it would
 596       make the high part zero, we can (usually) eliminate one insn.  */
 597    if (cbl && cbh && bh == -1 && bl != 0) {
 598        bl = -bl;
 599        bh = 0;
 600        is_sub = !is_sub;
 601    }
 602
 603    /* By operating on the high part first, we get to use the final
 604       carry operation to move back from the temporary.  */
 605    if (!cbh) {
 606        tcg_out_opc_reg(s, (is_sub ? OPC_SUBU : OPC_ADDU), th, ah, bh);
 607    } else if (bh != 0 || ah == rl) {
 608        tcg_out_opc_imm(s, OPC_ADDIU, th, ah, (is_sub ? -bh : bh));
 609    } else {
 610        th = ah;
 611    }
 612
 613    /* Note that tcg optimization should eliminate the bl == 0 case.  */
 614    if (is_sub) {
 615        if (cbl) {
 616            tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, al, bl);
 617            tcg_out_opc_imm(s, OPC_ADDIU, rl, al, -bl);
 618        } else {
 619            tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, al, bl);
 620            tcg_out_opc_reg(s, OPC_SUBU, rl, al, bl);
 621        }
 622        tcg_out_opc_reg(s, OPC_SUBU, rh, th, TCG_TMP0);
 623    } else {
 624        if (cbl) {
 625            tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl);
 626            tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl);
 627        } else if (rl == al && rl == bl) {
 628            tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, al, 31);
 629            tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
 630        } else {
 631            tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
 632            tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl));
 633        }
 634        tcg_out_opc_reg(s, OPC_ADDU, rh, th, TCG_TMP0);
 635    }
 636}
 637
 638/* Bit 0 set if inversion required; bit 1 set if swapping required.  */
 639#define MIPS_CMP_INV  1
 640#define MIPS_CMP_SWAP 2
 641
 642static const uint8_t mips_cmp_map[16] = {
 643    [TCG_COND_LT]  = 0,
 644    [TCG_COND_LTU] = 0,
 645    [TCG_COND_GE]  = MIPS_CMP_INV,
 646    [TCG_COND_GEU] = MIPS_CMP_INV,
 647    [TCG_COND_LE]  = MIPS_CMP_INV | MIPS_CMP_SWAP,
 648    [TCG_COND_LEU] = MIPS_CMP_INV | MIPS_CMP_SWAP,
 649    [TCG_COND_GT]  = MIPS_CMP_SWAP,
 650    [TCG_COND_GTU] = MIPS_CMP_SWAP,
 651};
 652
 653static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
 654                            TCGReg arg1, TCGReg arg2)
 655{
 656    MIPSInsn s_opc = OPC_SLTU;
 657    int cmp_map;
 658
 659    switch (cond) {
 660    case TCG_COND_EQ:
 661        if (arg2 != 0) {
 662            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 663            arg1 = ret;
 664        }
 665        tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
 666        break;
 667
 668    case TCG_COND_NE:
 669        if (arg2 != 0) {
 670            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 671            arg1 = ret;
 672        }
 673        tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
 674        break;
 675
 676    case TCG_COND_LT:
 677    case TCG_COND_GE:
 678    case TCG_COND_LE:
 679    case TCG_COND_GT:
 680        s_opc = OPC_SLT;
 681        /* FALLTHRU */
 682
 683    case TCG_COND_LTU:
 684    case TCG_COND_GEU:
 685    case TCG_COND_LEU:
 686    case TCG_COND_GTU:
 687        cmp_map = mips_cmp_map[cond];
 688        if (cmp_map & MIPS_CMP_SWAP) {
 689            TCGReg t = arg1;
 690            arg1 = arg2;
 691            arg2 = t;
 692        }
 693        tcg_out_opc_reg(s, s_opc, ret, arg1, arg2);
 694        if (cmp_map & MIPS_CMP_INV) {
 695            tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 696        }
 697        break;
 698
 699     default:
 700         tcg_abort();
 701         break;
 702     }
 703}
 704
 705static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
 706                           TCGReg arg2, TCGLabel *l)
 707{
 708    static const MIPSInsn b_zero[16] = {
 709        [TCG_COND_LT] = OPC_BLTZ,
 710        [TCG_COND_GT] = OPC_BGTZ,
 711        [TCG_COND_LE] = OPC_BLEZ,
 712        [TCG_COND_GE] = OPC_BGEZ,
 713    };
 714
 715    MIPSInsn s_opc = OPC_SLTU;
 716    MIPSInsn b_opc;
 717    int cmp_map;
 718
 719    switch (cond) {
 720    case TCG_COND_EQ:
 721        b_opc = OPC_BEQ;
 722        break;
 723    case TCG_COND_NE:
 724        b_opc = OPC_BNE;
 725        break;
 726
 727    case TCG_COND_LT:
 728    case TCG_COND_GT:
 729    case TCG_COND_LE:
 730    case TCG_COND_GE:
 731        if (arg2 == 0) {
 732            b_opc = b_zero[cond];
 733            arg2 = arg1;
 734            arg1 = 0;
 735            break;
 736        }
 737        s_opc = OPC_SLT;
 738        /* FALLTHRU */
 739
 740    case TCG_COND_LTU:
 741    case TCG_COND_GTU:
 742    case TCG_COND_LEU:
 743    case TCG_COND_GEU:
 744        cmp_map = mips_cmp_map[cond];
 745        if (cmp_map & MIPS_CMP_SWAP) {
 746            TCGReg t = arg1;
 747            arg1 = arg2;
 748            arg2 = t;
 749        }
 750        tcg_out_opc_reg(s, s_opc, TCG_TMP0, arg1, arg2);
 751        b_opc = (cmp_map & MIPS_CMP_INV ? OPC_BEQ : OPC_BNE);
 752        arg1 = TCG_TMP0;
 753        arg2 = TCG_REG_ZERO;
 754        break;
 755
 756    default:
 757        tcg_abort();
 758        break;
 759    }
 760
 761    tcg_out_opc_br(s, b_opc, arg1, arg2);
 762    if (l->has_value) {
 763        reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
 764    } else {
 765        tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
 766    }
 767    tcg_out_nop(s);
 768}
 769
 770static TCGReg tcg_out_reduce_eq2(TCGContext *s, TCGReg tmp0, TCGReg tmp1,
 771                                 TCGReg al, TCGReg ah,
 772                                 TCGReg bl, TCGReg bh)
 773{
 774    /* Merge highpart comparison into AH.  */
 775    if (bh != 0) {
 776        if (ah != 0) {
 777            tcg_out_opc_reg(s, OPC_XOR, tmp0, ah, bh);
 778            ah = tmp0;
 779        } else {
 780            ah = bh;
 781        }
 782    }
 783    /* Merge lowpart comparison into AL.  */
 784    if (bl != 0) {
 785        if (al != 0) {
 786            tcg_out_opc_reg(s, OPC_XOR, tmp1, al, bl);
 787            al = tmp1;
 788        } else {
 789            al = bl;
 790        }
 791    }
 792    /* Merge high and low part comparisons into AL.  */
 793    if (ah != 0) {
 794        if (al != 0) {
 795            tcg_out_opc_reg(s, OPC_OR, tmp0, ah, al);
 796            al = tmp0;
 797        } else {
 798            al = ah;
 799        }
 800    }
 801    return al;
 802}
 803
 804static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
 805                             TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
 806{
 807    TCGReg tmp0 = TCG_TMP0;
 808    TCGReg tmp1 = ret;
 809
 810    tcg_debug_assert(ret != TCG_TMP0);
 811    if (ret == ah || ret == bh) {
 812        tcg_debug_assert(ret != TCG_TMP1);
 813        tmp1 = TCG_TMP1;
 814    }
 815
 816    switch (cond) {
 817    case TCG_COND_EQ:
 818    case TCG_COND_NE:
 819        tmp1 = tcg_out_reduce_eq2(s, tmp0, tmp1, al, ah, bl, bh);
 820        tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
 821        break;
 822
 823    default:
 824        tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);
 825        tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);
 826        tcg_out_opc_reg(s, OPC_AND, tmp1, tmp1, tmp0);
 827        tcg_out_setcond(s, tcg_high_cond(cond), tmp0, ah, bh);
 828        tcg_out_opc_reg(s, OPC_OR, ret, tmp1, tmp0);
 829        break;
 830    }
 831}
 832
 833static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
 834                            TCGReg bl, TCGReg bh, TCGLabel *l)
 835{
 836    TCGCond b_cond = TCG_COND_NE;
 837    TCGReg tmp = TCG_TMP1;
 838
 839    /* With branches, we emit between 4 and 9 insns with 2 or 3 branches.
 840       With setcond, we emit between 3 and 10 insns and only 1 branch,
 841       which ought to get better branch prediction.  */
 842     switch (cond) {
 843     case TCG_COND_EQ:
 844     case TCG_COND_NE:
 845        b_cond = cond;
 846        tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh);
 847        break;
 848
 849    default:
 850        /* Minimize code size by preferring a compare not requiring INV.  */
 851        if (mips_cmp_map[cond] & MIPS_CMP_INV) {
 852            cond = tcg_invert_cond(cond);
 853            b_cond = TCG_COND_EQ;
 854        }
 855        tcg_out_setcond2(s, cond, tmp, al, ah, bl, bh);
 856        break;
 857    }
 858
 859    tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, l);
 860}
 861
 862static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
 863                            TCGReg c1, TCGReg c2, TCGReg v1, TCGReg v2)
 864{
 865    bool eqz = false;
 866
 867    /* If one of the values is zero, put it last to match SEL*Z instructions */
 868    if (use_mips32r6_instructions && v1 == 0) {
 869        v1 = v2;
 870        v2 = 0;
 871        cond = tcg_invert_cond(cond);
 872    }
 873
 874    switch (cond) {
 875    case TCG_COND_EQ:
 876        eqz = true;
 877        /* FALLTHRU */
 878    case TCG_COND_NE:
 879        if (c2 != 0) {
 880            tcg_out_opc_reg(s, OPC_XOR, TCG_TMP0, c1, c2);
 881            c1 = TCG_TMP0;
 882        }
 883        break;
 884
 885    default:
 886        /* Minimize code size by preferring a compare not requiring INV.  */
 887        if (mips_cmp_map[cond] & MIPS_CMP_INV) {
 888            cond = tcg_invert_cond(cond);
 889            eqz = true;
 890        }
 891        tcg_out_setcond(s, cond, TCG_TMP0, c1, c2);
 892        c1 = TCG_TMP0;
 893        break;
 894    }
 895
 896    if (use_mips32r6_instructions) {
 897        MIPSInsn m_opc_t = eqz ? OPC_SELEQZ : OPC_SELNEZ;
 898        MIPSInsn m_opc_f = eqz ? OPC_SELNEZ : OPC_SELEQZ;
 899
 900        if (v2 != 0) {
 901            tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
 902        }
 903        tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
 904        if (v2 != 0) {
 905            tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
 906        }
 907    } else {
 908        MIPSInsn m_opc = eqz ? OPC_MOVZ : OPC_MOVN;
 909
 910        tcg_out_opc_reg(s, m_opc, ret, v1, c1);
 911
 912        /* This should be guaranteed via constraints */
 913        tcg_debug_assert(v2 == ret);
 914    }
 915}
 916
 917static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
 918{
 919    /* Note that the ABI requires the called function's address to be
 920       loaded into T9, even if a direct branch is in range.  */
 921    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T9, (uintptr_t)arg);
 922
 923    /* But do try a direct branch, allowing the cpu better insn prefetch.  */
 924    if (tail) {
 925        if (!tcg_out_opc_jmp(s, OPC_J, arg)) {
 926            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_T9, 0);
 927        }
 928    } else {
 929        if (!tcg_out_opc_jmp(s, OPC_JAL, arg)) {
 930            tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
 931        }
 932    }
 933}
 934
 935static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
 936{
 937    tcg_out_call_int(s, arg, false);
 938    tcg_out_nop(s);
 939}
 940
 941#if defined(CONFIG_SOFTMMU)
 942static void * const qemu_ld_helpers[16] = {
 943    [MO_UB]   = helper_ret_ldub_mmu,
 944    [MO_SB]   = helper_ret_ldsb_mmu,
 945    [MO_LEUW] = helper_le_lduw_mmu,
 946    [MO_LESW] = helper_le_ldsw_mmu,
 947    [MO_LEUL] = helper_le_ldul_mmu,
 948    [MO_LEQ]  = helper_le_ldq_mmu,
 949    [MO_BEUW] = helper_be_lduw_mmu,
 950    [MO_BESW] = helper_be_ldsw_mmu,
 951    [MO_BEUL] = helper_be_ldul_mmu,
 952    [MO_BEQ]  = helper_be_ldq_mmu,
 953};
 954
 955static void * const qemu_st_helpers[16] = {
 956    [MO_UB]   = helper_ret_stb_mmu,
 957    [MO_LEUW] = helper_le_stw_mmu,
 958    [MO_LEUL] = helper_le_stl_mmu,
 959    [MO_LEQ]  = helper_le_stq_mmu,
 960    [MO_BEUW] = helper_be_stw_mmu,
 961    [MO_BEUL] = helper_be_stl_mmu,
 962    [MO_BEQ]  = helper_be_stq_mmu,
 963};
 964
 965/* Helper routines for marshalling helper function arguments into
 966 * the correct registers and stack.
 967 * I is where we want to put this argument, and is updated and returned
 968 * for the next call. ARG is the argument itself.
 969 *
 970 * We provide routines for arguments which are: immediate, 32 bit
 971 * value in register, 16 and 8 bit values in register (which must be zero
 972 * extended before use) and 64 bit value in a lo:hi register pair.
 973 */
 974
 975static int tcg_out_call_iarg_reg(TCGContext *s, int i, TCGReg arg)
 976{
 977    if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
 978        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[i], arg);
 979    } else {
 980        tcg_out_st(s, TCG_TYPE_REG, arg, TCG_REG_SP, 4 * i);
 981    }
 982    return i + 1;
 983}
 984
 985static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg)
 986{
 987    TCGReg tmp = TCG_TMP0;
 988    if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
 989        tmp = tcg_target_call_iarg_regs[i];
 990    }
 991    tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff);
 992    return tcg_out_call_iarg_reg(s, i, tmp);
 993}
 994
 995static int tcg_out_call_iarg_reg16(TCGContext *s, int i, TCGReg arg)
 996{
 997    TCGReg tmp = TCG_TMP0;
 998    if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
 999        tmp = tcg_target_call_iarg_regs[i];
1000    }
1001    tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xffff);
1002    return tcg_out_call_iarg_reg(s, i, tmp);
1003}
1004
1005static int tcg_out_call_iarg_imm(TCGContext *s, int i, TCGArg arg)
1006{
1007    TCGReg tmp = TCG_TMP0;
1008    if (arg == 0) {
1009        tmp = TCG_REG_ZERO;
1010    } else {
1011        if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1012            tmp = tcg_target_call_iarg_regs[i];
1013        }
1014        tcg_out_movi(s, TCG_TYPE_REG, tmp, arg);
1015    }
1016    return tcg_out_call_iarg_reg(s, i, tmp);
1017}
1018
1019static int tcg_out_call_iarg_reg2(TCGContext *s, int i, TCGReg al, TCGReg ah)
1020{
1021    i = (i + 1) & ~1;
1022    i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? ah : al));
1023    i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? al : ah));
1024    return i;
1025}
1026
1027/* Perform the tlb comparison operation.  The complete host address is
1028   placed in BASE.  Clobbers AT, T0, A0.  */
1029static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl,
1030                             TCGReg addrh, TCGMemOpIdx oi,
1031                             tcg_insn_unit *label_ptr[2], bool is_load)
1032{
1033    TCGMemOp s_bits = get_memop(oi) & MO_SIZE;
1034    int mem_index = get_mmuidx(oi);
1035    int cmp_off
1036        = (is_load
1037           ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1038           : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1039    int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1040
1041    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addrl,
1042                   TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1043    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0,
1044                    (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1045    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1046
1047    /* Compensate for very large offsets.  */
1048    if (add_off >= 0x8000) {
1049        /* Most target env are smaller than 32k; none are larger than 64k.
1050           Simplify the logic here merely to offset by 0x7ff0, giving us a
1051           range just shy of 64k.  Check this assumption.  */
1052        QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
1053                                   tlb_table[NB_MMU_MODES - 1][1])
1054                          > 0x7ff0 + 0x7fff);
1055        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, TCG_REG_A0, 0x7ff0);
1056        cmp_off -= 0x7ff0;
1057        add_off -= 0x7ff0;
1058    }
1059
1060    /* Load the (low half) tlb comparator.  */
1061    tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0,
1062                    cmp_off + (TARGET_LONG_BITS == 64 ? LO_OFF : 0));
1063
1064    /* Mask the page bits, keeping the alignment bits to compare against.
1065       In between on 32-bit targets, load the tlb addend for the fast path.  */
1066    tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1,
1067                 TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1068    if (TARGET_LONG_BITS == 32) {
1069        tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, add_off);
1070    }
1071    tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl);
1072
1073    label_ptr[0] = s->code_ptr;
1074    tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
1075
1076    /* Load and test the high half tlb comparator.  */
1077    if (TARGET_LONG_BITS == 64) {
1078        /* delay slot */
1079        tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off + HI_OFF);
1080
1081        /* Load the tlb addend for the fast path. We can't do it earlier with
1082           64-bit targets or we'll clobber a0 before reading the high half tlb
1083           comparator.  */
1084        tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, add_off);
1085
1086        label_ptr[1] = s->code_ptr;
1087        tcg_out_opc_br(s, OPC_BNE, addrh, TCG_TMP0);
1088    }
1089
1090    /* delay slot */
1091    tcg_out_opc_reg(s, OPC_ADDU, base, TCG_REG_A0, addrl);
1092}
1093
1094static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
1095                                TCGReg datalo, TCGReg datahi,
1096                                TCGReg addrlo, TCGReg addrhi,
1097                                void *raddr, tcg_insn_unit *label_ptr[2])
1098{
1099    TCGLabelQemuLdst *label = new_ldst_label(s);
1100
1101    label->is_ld = is_ld;
1102    label->oi = oi;
1103    label->datalo_reg = datalo;
1104    label->datahi_reg = datahi;
1105    label->addrlo_reg = addrlo;
1106    label->addrhi_reg = addrhi;
1107    label->raddr = raddr;
1108    label->label_ptr[0] = label_ptr[0];
1109    if (TARGET_LONG_BITS == 64) {
1110        label->label_ptr[1] = label_ptr[1];
1111    }
1112}
1113
1114static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1115{
1116    TCGMemOpIdx oi = l->oi;
1117    TCGMemOp opc = get_memop(oi);
1118    TCGReg v0;
1119    int i;
1120
1121    /* resolve label address */
1122    reloc_pc16(l->label_ptr[0], s->code_ptr);
1123    if (TARGET_LONG_BITS == 64) {
1124        reloc_pc16(l->label_ptr[1], s->code_ptr);
1125    }
1126
1127    i = 1;
1128    if (TARGET_LONG_BITS == 64) {
1129        i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1130    } else {
1131        i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1132    }
1133    i = tcg_out_call_iarg_imm(s, i, oi);
1134    i = tcg_out_call_iarg_imm(s, i, (intptr_t)l->raddr);
1135    tcg_out_call_int(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)], false);
1136    /* delay slot */
1137    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1138
1139    v0 = l->datalo_reg;
1140    if ((opc & MO_SIZE) == MO_64) {
1141        /* We eliminated V0 from the possible output registers, so it
1142           cannot be clobbered here.  So we must move V1 first.  */
1143        if (MIPS_BE) {
1144            tcg_out_mov(s, TCG_TYPE_I32, v0, TCG_REG_V1);
1145            v0 = l->datahi_reg;
1146        } else {
1147            tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_V1);
1148        }
1149    }
1150
1151    reloc_pc16(s->code_ptr, l->raddr);
1152    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1153    /* delay slot */
1154    tcg_out_mov(s, TCG_TYPE_REG, v0, TCG_REG_V0);
1155}
1156
1157static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1158{
1159    TCGMemOpIdx oi = l->oi;
1160    TCGMemOp opc = get_memop(oi);
1161    TCGMemOp s_bits = opc & MO_SIZE;
1162    int i;
1163
1164    /* resolve label address */
1165    reloc_pc16(l->label_ptr[0], s->code_ptr);
1166    if (TARGET_LONG_BITS == 64) {
1167        reloc_pc16(l->label_ptr[1], s->code_ptr);
1168    }
1169
1170    i = 1;
1171    if (TARGET_LONG_BITS == 64) {
1172        i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1173    } else {
1174        i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1175    }
1176    switch (s_bits) {
1177    case MO_8:
1178        i = tcg_out_call_iarg_reg8(s, i, l->datalo_reg);
1179        break;
1180    case MO_16:
1181        i = tcg_out_call_iarg_reg16(s, i, l->datalo_reg);
1182        break;
1183    case MO_32:
1184        i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1185        break;
1186    case MO_64:
1187        i = tcg_out_call_iarg_reg2(s, i, l->datalo_reg, l->datahi_reg);
1188        break;
1189    default:
1190        tcg_abort();
1191    }
1192    i = tcg_out_call_iarg_imm(s, i, oi);
1193
1194    /* Tail call to the store helper.  Thus force the return address
1195       computation to take place in the return address register.  */
1196    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)l->raddr);
1197    i = tcg_out_call_iarg_reg(s, i, TCG_REG_RA);
1198    tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
1199    /* delay slot */
1200    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1201}
1202#endif
1203
1204static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
1205                                   TCGReg base, TCGMemOp opc)
1206{
1207    switch (opc & (MO_SSIZE | MO_BSWAP)) {
1208    case MO_UB:
1209        tcg_out_opc_imm(s, OPC_LBU, datalo, base, 0);
1210        break;
1211    case MO_SB:
1212        tcg_out_opc_imm(s, OPC_LB, datalo, base, 0);
1213        break;
1214    case MO_UW | MO_BSWAP:
1215        tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1216        tcg_out_bswap16(s, datalo, TCG_TMP1);
1217        break;
1218    case MO_UW:
1219        tcg_out_opc_imm(s, OPC_LHU, datalo, base, 0);
1220        break;
1221    case MO_SW | MO_BSWAP:
1222        tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1223        tcg_out_bswap16s(s, datalo, TCG_TMP1);
1224        break;
1225    case MO_SW:
1226        tcg_out_opc_imm(s, OPC_LH, datalo, base, 0);
1227        break;
1228    case MO_UL | MO_BSWAP:
1229        tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, 0);
1230        tcg_out_bswap32(s, datalo, TCG_TMP1);
1231        break;
1232    case MO_UL:
1233        tcg_out_opc_imm(s, OPC_LW, datalo, base, 0);
1234        break;
1235    case MO_Q | MO_BSWAP:
1236        tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, HI_OFF);
1237        tcg_out_bswap32(s, datalo, TCG_TMP1);
1238        tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, LO_OFF);
1239        tcg_out_bswap32(s, datahi, TCG_TMP1);
1240        break;
1241    case MO_Q:
1242        tcg_out_opc_imm(s, OPC_LW, datalo, base, LO_OFF);
1243        tcg_out_opc_imm(s, OPC_LW, datahi, base, HI_OFF);
1244        break;
1245    default:
1246        tcg_abort();
1247    }
1248}
1249
1250static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1251{
1252    TCGReg addr_regl, addr_regh __attribute__((unused));
1253    TCGReg data_regl, data_regh;
1254    TCGMemOpIdx oi;
1255    TCGMemOp opc;
1256#if defined(CONFIG_SOFTMMU)
1257    tcg_insn_unit *label_ptr[2];
1258#endif
1259    /* Note that we've eliminated V0 from the output registers,
1260       so we won't overwrite the base register during loading.  */
1261    TCGReg base = TCG_REG_V0;
1262
1263    data_regl = *args++;
1264    data_regh = (is_64 ? *args++ : 0);
1265    addr_regl = *args++;
1266    addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1267    oi = *args++;
1268    opc = get_memop(oi);
1269
1270#if defined(CONFIG_SOFTMMU)
1271    tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 1);
1272    tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc);
1273    add_qemu_ldst_label(s, 1, oi, data_regl, data_regh, addr_regl, addr_regh,
1274                        s->code_ptr, label_ptr);
1275#else
1276    if (guest_base == 0 && data_regl != addr_regl) {
1277        base = addr_regl;
1278    } else if (guest_base == (int16_t)guest_base) {
1279        tcg_out_opc_imm(s, OPC_ADDIU, base, addr_regl, guest_base);
1280    } else {
1281        tcg_out_movi(s, TCG_TYPE_PTR, base, guest_base);
1282        tcg_out_opc_reg(s, OPC_ADDU, base, base, addr_regl);
1283    }
1284    tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc);
1285#endif
1286}
1287
1288static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
1289                                   TCGReg base, TCGMemOp opc)
1290{
1291    switch (opc & (MO_SIZE | MO_BSWAP)) {
1292    case MO_8:
1293        tcg_out_opc_imm(s, OPC_SB, datalo, base, 0);
1294        break;
1295
1296    case MO_16 | MO_BSWAP:
1297        tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, datalo, 0xffff);
1298        tcg_out_bswap16(s, TCG_TMP1, TCG_TMP1);
1299        datalo = TCG_TMP1;
1300        /* FALLTHRU */
1301    case MO_16:
1302        tcg_out_opc_imm(s, OPC_SH, datalo, base, 0);
1303        break;
1304
1305    case MO_32 | MO_BSWAP:
1306        tcg_out_bswap32(s, TCG_TMP1, datalo);
1307        datalo = TCG_TMP1;
1308        /* FALLTHRU */
1309    case MO_32:
1310        tcg_out_opc_imm(s, OPC_SW, datalo, base, 0);
1311        break;
1312
1313    case MO_64 | MO_BSWAP:
1314        tcg_out_bswap32(s, TCG_TMP1, datalo);
1315        tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, HI_OFF);
1316        tcg_out_bswap32(s, TCG_TMP1, datahi);
1317        tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, LO_OFF);
1318        break;
1319    case MO_64:
1320        tcg_out_opc_imm(s, OPC_SW, datalo, base, LO_OFF);
1321        tcg_out_opc_imm(s, OPC_SW, datahi, base, HI_OFF);
1322        break;
1323
1324    default:
1325        tcg_abort();
1326    }
1327}
1328
1329static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1330{
1331    TCGReg addr_regl, addr_regh __attribute__((unused));
1332    TCGReg data_regl, data_regh, base;
1333    TCGMemOpIdx oi;
1334    TCGMemOp opc;
1335#if defined(CONFIG_SOFTMMU)
1336    tcg_insn_unit *label_ptr[2];
1337#endif
1338
1339    data_regl = *args++;
1340    data_regh = (is_64 ? *args++ : 0);
1341    addr_regl = *args++;
1342    addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1343    oi = *args++;
1344    opc = get_memop(oi);
1345
1346#if defined(CONFIG_SOFTMMU)
1347    /* Note that we eliminated the helper's address argument,
1348       so we can reuse that for the base.  */
1349    base = (TARGET_LONG_BITS == 32 ? TCG_REG_A1 : TCG_REG_A2);
1350    tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 0);
1351    tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1352    add_qemu_ldst_label(s, 0, oi, data_regl, data_regh, addr_regl, addr_regh,
1353                        s->code_ptr, label_ptr);
1354#else
1355    if (guest_base == 0) {
1356        base = addr_regl;
1357    } else {
1358        base = TCG_REG_A0;
1359        if (guest_base == (int16_t)guest_base) {
1360            tcg_out_opc_imm(s, OPC_ADDIU, base, addr_regl, guest_base);
1361        } else {
1362            tcg_out_movi(s, TCG_TYPE_PTR, base, guest_base);
1363            tcg_out_opc_reg(s, OPC_ADDU, base, base, addr_regl);
1364        }
1365    }
1366    tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1367#endif
1368}
1369
1370static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1371                              const TCGArg *args, const int *const_args)
1372{
1373    MIPSInsn i1, i2;
1374    TCGArg a0, a1, a2;
1375    int c2;
1376
1377    a0 = args[0];
1378    a1 = args[1];
1379    a2 = args[2];
1380    c2 = const_args[2];
1381
1382    switch (opc) {
1383    case INDEX_op_exit_tb:
1384        {
1385            TCGReg b0 = TCG_REG_ZERO;
1386
1387            if (a0 & ~0xffff) {
1388                tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, a0 & ~0xffff);
1389                b0 = TCG_REG_V0;
1390            }
1391            if (!tcg_out_opc_jmp(s, OPC_J, tb_ret_addr)) {
1392                tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0,
1393                             (uintptr_t)tb_ret_addr);
1394                tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1395            }
1396            tcg_out_opc_imm(s, OPC_ORI, TCG_REG_V0, b0, a0 & 0xffff);
1397        }
1398        break;
1399    case INDEX_op_goto_tb:
1400        if (s->tb_jmp_offset) {
1401            /* direct jump method */
1402            s->tb_jmp_offset[a0] = tcg_current_code_size(s);
1403            /* Avoid clobbering the address during retranslation.  */
1404            tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff));
1405        } else {
1406            /* indirect jump method */
1407            tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
1408                       (uintptr_t)(s->tb_next + a0));
1409            tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1410        }
1411        tcg_out_nop(s);
1412        s->tb_next_offset[a0] = tcg_current_code_size(s);
1413        break;
1414    case INDEX_op_br:
1415        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
1416                       arg_label(a0));
1417        break;
1418
1419    case INDEX_op_ld8u_i32:
1420        i1 = OPC_LBU;
1421        goto do_ldst;
1422    case INDEX_op_ld8s_i32:
1423        i1 = OPC_LB;
1424        goto do_ldst;
1425    case INDEX_op_ld16u_i32:
1426        i1 = OPC_LHU;
1427        goto do_ldst;
1428    case INDEX_op_ld16s_i32:
1429        i1 = OPC_LH;
1430        goto do_ldst;
1431    case INDEX_op_ld_i32:
1432        i1 = OPC_LW;
1433        goto do_ldst;
1434    case INDEX_op_st8_i32:
1435        i1 = OPC_SB;
1436        goto do_ldst;
1437    case INDEX_op_st16_i32:
1438        i1 = OPC_SH;
1439        goto do_ldst;
1440    case INDEX_op_st_i32:
1441        i1 = OPC_SW;
1442    do_ldst:
1443        tcg_out_ldst(s, i1, a0, a1, a2);
1444        break;
1445
1446    case INDEX_op_add_i32:
1447        i1 = OPC_ADDU, i2 = OPC_ADDIU;
1448        goto do_binary;
1449    case INDEX_op_or_i32:
1450        i1 = OPC_OR, i2 = OPC_ORI;
1451        goto do_binary;
1452    case INDEX_op_xor_i32:
1453        i1 = OPC_XOR, i2 = OPC_XORI;
1454    do_binary:
1455        if (c2) {
1456            tcg_out_opc_imm(s, i2, a0, a1, a2);
1457            break;
1458        }
1459    do_binaryv:
1460        tcg_out_opc_reg(s, i1, a0, a1, a2);
1461        break;
1462
1463    case INDEX_op_sub_i32:
1464        if (c2) {
1465            tcg_out_opc_imm(s, OPC_ADDIU, a0, a1, -a2);
1466            break;
1467        }
1468        i1 = OPC_SUBU;
1469        goto do_binary;
1470    case INDEX_op_and_i32:
1471        if (c2 && a2 != (uint16_t)a2) {
1472            int msb = ctz32(~a2) - 1;
1473            tcg_debug_assert(use_mips32r2_instructions);
1474            tcg_debug_assert(is_p2m1(a2));
1475            tcg_out_opc_bf(s, OPC_EXT, a0, a1, msb, 0);
1476            break;
1477        }
1478        i1 = OPC_AND, i2 = OPC_ANDI;
1479        goto do_binary;
1480    case INDEX_op_nor_i32:
1481        i1 = OPC_NOR;
1482        goto do_binaryv;
1483
1484    case INDEX_op_mul_i32:
1485        if (use_mips32_instructions) {
1486            tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2);
1487            break;
1488        }
1489        i1 = OPC_MULT, i2 = OPC_MFLO;
1490        goto do_hilo1;
1491    case INDEX_op_mulsh_i32:
1492        if (use_mips32r6_instructions) {
1493            tcg_out_opc_reg(s, OPC_MUH, a0, a1, a2);
1494            break;
1495        }
1496        i1 = OPC_MULT, i2 = OPC_MFHI;
1497        goto do_hilo1;
1498    case INDEX_op_muluh_i32:
1499        if (use_mips32r6_instructions) {
1500            tcg_out_opc_reg(s, OPC_MUHU, a0, a1, a2);
1501            break;
1502        }
1503        i1 = OPC_MULTU, i2 = OPC_MFHI;
1504        goto do_hilo1;
1505    case INDEX_op_div_i32:
1506        if (use_mips32r6_instructions) {
1507            tcg_out_opc_reg(s, OPC_DIV_R6, a0, a1, a2);
1508            break;
1509        }
1510        i1 = OPC_DIV, i2 = OPC_MFLO;
1511        goto do_hilo1;
1512    case INDEX_op_divu_i32:
1513        if (use_mips32r6_instructions) {
1514            tcg_out_opc_reg(s, OPC_DIVU_R6, a0, a1, a2);
1515            break;
1516        }
1517        i1 = OPC_DIVU, i2 = OPC_MFLO;
1518        goto do_hilo1;
1519    case INDEX_op_rem_i32:
1520        if (use_mips32r6_instructions) {
1521            tcg_out_opc_reg(s, OPC_MOD, a0, a1, a2);
1522            break;
1523        }
1524        i1 = OPC_DIV, i2 = OPC_MFHI;
1525        goto do_hilo1;
1526    case INDEX_op_remu_i32:
1527        if (use_mips32r6_instructions) {
1528            tcg_out_opc_reg(s, OPC_MODU, a0, a1, a2);
1529            break;
1530        }
1531        i1 = OPC_DIVU, i2 = OPC_MFHI;
1532    do_hilo1:
1533        tcg_out_opc_reg(s, i1, 0, a1, a2);
1534        tcg_out_opc_reg(s, i2, a0, 0, 0);
1535        break;
1536
1537    case INDEX_op_muls2_i32:
1538        i1 = OPC_MULT;
1539        goto do_hilo2;
1540    case INDEX_op_mulu2_i32:
1541        i1 = OPC_MULTU;
1542    do_hilo2:
1543        tcg_out_opc_reg(s, i1, 0, a2, args[3]);
1544        tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1545        tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1546        break;
1547
1548    case INDEX_op_not_i32:
1549        i1 = OPC_NOR;
1550        goto do_unary;
1551    case INDEX_op_bswap16_i32:
1552        i1 = OPC_WSBH;
1553        goto do_unary;
1554    case INDEX_op_ext8s_i32:
1555        i1 = OPC_SEB;
1556        goto do_unary;
1557    case INDEX_op_ext16s_i32:
1558        i1 = OPC_SEH;
1559    do_unary:
1560        tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1);
1561        break;
1562
1563    case INDEX_op_sar_i32:
1564        i1 = OPC_SRAV, i2 = OPC_SRA;
1565        goto do_shift;
1566    case INDEX_op_shl_i32:
1567        i1 = OPC_SLLV, i2 = OPC_SLL;
1568        goto do_shift;
1569    case INDEX_op_shr_i32:
1570        i1 = OPC_SRLV, i2 = OPC_SRL;
1571        goto do_shift;
1572    case INDEX_op_rotr_i32:
1573        i1 = OPC_ROTRV, i2 = OPC_ROTR;
1574    do_shift:
1575        if (c2) {
1576            tcg_out_opc_sa(s, i2, a0, a1, a2);
1577        } else {
1578            tcg_out_opc_reg(s, i1, a0, a2, a1);
1579        }
1580        break;
1581    case INDEX_op_rotl_i32:
1582        if (c2) {
1583            tcg_out_opc_sa(s, OPC_ROTR, a0, a1, 32 - a2);
1584        } else {
1585            tcg_out_opc_reg(s, OPC_SUBU, TCG_TMP0, TCG_REG_ZERO, a2);
1586            tcg_out_opc_reg(s, OPC_ROTRV, a0, TCG_TMP0, a1);
1587        }
1588        break;
1589
1590    case INDEX_op_bswap32_i32:
1591        tcg_out_opc_reg(s, OPC_WSBH, a0, 0, a1);
1592        tcg_out_opc_sa(s, OPC_ROTR, a0, a0, 16);
1593        break;
1594
1595    case INDEX_op_deposit_i32:
1596        tcg_out_opc_bf(s, OPC_INS, a0, a2, args[3] + args[4] - 1, args[3]);
1597        break;
1598
1599    case INDEX_op_brcond_i32:
1600        tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
1601        break;
1602    case INDEX_op_brcond2_i32:
1603        tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
1604        break;
1605
1606    case INDEX_op_movcond_i32:
1607        tcg_out_movcond(s, args[5], a0, a1, a2, args[3], args[4]);
1608        break;
1609
1610    case INDEX_op_setcond_i32:
1611        tcg_out_setcond(s, args[3], a0, a1, a2);
1612        break;
1613    case INDEX_op_setcond2_i32:
1614        tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
1615        break;
1616
1617    case INDEX_op_qemu_ld_i32:
1618        tcg_out_qemu_ld(s, args, false);
1619        break;
1620    case INDEX_op_qemu_ld_i64:
1621        tcg_out_qemu_ld(s, args, true);
1622        break;
1623    case INDEX_op_qemu_st_i32:
1624        tcg_out_qemu_st(s, args, false);
1625        break;
1626    case INDEX_op_qemu_st_i64:
1627        tcg_out_qemu_st(s, args, true);
1628        break;
1629
1630    case INDEX_op_add2_i32:
1631        tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
1632                        const_args[4], const_args[5], false);
1633        break;
1634    case INDEX_op_sub2_i32:
1635        tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
1636                        const_args[4], const_args[5], true);
1637        break;
1638
1639    case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
1640    case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
1641    case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1642    default:
1643        tcg_abort();
1644    }
1645}
1646
1647static const TCGTargetOpDef mips_op_defs[] = {
1648    { INDEX_op_exit_tb, { } },
1649    { INDEX_op_goto_tb, { } },
1650    { INDEX_op_br, { } },
1651
1652    { INDEX_op_ld8u_i32, { "r", "r" } },
1653    { INDEX_op_ld8s_i32, { "r", "r" } },
1654    { INDEX_op_ld16u_i32, { "r", "r" } },
1655    { INDEX_op_ld16s_i32, { "r", "r" } },
1656    { INDEX_op_ld_i32, { "r", "r" } },
1657    { INDEX_op_st8_i32, { "rZ", "r" } },
1658    { INDEX_op_st16_i32, { "rZ", "r" } },
1659    { INDEX_op_st_i32, { "rZ", "r" } },
1660
1661    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1662    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1663#if !use_mips32r6_instructions
1664    { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } },
1665    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1666#endif
1667    { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } },
1668    { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } },
1669    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1670    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1671    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1672    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1673    { INDEX_op_sub_i32, { "r", "rZ", "rN" } },
1674
1675    { INDEX_op_and_i32, { "r", "rZ", "rIK" } },
1676    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1677    { INDEX_op_not_i32, { "r", "rZ" } },
1678    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1679    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1680
1681    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1682    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1683    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1684    { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1685    { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1686
1687    { INDEX_op_bswap16_i32, { "r", "r" } },
1688    { INDEX_op_bswap32_i32, { "r", "r" } },
1689
1690    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1691    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1692
1693    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1694
1695    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1696#if use_mips32r6_instructions
1697    { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1698#else
1699    { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1700#endif
1701    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1702    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1703
1704    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
1705    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
1706    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1707
1708#if TARGET_LONG_BITS == 32
1709    { INDEX_op_qemu_ld_i32, { "L", "lZ" } },
1710    { INDEX_op_qemu_st_i32, { "SZ", "SZ" } },
1711    { INDEX_op_qemu_ld_i64, { "L", "L", "lZ" } },
1712    { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ" } },
1713#else
1714    { INDEX_op_qemu_ld_i32, { "L", "lZ", "lZ" } },
1715    { INDEX_op_qemu_st_i32, { "SZ", "SZ", "SZ" } },
1716    { INDEX_op_qemu_ld_i64, { "L", "L", "lZ", "lZ" } },
1717    { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ", "SZ" } },
1718#endif
1719    { -1 },
1720};
1721
1722static int tcg_target_callee_save_regs[] = {
1723    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1724    TCG_REG_S1,
1725    TCG_REG_S2,
1726    TCG_REG_S3,
1727    TCG_REG_S4,
1728    TCG_REG_S5,
1729    TCG_REG_S6,
1730    TCG_REG_S7,
1731    TCG_REG_S8,
1732    TCG_REG_RA,       /* should be last for ABI compliance */
1733};
1734
1735/* The Linux kernel doesn't provide any information about the available
1736   instruction set. Probe it using a signal handler. */
1737
1738
1739#ifndef use_movnz_instructions
1740bool use_movnz_instructions = false;
1741#endif
1742
1743#ifndef use_mips32_instructions
1744bool use_mips32_instructions = false;
1745#endif
1746
1747#ifndef use_mips32r2_instructions
1748bool use_mips32r2_instructions = false;
1749#endif
1750
1751static volatile sig_atomic_t got_sigill;
1752
1753static void sigill_handler(int signo, siginfo_t *si, void *data)
1754{
1755    /* Skip the faulty instruction */
1756    ucontext_t *uc = (ucontext_t *)data;
1757    uc->uc_mcontext.pc += 4;
1758
1759    got_sigill = 1;
1760}
1761
1762static void tcg_target_detect_isa(void)
1763{
1764    struct sigaction sa_old, sa_new;
1765
1766    memset(&sa_new, 0, sizeof(sa_new));
1767    sa_new.sa_flags = SA_SIGINFO;
1768    sa_new.sa_sigaction = sigill_handler;
1769    sigaction(SIGILL, &sa_new, &sa_old);
1770
1771    /* Probe for movn/movz, necessary to implement movcond. */
1772#ifndef use_movnz_instructions
1773    got_sigill = 0;
1774    asm volatile(".set push\n"
1775                 ".set mips32\n"
1776                 "movn $zero, $zero, $zero\n"
1777                 "movz $zero, $zero, $zero\n"
1778                 ".set pop\n"
1779                 : : : );
1780    use_movnz_instructions = !got_sigill;
1781#endif
1782
1783    /* Probe for MIPS32 instructions. As no subsetting is allowed
1784       by the specification, it is only necessary to probe for one
1785       of the instructions. */
1786#ifndef use_mips32_instructions
1787    got_sigill = 0;
1788    asm volatile(".set push\n"
1789                 ".set mips32\n"
1790                 "mul $zero, $zero\n"
1791                 ".set pop\n"
1792                 : : : );
1793    use_mips32_instructions = !got_sigill;
1794#endif
1795
1796    /* Probe for MIPS32r2 instructions if MIPS32 instructions are
1797       available. As no subsetting is allowed by the specification,
1798       it is only necessary to probe for one of the instructions. */
1799#ifndef use_mips32r2_instructions
1800    if (use_mips32_instructions) {
1801        got_sigill = 0;
1802        asm volatile(".set push\n"
1803                     ".set mips32r2\n"
1804                     "seb $zero, $zero\n"
1805                     ".set pop\n"
1806                     : : : );
1807        use_mips32r2_instructions = !got_sigill;
1808    }
1809#endif
1810
1811    sigaction(SIGILL, &sa_old, NULL);
1812}
1813
1814/* Generate global QEMU prologue and epilogue code */
1815static void tcg_target_qemu_prologue(TCGContext *s)
1816{
1817    int i, frame_size;
1818
1819    /* reserve some stack space, also for TCG temps. */
1820    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1821                 + TCG_STATIC_CALL_ARGS_SIZE
1822                 + CPU_TEMP_BUF_NLONGS * sizeof(long);
1823    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1824                 ~(TCG_TARGET_STACK_ALIGN - 1);
1825    tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1826                  + TCG_STATIC_CALL_ARGS_SIZE,
1827                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1828
1829    /* TB prologue */
1830    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1831    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1832        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1833                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1834    }
1835
1836    /* Call generated code */
1837    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1838    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1839    tb_ret_addr = s->code_ptr;
1840
1841    /* TB epilogue */
1842    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1843        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1844                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1845    }
1846
1847    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1848    tcg_out_addi(s, TCG_REG_SP, frame_size);
1849}
1850
1851static void tcg_target_init(TCGContext *s)
1852{
1853    tcg_target_detect_isa();
1854    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1855    tcg_regset_set(tcg_target_call_clobber_regs,
1856                   (1 << TCG_REG_V0) |
1857                   (1 << TCG_REG_V1) |
1858                   (1 << TCG_REG_A0) |
1859                   (1 << TCG_REG_A1) |
1860                   (1 << TCG_REG_A2) |
1861                   (1 << TCG_REG_A3) |
1862                   (1 << TCG_REG_T0) |
1863                   (1 << TCG_REG_T1) |
1864                   (1 << TCG_REG_T2) |
1865                   (1 << TCG_REG_T3) |
1866                   (1 << TCG_REG_T4) |
1867                   (1 << TCG_REG_T5) |
1868                   (1 << TCG_REG_T6) |
1869                   (1 << TCG_REG_T7) |
1870                   (1 << TCG_REG_T8) |
1871                   (1 << TCG_REG_T9));
1872
1873    tcg_regset_clear(s->reserved_regs);
1874    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1875    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1876    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1877    tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);     /* internal use */
1878    tcg_regset_set_reg(s->reserved_regs, TCG_TMP1);     /* internal use */
1879    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1880    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1881    tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
1882
1883    tcg_add_target_add_op_defs(mips_op_defs);
1884}
1885
1886void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
1887{
1888    uint32_t *ptr = (uint32_t *)jmp_addr;
1889    *ptr = deposit32(*ptr, 0, 26, addr >> 2);
1890    flush_icache_range(jmp_addr, jmp_addr + 4);
1891}
1892