qemu/tcg/mips/tcg-target.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#if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
  28# define TCG_NEED_BSWAP 0
  29#else
  30# define TCG_NEED_BSWAP 1
  31#endif
  32
  33#ifndef NDEBUG
  34static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
  35    "zero",
  36    "at",
  37    "v0",
  38    "v1",
  39    "a0",
  40    "a1",
  41    "a2",
  42    "a3",
  43    "t0",
  44    "t1",
  45    "t2",
  46    "t3",
  47    "t4",
  48    "t5",
  49    "t6",
  50    "t7",
  51    "s0",
  52    "s1",
  53    "s2",
  54    "s3",
  55    "s4",
  56    "s5",
  57    "s6",
  58    "s7",
  59    "t8",
  60    "t9",
  61    "k0",
  62    "k1",
  63    "gp",
  64    "sp",
  65    "fp",
  66    "ra",
  67};
  68#endif
  69
  70/* check if we really need so many registers :P */
  71static const int tcg_target_reg_alloc_order[] = {
  72    TCG_REG_S0,
  73    TCG_REG_S1,
  74    TCG_REG_S2,
  75    TCG_REG_S3,
  76    TCG_REG_S4,
  77    TCG_REG_S5,
  78    TCG_REG_S6,
  79    TCG_REG_S7,
  80    TCG_REG_T1,
  81    TCG_REG_T2,
  82    TCG_REG_T3,
  83    TCG_REG_T4,
  84    TCG_REG_T5,
  85    TCG_REG_T6,
  86    TCG_REG_T7,
  87    TCG_REG_T8,
  88    TCG_REG_T9,
  89    TCG_REG_A0,
  90    TCG_REG_A1,
  91    TCG_REG_A2,
  92    TCG_REG_A3,
  93    TCG_REG_V0,
  94    TCG_REG_V1
  95};
  96
  97static const int tcg_target_call_iarg_regs[4] = {
  98    TCG_REG_A0,
  99    TCG_REG_A1,
 100    TCG_REG_A2,
 101    TCG_REG_A3
 102};
 103
 104static const int tcg_target_call_oarg_regs[2] = {
 105    TCG_REG_V0,
 106    TCG_REG_V1
 107};
 108
 109static uint8_t *tb_ret_addr;
 110
 111static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
 112{
 113    return target & 0xffff;
 114}
 115
 116static inline void reloc_lo16 (void *pc, tcg_target_long target)
 117{
 118    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
 119                       | reloc_lo16_val(pc, target);
 120}
 121
 122static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
 123{
 124    return (target >> 16) & 0xffff;
 125}
 126
 127static inline void reloc_hi16 (void *pc, tcg_target_long target)
 128{
 129    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
 130                       | reloc_hi16_val(pc, target);
 131}
 132
 133static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
 134{
 135    int32_t disp;
 136
 137    disp = target - (tcg_target_long) pc - 4;
 138    if (disp != (disp << 14) >> 14) {
 139        tcg_abort ();
 140    }
 141
 142    return (disp >> 2) & 0xffff;
 143}
 144
 145static inline void reloc_pc16 (void *pc, tcg_target_long target)
 146{
 147    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
 148                       | reloc_pc16_val(pc, target);
 149}
 150
 151static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
 152{
 153    if ((((tcg_target_long)pc + 4) & 0xf0000000) != (target & 0xf0000000)) {
 154        tcg_abort ();
 155    }
 156
 157    return (target >> 2) & 0x3ffffff;
 158}
 159
 160static inline void reloc_pc26 (void *pc, tcg_target_long target)
 161{
 162    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
 163                       | reloc_26_val(pc, target);
 164}
 165
 166static void patch_reloc(uint8_t *code_ptr, int type,
 167                        tcg_target_long value, tcg_target_long addend)
 168{
 169    value += addend;
 170    switch(type) {
 171    case R_MIPS_LO16:
 172        reloc_lo16(code_ptr, value);
 173        break;
 174    case R_MIPS_HI16:
 175        reloc_hi16(code_ptr, value);
 176        break;
 177    case R_MIPS_PC16:
 178        reloc_pc16(code_ptr, value);
 179        break;
 180    case R_MIPS_26:
 181        reloc_pc26(code_ptr, value);
 182        break;
 183    default:
 184        tcg_abort();
 185    }
 186}
 187
 188/* maximum number of register used for input function arguments */
 189static inline int tcg_target_get_call_iarg_regs_count(int flags)
 190{
 191    return 4;
 192}
 193
 194/* parse target specific constraints */
 195static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 196{
 197    const char *ct_str;
 198
 199    ct_str = *pct_str;
 200    switch(ct_str[0]) {
 201    case 'r':
 202        ct->ct |= TCG_CT_REG;
 203        tcg_regset_set(ct->u.regs, 0xffffffff);
 204        break;
 205    case 'C':
 206        ct->ct |= TCG_CT_REG;
 207        tcg_regset_clear(ct->u.regs);
 208        tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
 209        break;
 210    case 'L': /* qemu_ld output arg constraint */
 211        ct->ct |= TCG_CT_REG;
 212        tcg_regset_set(ct->u.regs, 0xffffffff);
 213        tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
 214        break;
 215    case 'l': /* qemu_ld input arg constraint */
 216        ct->ct |= TCG_CT_REG;
 217        tcg_regset_set(ct->u.regs, 0xffffffff);
 218#if defined(CONFIG_SOFTMMU)
 219        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 220#endif
 221        break;
 222    case 'S': /* qemu_st constraint */
 223        ct->ct |= TCG_CT_REG;
 224        tcg_regset_set(ct->u.regs, 0xffffffff);
 225        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 226#if defined(CONFIG_SOFTMMU)
 227# if TARGET_LONG_BITS == 64
 228        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
 229# endif
 230        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 231#endif
 232        break;
 233    case 'I':
 234        ct->ct |= TCG_CT_CONST_U16;
 235        break;
 236    case 'J':
 237        ct->ct |= TCG_CT_CONST_S16;
 238        break;
 239    case 'Z':
 240        /* We are cheating a bit here, using the fact that the register
 241           ZERO is also the register number 0. Hence there is no need
 242           to check for const_args in each instruction. */
 243        ct->ct |= TCG_CT_CONST_ZERO;
 244        break;
 245    default:
 246        return -1;
 247    }
 248    ct_str++;
 249    *pct_str = ct_str;
 250    return 0;
 251}
 252
 253/* test if a constant matches the constraint */
 254static inline int tcg_target_const_match(tcg_target_long val,
 255                                         const TCGArgConstraint *arg_ct)
 256{
 257    int ct;
 258    ct = arg_ct->ct;
 259    if (ct & TCG_CT_CONST)
 260        return 1;
 261    else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
 262        return 1;
 263    else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
 264        return 1;
 265    else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
 266        return 1;
 267    else
 268        return 0;
 269}
 270
 271/* instruction opcodes */
 272enum {
 273    OPC_BEQ      = 0x04 << 26,
 274    OPC_BNE      = 0x05 << 26,
 275    OPC_ADDIU    = 0x09 << 26,
 276    OPC_SLTI     = 0x0A << 26,
 277    OPC_SLTIU    = 0x0B << 26,
 278    OPC_ANDI     = 0x0C << 26,
 279    OPC_ORI      = 0x0D << 26,
 280    OPC_XORI     = 0x0E << 26,
 281    OPC_LUI      = 0x0F << 26,
 282    OPC_LB       = 0x20 << 26,
 283    OPC_LH       = 0x21 << 26,
 284    OPC_LW       = 0x23 << 26,
 285    OPC_LBU      = 0x24 << 26,
 286    OPC_LHU      = 0x25 << 26,
 287    OPC_LWU      = 0x27 << 26,
 288    OPC_SB       = 0x28 << 26,
 289    OPC_SH       = 0x29 << 26,
 290    OPC_SW       = 0x2B << 26,
 291
 292    OPC_SPECIAL  = 0x00 << 26,
 293    OPC_SLL      = OPC_SPECIAL | 0x00,
 294    OPC_SRL      = OPC_SPECIAL | 0x02,
 295    OPC_SRA      = OPC_SPECIAL | 0x03,
 296    OPC_SLLV     = OPC_SPECIAL | 0x04,
 297    OPC_SRLV     = OPC_SPECIAL | 0x06,
 298    OPC_SRAV     = OPC_SPECIAL | 0x07,
 299    OPC_JR       = OPC_SPECIAL | 0x08,
 300    OPC_JALR     = OPC_SPECIAL | 0x09,
 301    OPC_MFHI     = OPC_SPECIAL | 0x10,
 302    OPC_MFLO     = OPC_SPECIAL | 0x12,
 303    OPC_MULT     = OPC_SPECIAL | 0x18,
 304    OPC_MULTU    = OPC_SPECIAL | 0x19,
 305    OPC_DIV      = OPC_SPECIAL | 0x1A,
 306    OPC_DIVU     = OPC_SPECIAL | 0x1B,
 307    OPC_ADDU     = OPC_SPECIAL | 0x21,
 308    OPC_SUBU     = OPC_SPECIAL | 0x23,
 309    OPC_AND      = OPC_SPECIAL | 0x24,
 310    OPC_OR       = OPC_SPECIAL | 0x25,
 311    OPC_XOR      = OPC_SPECIAL | 0x26,
 312    OPC_NOR      = OPC_SPECIAL | 0x27,
 313    OPC_SLT      = OPC_SPECIAL | 0x2A,
 314    OPC_SLTU     = OPC_SPECIAL | 0x2B,
 315
 316    OPC_SPECIAL3 = 0x1f << 26,
 317    OPC_SEB      = OPC_SPECIAL3 | 0x420,
 318    OPC_SEH      = OPC_SPECIAL3 | 0x620,
 319};
 320
 321/*
 322 * Type reg
 323 */
 324static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
 325{
 326    int32_t inst;
 327
 328    inst = opc;
 329    inst |= (rs & 0x1F) << 21;
 330    inst |= (rt & 0x1F) << 16;
 331    inst |= (rd & 0x1F) << 11;
 332    tcg_out32(s, inst);
 333}
 334
 335/*
 336 * Type immediate
 337 */
 338static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
 339{
 340    int32_t inst;
 341
 342    inst = opc;
 343    inst |= (rs & 0x1F) << 21;
 344    inst |= (rt & 0x1F) << 16;
 345    inst |= (imm & 0xffff);
 346    tcg_out32(s, inst);
 347}
 348
 349/*
 350 * Type branch
 351 */
 352static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
 353{
 354    /* We pay attention here to not modify the branch target by reading
 355       the existing value and using it again. This ensure that caches and
 356       memory are kept coherent during retranslation. */
 357    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
 358
 359    tcg_out_opc_imm(s, opc, rt, rs, offset);
 360}
 361
 362/*
 363 * Type sa
 364 */
 365static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
 366{
 367    int32_t inst;
 368
 369    inst = opc;
 370    inst |= (rt & 0x1F) << 16;
 371    inst |= (rd & 0x1F) << 11;
 372    inst |= (sa & 0x1F) <<  6;
 373    tcg_out32(s, inst);
 374
 375}
 376
 377static inline void tcg_out_nop(TCGContext *s)
 378{
 379    tcg_out32(s, 0);
 380}
 381
 382static inline void tcg_out_mov(TCGContext *s, TCGType type,
 383                               TCGReg ret, TCGReg arg)
 384{
 385    tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
 386}
 387
 388static inline void tcg_out_movi(TCGContext *s, TCGType type,
 389                                TCGReg reg, tcg_target_long arg)
 390{
 391    if (arg == (int16_t)arg) {
 392        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
 393    } else if (arg == (uint16_t)arg) {
 394        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
 395    } else {
 396        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
 397        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
 398    }
 399}
 400
 401static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
 402{
 403    /* ret and arg can't be register at */
 404    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
 405        tcg_abort();
 406    }
 407
 408    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 409    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
 410
 411    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
 412    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
 413    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 414}
 415
 416static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
 417{
 418    /* ret and arg can't be register at */
 419    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
 420        tcg_abort();
 421    }
 422
 423    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 424    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
 425
 426    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 427    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 428    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 429}
 430
 431static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
 432{
 433    /* ret and arg must be different and can't be register at */
 434    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
 435        tcg_abort();
 436    }
 437
 438    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 439
 440    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
 441    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 442
 443    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
 444    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
 445    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 446
 447    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 448    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
 449    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 450}
 451
 452static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
 453{
 454#ifdef _MIPS_ARCH_MIPS32R2
 455    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
 456#else
 457    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 458    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
 459#endif
 460}
 461
 462static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
 463{
 464#ifdef _MIPS_ARCH_MIPS32R2
 465    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
 466#else
 467    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
 468    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 469#endif
 470}
 471
 472static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
 473                              int arg1, tcg_target_long arg2)
 474{
 475    if (arg2 == (int16_t) arg2) {
 476        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
 477    } else {
 478        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
 479        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
 480        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
 481    }
 482}
 483
 484static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
 485                              TCGReg arg1, tcg_target_long arg2)
 486{
 487    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
 488}
 489
 490static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 491                              TCGReg arg1, tcg_target_long arg2)
 492{
 493    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
 494}
 495
 496static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
 497{
 498    if (val == (int16_t)val) {
 499        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
 500    } else {
 501        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
 502        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
 503    }
 504}
 505
 506static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
 507                           int arg2, int label_index)
 508{
 509    TCGLabel *l = &s->labels[label_index];
 510
 511    switch (cond) {
 512    case TCG_COND_EQ:
 513        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
 514        break;
 515    case TCG_COND_NE:
 516        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
 517        break;
 518    case TCG_COND_LT:
 519        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
 520        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 521        break;
 522    case TCG_COND_LTU:
 523        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
 524        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 525        break;
 526    case TCG_COND_GE:
 527        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
 528        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 529        break;
 530    case TCG_COND_GEU:
 531        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
 532        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 533        break;
 534    case TCG_COND_LE:
 535        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
 536        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 537        break;
 538    case TCG_COND_LEU:
 539        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
 540        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 541        break;
 542    case TCG_COND_GT:
 543        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
 544        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 545        break;
 546    case TCG_COND_GTU:
 547        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
 548        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 549        break;
 550    default:
 551        tcg_abort();
 552        break;
 553    }
 554    if (l->has_value) {
 555        reloc_pc16(s->code_ptr - 4, l->u.value);
 556    } else {
 557        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
 558    }
 559    tcg_out_nop(s);
 560}
 561
 562/* XXX: we implement it at the target level to avoid having to
 563   handle cross basic blocks temporaries */
 564static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
 565                            int arg2, int arg3, int arg4, int label_index)
 566{
 567    void *label_ptr;
 568
 569    switch(cond) {
 570    case TCG_COND_NE:
 571        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
 572        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
 573        return;
 574    case TCG_COND_EQ:
 575        break;
 576    case TCG_COND_LT:
 577    case TCG_COND_LE:
 578        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
 579        break;
 580    case TCG_COND_GT:
 581    case TCG_COND_GE:
 582        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
 583        break;
 584    case TCG_COND_LTU:
 585    case TCG_COND_LEU:
 586        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
 587        break;
 588    case TCG_COND_GTU:
 589    case TCG_COND_GEU:
 590        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
 591        break;
 592    default:
 593        tcg_abort();
 594    }
 595
 596    label_ptr = s->code_ptr;
 597    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
 598    tcg_out_nop(s);
 599
 600    switch(cond) {
 601    case TCG_COND_EQ:
 602        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
 603        break;
 604    case TCG_COND_LT:
 605    case TCG_COND_LTU:
 606        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
 607        break;
 608    case TCG_COND_LE:
 609    case TCG_COND_LEU:
 610        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
 611        break;
 612    case TCG_COND_GT:
 613    case TCG_COND_GTU:
 614        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
 615        break;
 616    case TCG_COND_GE:
 617    case TCG_COND_GEU:
 618        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
 619        break;
 620    default:
 621        tcg_abort();
 622    }
 623
 624    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
 625}
 626
 627static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
 628                            int arg1, int arg2)
 629{
 630    switch (cond) {
 631    case TCG_COND_EQ:
 632        if (arg1 == 0) {
 633            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
 634        } else if (arg2 == 0) {
 635            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
 636        } else {
 637            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 638            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
 639        }
 640        break;
 641    case TCG_COND_NE:
 642        if (arg1 == 0) {
 643            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
 644        } else if (arg2 == 0) {
 645            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
 646        } else {
 647            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 648            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
 649        }
 650        break;
 651    case TCG_COND_LT:
 652        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
 653        break;
 654    case TCG_COND_LTU:
 655        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
 656        break;
 657    case TCG_COND_GE:
 658        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
 659        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 660        break;
 661    case TCG_COND_GEU:
 662        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
 663        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 664        break;
 665    case TCG_COND_LE:
 666        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
 667        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 668        break;
 669    case TCG_COND_LEU:
 670        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
 671        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 672        break;
 673    case TCG_COND_GT:
 674        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
 675        break;
 676    case TCG_COND_GTU:
 677        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
 678        break;
 679    default:
 680        tcg_abort();
 681        break;
 682    }
 683}
 684
 685/* XXX: we implement it at the target level to avoid having to
 686   handle cross basic blocks temporaries */
 687static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
 688                             int arg1, int arg2, int arg3, int arg4)
 689{
 690    switch (cond) {
 691    case TCG_COND_EQ:
 692        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
 693        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
 694        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
 695        return;
 696    case TCG_COND_NE:
 697        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
 698        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
 699        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
 700        return;
 701    case TCG_COND_LT:
 702    case TCG_COND_LE:
 703        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
 704        break;
 705    case TCG_COND_GT:
 706    case TCG_COND_GE:
 707        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
 708        break;
 709    case TCG_COND_LTU:
 710    case TCG_COND_LEU:
 711        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
 712        break;
 713    case TCG_COND_GTU:
 714    case TCG_COND_GEU:
 715        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
 716        break;
 717    default:
 718        tcg_abort();
 719        break;
 720    }
 721
 722    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
 723
 724    switch(cond) {
 725    case TCG_COND_LT:
 726    case TCG_COND_LTU:
 727        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
 728        break;
 729    case TCG_COND_LE:
 730    case TCG_COND_LEU:
 731        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
 732        break;
 733    case TCG_COND_GT:
 734    case TCG_COND_GTU:
 735        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
 736        break;
 737    case TCG_COND_GE:
 738    case TCG_COND_GEU:
 739        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
 740        break;
 741    default:
 742        tcg_abort();
 743    }
 744
 745    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
 746    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 747}
 748
 749#if defined(CONFIG_SOFTMMU)
 750
 751#include "../../softmmu_defs.h"
 752
 753#ifdef CONFIG_TCG_PASS_AREG0
 754/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
 755   int mmu_idx) */
 756static const void * const qemu_ld_helpers[4] = {
 757    helper_ldb_mmu,
 758    helper_ldw_mmu,
 759    helper_ldl_mmu,
 760    helper_ldq_mmu,
 761};
 762
 763/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
 764   uintxx_t val, int mmu_idx) */
 765static const void * const qemu_st_helpers[4] = {
 766    helper_stb_mmu,
 767    helper_stw_mmu,
 768    helper_stl_mmu,
 769    helper_stq_mmu,
 770};
 771#else
 772/* legacy helper signature: __ld_mmu(target_ulong addr, int
 773   mmu_idx) */
 774static void *qemu_ld_helpers[4] = {
 775    __ldb_mmu,
 776    __ldw_mmu,
 777    __ldl_mmu,
 778    __ldq_mmu,
 779};
 780
 781/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
 782   int mmu_idx) */
 783static void *qemu_st_helpers[4] = {
 784    __stb_mmu,
 785    __stw_mmu,
 786    __stl_mmu,
 787    __stq_mmu,
 788};
 789#endif
 790#endif
 791
 792static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
 793                            int opc)
 794{
 795    int addr_regl, addr_reg1, addr_meml;
 796    int data_regl, data_regh, data_reg1, data_reg2;
 797    int mem_index, s_bits;
 798#if defined(CONFIG_SOFTMMU)
 799    void *label1_ptr, *label2_ptr;
 800    int sp_args;
 801#endif
 802#if TARGET_LONG_BITS == 64
 803# if defined(CONFIG_SOFTMMU)
 804    uint8_t *label3_ptr;
 805# endif
 806    int addr_regh, addr_reg2, addr_memh;
 807#endif
 808    data_regl = *args++;
 809    if (opc == 3)
 810        data_regh = *args++;
 811    else
 812        data_regh = 0;
 813    addr_regl = *args++;
 814#if TARGET_LONG_BITS == 64
 815    addr_regh = *args++;
 816#endif
 817    mem_index = *args;
 818    s_bits = opc & 3;
 819
 820    if (opc == 3) {
 821#if defined(TCG_TARGET_WORDS_BIGENDIAN)
 822        data_reg1 = data_regh;
 823        data_reg2 = data_regl;
 824#else
 825        data_reg1 = data_regl;
 826        data_reg2 = data_regh;
 827#endif
 828    } else {
 829        data_reg1 = data_regl;
 830        data_reg2 = 0;
 831    }
 832#if TARGET_LONG_BITS == 64
 833# if defined(TCG_TARGET_WORDS_BIGENDIAN)
 834    addr_reg1 = addr_regh;
 835    addr_reg2 = addr_regl;
 836    addr_memh = 0;
 837    addr_meml = 4;
 838# else
 839    addr_reg1 = addr_regl;
 840    addr_reg2 = addr_regh;
 841    addr_memh = 4;
 842    addr_meml = 0;
 843# endif
 844#else
 845    addr_reg1 = addr_regl;
 846    addr_meml = 0;
 847#endif
 848
 849#if defined(CONFIG_SOFTMMU)
 850    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 851    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
 852    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
 853    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 854                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
 855    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
 856    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
 857
 858# if TARGET_LONG_BITS == 64
 859    label3_ptr = s->code_ptr;
 860    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
 861    tcg_out_nop(s);
 862
 863    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 864                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
 865
 866    label1_ptr = s->code_ptr;
 867    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
 868    tcg_out_nop(s);
 869
 870    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
 871# else
 872    label1_ptr = s->code_ptr;
 873    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
 874    tcg_out_nop(s);
 875# endif
 876
 877    /* slow path */
 878    sp_args = TCG_REG_A0;
 879    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
 880# if TARGET_LONG_BITS == 64
 881    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
 882# endif
 883    tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
 884    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
 885#ifdef CONFIG_TCG_PASS_AREG0
 886    /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */
 887    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
 888                tcg_target_call_iarg_regs[1]);
 889    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
 890                tcg_target_call_iarg_regs[0]);
 891    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
 892                TCG_AREG0);
 893#endif
 894    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
 895    tcg_out_nop(s);
 896
 897    switch(opc) {
 898    case 0:
 899        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
 900        break;
 901    case 0 | 4:
 902        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
 903        break;
 904    case 1:
 905        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
 906        break;
 907    case 1 | 4:
 908        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
 909        break;
 910    case 2:
 911        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
 912        break;
 913    case 3:
 914        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
 915        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
 916        break;
 917    default:
 918        tcg_abort();
 919    }
 920
 921    label2_ptr = s->code_ptr;
 922    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
 923    tcg_out_nop(s);
 924
 925    /* label1: fast path */
 926    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
 927
 928    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
 929                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
 930    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
 931#else
 932    if (GUEST_BASE == (int16_t)GUEST_BASE) {
 933        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
 934    } else {
 935        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
 936        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
 937    }
 938#endif
 939
 940    switch(opc) {
 941    case 0:
 942        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
 943        break;
 944    case 0 | 4:
 945        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
 946        break;
 947    case 1:
 948        if (TCG_NEED_BSWAP) {
 949            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
 950            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
 951        } else {
 952            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
 953        }
 954        break;
 955    case 1 | 4:
 956        if (TCG_NEED_BSWAP) {
 957            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
 958            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
 959        } else {
 960            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
 961        }
 962        break;
 963    case 2:
 964        if (TCG_NEED_BSWAP) {
 965            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
 966            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
 967        } else {
 968            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
 969        }
 970        break;
 971    case 3:
 972        if (TCG_NEED_BSWAP) {
 973            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
 974            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
 975            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
 976            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
 977        } else {
 978            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
 979            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
 980        }
 981        break;
 982    default:
 983        tcg_abort();
 984    }
 985
 986#if defined(CONFIG_SOFTMMU)
 987    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
 988#endif
 989}
 990
 991static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
 992                            int opc)
 993{
 994    int addr_regl, addr_reg1, addr_meml;
 995    int data_regl, data_regh, data_reg1, data_reg2;
 996    int mem_index, s_bits;
 997#if defined(CONFIG_SOFTMMU)
 998    uint8_t *label1_ptr, *label2_ptr;
 999    int sp_args;
1000#endif
1001#if TARGET_LONG_BITS == 64
1002# if defined(CONFIG_SOFTMMU)
1003    uint8_t *label3_ptr;
1004# endif
1005    int addr_regh, addr_reg2, addr_memh;
1006#endif
1007
1008    data_regl = *args++;
1009    if (opc == 3) {
1010        data_regh = *args++;
1011#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1012        data_reg1 = data_regh;
1013        data_reg2 = data_regl;
1014#else
1015        data_reg1 = data_regl;
1016        data_reg2 = data_regh;
1017#endif
1018    } else {
1019        data_reg1 = data_regl;
1020        data_reg2 = 0;
1021        data_regh = 0;
1022    }
1023    addr_regl = *args++;
1024#if TARGET_LONG_BITS == 64
1025    addr_regh = *args++;
1026# if defined(TCG_TARGET_WORDS_BIGENDIAN)
1027    addr_reg1 = addr_regh;
1028    addr_reg2 = addr_regl;
1029    addr_memh = 0;
1030    addr_meml = 4;
1031# else
1032    addr_reg1 = addr_regl;
1033    addr_reg2 = addr_regh;
1034    addr_memh = 4;
1035    addr_meml = 0;
1036# endif
1037#else
1038    addr_reg1 = addr_regl;
1039    addr_meml = 0;
1040#endif
1041    mem_index = *args;
1042    s_bits = opc;
1043
1044#if defined(CONFIG_SOFTMMU)
1045    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1046    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1047    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1048    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1049                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1050    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1051    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1052
1053# if TARGET_LONG_BITS == 64
1054    label3_ptr = s->code_ptr;
1055    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1056    tcg_out_nop(s);
1057
1058    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1059                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1060
1061    label1_ptr = s->code_ptr;
1062    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1063    tcg_out_nop(s);
1064
1065    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1066# else
1067    label1_ptr = s->code_ptr;
1068    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1069    tcg_out_nop(s);
1070# endif
1071
1072    /* slow path */
1073    sp_args = TCG_REG_A0;
1074    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1075# if TARGET_LONG_BITS == 64
1076    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1077# endif
1078    switch(opc) {
1079    case 0:
1080        tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
1081        break;
1082    case 1:
1083        tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
1084        break;
1085    case 2:
1086        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1087        break;
1088    case 3:
1089        sp_args = (sp_args + 1) & ~1;
1090        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1091        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
1092        break;
1093    default:
1094        tcg_abort();
1095    }
1096    if (sp_args > TCG_REG_A3) {
1097        /* Push mem_index on the stack */
1098        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
1099        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
1100    } else {
1101        tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
1102    }
1103
1104    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1105#ifdef CONFIG_TCG_PASS_AREG0
1106    /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */
1107    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
1108                tcg_target_call_iarg_regs[2]);
1109    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
1110                tcg_target_call_iarg_regs[1]);
1111    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
1112                tcg_target_call_iarg_regs[0]);
1113    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
1114                TCG_AREG0);
1115#endif
1116    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1117    tcg_out_nop(s);
1118
1119    label2_ptr = s->code_ptr;
1120    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1121    tcg_out_nop(s);
1122
1123    /* label1: fast path */
1124    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1125
1126    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1127                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1128    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1129#else
1130    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1131        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1132    } else {
1133        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1134        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1135    }
1136
1137#endif
1138
1139    switch(opc) {
1140    case 0:
1141        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1142        break;
1143    case 1:
1144        if (TCG_NEED_BSWAP) {
1145            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1146            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1147        } else {
1148            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1149        }
1150        break;
1151    case 2:
1152        if (TCG_NEED_BSWAP) {
1153            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1154            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1155        } else {
1156            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1157        }
1158        break;
1159    case 3:
1160        if (TCG_NEED_BSWAP) {
1161            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1162            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1163            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1164            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1165        } else {
1166            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1167            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1168        }
1169        break;
1170    default:
1171        tcg_abort();
1172    }
1173
1174#if defined(CONFIG_SOFTMMU)
1175    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1176#endif
1177}
1178
1179static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1180                              const TCGArg *args, const int *const_args)
1181{
1182    switch(opc) {
1183    case INDEX_op_exit_tb:
1184        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1185        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1186        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1187        tcg_out_nop(s);
1188        break;
1189    case INDEX_op_goto_tb:
1190        if (s->tb_jmp_offset) {
1191            /* direct jump method */
1192            tcg_abort();
1193        } else {
1194            /* indirect jump method */
1195            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1196            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1197            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1198        }
1199        tcg_out_nop(s);
1200        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1201        break;
1202    case INDEX_op_call:
1203        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1204        tcg_out_nop(s);
1205        break;
1206    case INDEX_op_jmp:
1207        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1208        tcg_out_nop(s);
1209        break;
1210    case INDEX_op_br:
1211        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1212        break;
1213
1214    case INDEX_op_mov_i32:
1215        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1216        break;
1217    case INDEX_op_movi_i32:
1218        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1219        break;
1220
1221    case INDEX_op_ld8u_i32:
1222        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1223        break;
1224    case INDEX_op_ld8s_i32:
1225        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1226        break;
1227    case INDEX_op_ld16u_i32:
1228        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1229        break;
1230    case INDEX_op_ld16s_i32:
1231        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1232        break;
1233    case INDEX_op_ld_i32:
1234        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1235        break;
1236    case INDEX_op_st8_i32:
1237        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1238        break;
1239    case INDEX_op_st16_i32:
1240        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1241        break;
1242    case INDEX_op_st_i32:
1243        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1244        break;
1245
1246    case INDEX_op_add_i32:
1247        if (const_args[2]) {
1248            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1249        } else {
1250            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1251        }
1252        break;
1253    case INDEX_op_add2_i32:
1254        if (const_args[4]) {
1255            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1256        } else {
1257            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1258        }
1259        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1260        if (const_args[5]) {
1261            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1262        } else {
1263             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1264        }
1265        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1266        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1267        break;
1268    case INDEX_op_sub_i32:
1269        if (const_args[2]) {
1270            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1271        } else {
1272            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1273        }
1274        break;
1275    case INDEX_op_sub2_i32:
1276        if (const_args[4]) {
1277            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1278        } else {
1279            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1280        }
1281        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1282        if (const_args[5]) {
1283            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1284        } else {
1285             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1286        }
1287        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1288        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1289        break;
1290    case INDEX_op_mul_i32:
1291        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1292        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1293        break;
1294    case INDEX_op_mulu2_i32:
1295        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1296        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1297        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1298        break;
1299    case INDEX_op_div_i32:
1300        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1301        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1302        break;
1303    case INDEX_op_divu_i32:
1304        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1305        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1306        break;
1307    case INDEX_op_rem_i32:
1308        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1309        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1310        break;
1311    case INDEX_op_remu_i32:
1312        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1313        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1314        break;
1315
1316    case INDEX_op_and_i32:
1317        if (const_args[2]) {
1318            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1319        } else {
1320            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1321        }
1322        break;
1323    case INDEX_op_or_i32:
1324        if (const_args[2]) {
1325            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1326        } else {
1327            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1328        }
1329        break;
1330    case INDEX_op_nor_i32:
1331        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1332        break;
1333    case INDEX_op_not_i32:
1334        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1335        break;
1336    case INDEX_op_xor_i32:
1337        if (const_args[2]) {
1338            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1339        } else {
1340            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1341        }
1342        break;
1343
1344    case INDEX_op_sar_i32:
1345        if (const_args[2]) {
1346            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1347        } else {
1348            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1349        }
1350        break;
1351    case INDEX_op_shl_i32:
1352        if (const_args[2]) {
1353            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1354        } else {
1355            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1356        }
1357        break;
1358    case INDEX_op_shr_i32:
1359        if (const_args[2]) {
1360            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1361        } else {
1362            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1363        }
1364        break;
1365
1366    case INDEX_op_ext8s_i32:
1367        tcg_out_ext8s(s, args[0], args[1]);
1368        break;
1369    case INDEX_op_ext16s_i32:
1370        tcg_out_ext16s(s, args[0], args[1]);
1371        break;
1372
1373    case INDEX_op_brcond_i32:
1374        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1375        break;
1376    case INDEX_op_brcond2_i32:
1377        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1378        break;
1379
1380    case INDEX_op_setcond_i32:
1381        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1382        break;
1383    case INDEX_op_setcond2_i32:
1384        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1385        break;
1386
1387    case INDEX_op_qemu_ld8u:
1388        tcg_out_qemu_ld(s, args, 0);
1389        break;
1390    case INDEX_op_qemu_ld8s:
1391        tcg_out_qemu_ld(s, args, 0 | 4);
1392        break;
1393    case INDEX_op_qemu_ld16u:
1394        tcg_out_qemu_ld(s, args, 1);
1395        break;
1396    case INDEX_op_qemu_ld16s:
1397        tcg_out_qemu_ld(s, args, 1 | 4);
1398        break;
1399    case INDEX_op_qemu_ld32:
1400        tcg_out_qemu_ld(s, args, 2);
1401        break;
1402    case INDEX_op_qemu_ld64:
1403        tcg_out_qemu_ld(s, args, 3);
1404        break;
1405    case INDEX_op_qemu_st8:
1406        tcg_out_qemu_st(s, args, 0);
1407        break;
1408    case INDEX_op_qemu_st16:
1409        tcg_out_qemu_st(s, args, 1);
1410        break;
1411    case INDEX_op_qemu_st32:
1412        tcg_out_qemu_st(s, args, 2);
1413        break;
1414    case INDEX_op_qemu_st64:
1415        tcg_out_qemu_st(s, args, 3);
1416        break;
1417
1418    default:
1419        tcg_abort();
1420    }
1421}
1422
1423static const TCGTargetOpDef mips_op_defs[] = {
1424    { INDEX_op_exit_tb, { } },
1425    { INDEX_op_goto_tb, { } },
1426    { INDEX_op_call, { "C" } },
1427    { INDEX_op_jmp, { "r" } },
1428    { INDEX_op_br, { } },
1429
1430    { INDEX_op_mov_i32, { "r", "r" } },
1431    { INDEX_op_movi_i32, { "r" } },
1432    { INDEX_op_ld8u_i32, { "r", "r" } },
1433    { INDEX_op_ld8s_i32, { "r", "r" } },
1434    { INDEX_op_ld16u_i32, { "r", "r" } },
1435    { INDEX_op_ld16s_i32, { "r", "r" } },
1436    { INDEX_op_ld_i32, { "r", "r" } },
1437    { INDEX_op_st8_i32, { "rZ", "r" } },
1438    { INDEX_op_st16_i32, { "rZ", "r" } },
1439    { INDEX_op_st_i32, { "rZ", "r" } },
1440
1441    { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
1442    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1443    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1444    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1445    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1446    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1447    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1448    { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
1449
1450    { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
1451    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1452    { INDEX_op_not_i32, { "r", "rZ" } },
1453    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1454    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1455
1456    { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
1457    { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1458    { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1459
1460    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1461    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1462
1463    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1464    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1465    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1466
1467    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1468    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1469    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1470
1471#if TARGET_LONG_BITS == 32
1472    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1473    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1474    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1475    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1476    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1477    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1478
1479    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1480    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1481    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1482    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1483#else
1484    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1485    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1486    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1487    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1488    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1489    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1490
1491    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1492    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1493    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1494    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1495#endif
1496    { -1 },
1497};
1498
1499static int tcg_target_callee_save_regs[] = {
1500    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1501    TCG_REG_S1,
1502    TCG_REG_S2,
1503    TCG_REG_S3,
1504    TCG_REG_S4,
1505    TCG_REG_S5,
1506    TCG_REG_S6,
1507    TCG_REG_S7,
1508    TCG_REG_GP,
1509    TCG_REG_FP,
1510    TCG_REG_RA,       /* should be last for ABI compliance */
1511};
1512
1513/* Generate global QEMU prologue and epilogue code */
1514static void tcg_target_qemu_prologue(TCGContext *s)
1515{
1516    int i, frame_size;
1517
1518    /* reserve some stack space */
1519    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1520                 + TCG_STATIC_CALL_ARGS_SIZE;
1521    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1522                 ~(TCG_TARGET_STACK_ALIGN - 1);
1523
1524    /* TB prologue */
1525    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1526    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1527        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1528                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1529    }
1530
1531    /* Call generated code */
1532    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1533    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1534    tb_ret_addr = s->code_ptr;
1535
1536    /* TB epilogue */
1537    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1538        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1539                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1540    }
1541
1542    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1543    tcg_out_addi(s, TCG_REG_SP, frame_size);
1544}
1545
1546static void tcg_target_init(TCGContext *s)
1547{
1548    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1549    tcg_regset_set(tcg_target_call_clobber_regs,
1550                   (1 << TCG_REG_V0) |
1551                   (1 << TCG_REG_V1) |
1552                   (1 << TCG_REG_A0) |
1553                   (1 << TCG_REG_A1) |
1554                   (1 << TCG_REG_A2) |
1555                   (1 << TCG_REG_A3) |
1556                   (1 << TCG_REG_T1) |
1557                   (1 << TCG_REG_T2) |
1558                   (1 << TCG_REG_T3) |
1559                   (1 << TCG_REG_T4) |
1560                   (1 << TCG_REG_T5) |
1561                   (1 << TCG_REG_T6) |
1562                   (1 << TCG_REG_T7) |
1563                   (1 << TCG_REG_T8) |
1564                   (1 << TCG_REG_T9));
1565
1566    tcg_regset_clear(s->reserved_regs);
1567    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1568    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1569    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1570    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1571    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1572    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1573    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1574
1575    tcg_add_target_add_op_defs(mips_op_defs);
1576    tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1577                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1578}
1579