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 TCGReg 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 TCGReg 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 TCGReg 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/* parse target specific constraints */
 189static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 190{
 191    const char *ct_str;
 192
 193    ct_str = *pct_str;
 194    switch(ct_str[0]) {
 195    case 'r':
 196        ct->ct |= TCG_CT_REG;
 197        tcg_regset_set(ct->u.regs, 0xffffffff);
 198        break;
 199    case 'C':
 200        ct->ct |= TCG_CT_REG;
 201        tcg_regset_clear(ct->u.regs);
 202        tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
 203        break;
 204    case 'L': /* qemu_ld output arg constraint */
 205        ct->ct |= TCG_CT_REG;
 206        tcg_regset_set(ct->u.regs, 0xffffffff);
 207        tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
 208        break;
 209    case 'l': /* qemu_ld input arg constraint */
 210        ct->ct |= TCG_CT_REG;
 211        tcg_regset_set(ct->u.regs, 0xffffffff);
 212#if defined(CONFIG_SOFTMMU)
 213        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 214# if (TARGET_LONG_BITS == 64)
 215        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 216# endif
 217#endif
 218        break;
 219    case 'S': /* qemu_st constraint */
 220        ct->ct |= TCG_CT_REG;
 221        tcg_regset_set(ct->u.regs, 0xffffffff);
 222        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 223#if defined(CONFIG_SOFTMMU)
 224# if (TARGET_LONG_BITS == 32)
 225        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
 226# endif
 227        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 228# if TARGET_LONG_BITS == 64
 229        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
 230# endif
 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_BLEZ     = 0x06 << 26,
 276    OPC_BGTZ     = 0x07 << 26,
 277    OPC_ADDIU    = 0x09 << 26,
 278    OPC_SLTI     = 0x0A << 26,
 279    OPC_SLTIU    = 0x0B << 26,
 280    OPC_ANDI     = 0x0C << 26,
 281    OPC_ORI      = 0x0D << 26,
 282    OPC_XORI     = 0x0E << 26,
 283    OPC_LUI      = 0x0F << 26,
 284    OPC_LB       = 0x20 << 26,
 285    OPC_LH       = 0x21 << 26,
 286    OPC_LW       = 0x23 << 26,
 287    OPC_LBU      = 0x24 << 26,
 288    OPC_LHU      = 0x25 << 26,
 289    OPC_LWU      = 0x27 << 26,
 290    OPC_SB       = 0x28 << 26,
 291    OPC_SH       = 0x29 << 26,
 292    OPC_SW       = 0x2B << 26,
 293
 294    OPC_SPECIAL  = 0x00 << 26,
 295    OPC_SLL      = OPC_SPECIAL | 0x00,
 296    OPC_SRL      = OPC_SPECIAL | 0x02,
 297    OPC_ROTR     = OPC_SPECIAL | (0x01 << 21) | 0x02,
 298    OPC_SRA      = OPC_SPECIAL | 0x03,
 299    OPC_SLLV     = OPC_SPECIAL | 0x04,
 300    OPC_SRLV     = OPC_SPECIAL | 0x06,
 301    OPC_ROTRV    = OPC_SPECIAL | (0x01 <<  6) | 0x06,
 302    OPC_SRAV     = OPC_SPECIAL | 0x07,
 303    OPC_JR       = OPC_SPECIAL | 0x08,
 304    OPC_JALR     = OPC_SPECIAL | 0x09,
 305    OPC_MOVZ     = OPC_SPECIAL | 0x0A,
 306    OPC_MOVN     = OPC_SPECIAL | 0x0B,
 307    OPC_MFHI     = OPC_SPECIAL | 0x10,
 308    OPC_MFLO     = OPC_SPECIAL | 0x12,
 309    OPC_MULT     = OPC_SPECIAL | 0x18,
 310    OPC_MULTU    = OPC_SPECIAL | 0x19,
 311    OPC_DIV      = OPC_SPECIAL | 0x1A,
 312    OPC_DIVU     = OPC_SPECIAL | 0x1B,
 313    OPC_ADDU     = OPC_SPECIAL | 0x21,
 314    OPC_SUBU     = OPC_SPECIAL | 0x23,
 315    OPC_AND      = OPC_SPECIAL | 0x24,
 316    OPC_OR       = OPC_SPECIAL | 0x25,
 317    OPC_XOR      = OPC_SPECIAL | 0x26,
 318    OPC_NOR      = OPC_SPECIAL | 0x27,
 319    OPC_SLT      = OPC_SPECIAL | 0x2A,
 320    OPC_SLTU     = OPC_SPECIAL | 0x2B,
 321
 322    OPC_REGIMM   = 0x01 << 26,
 323    OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
 324    OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
 325
 326    OPC_SPECIAL2 = 0x1c << 26,
 327    OPC_MUL      = OPC_SPECIAL2 | 0x002,
 328
 329    OPC_SPECIAL3 = 0x1f << 26,
 330    OPC_INS      = OPC_SPECIAL3 | 0x004,
 331    OPC_WSBH     = OPC_SPECIAL3 | 0x0a0,
 332    OPC_SEB      = OPC_SPECIAL3 | 0x420,
 333    OPC_SEH      = OPC_SPECIAL3 | 0x620,
 334};
 335
 336/*
 337 * Type reg
 338 */
 339static inline void tcg_out_opc_reg(TCGContext *s, int opc,
 340                                   TCGReg rd, TCGReg rs, TCGReg rt)
 341{
 342    int32_t inst;
 343
 344    inst = opc;
 345    inst |= (rs & 0x1F) << 21;
 346    inst |= (rt & 0x1F) << 16;
 347    inst |= (rd & 0x1F) << 11;
 348    tcg_out32(s, inst);
 349}
 350
 351/*
 352 * Type immediate
 353 */
 354static inline void tcg_out_opc_imm(TCGContext *s, int opc,
 355                                   TCGReg rt, TCGReg rs, TCGArg imm)
 356{
 357    int32_t inst;
 358
 359    inst = opc;
 360    inst |= (rs & 0x1F) << 21;
 361    inst |= (rt & 0x1F) << 16;
 362    inst |= (imm & 0xffff);
 363    tcg_out32(s, inst);
 364}
 365
 366/*
 367 * Type branch
 368 */
 369static inline void tcg_out_opc_br(TCGContext *s, int opc,
 370                                  TCGReg rt, TCGReg rs)
 371{
 372    /* We pay attention here to not modify the branch target by reading
 373       the existing value and using it again. This ensure that caches and
 374       memory are kept coherent during retranslation. */
 375    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
 376
 377    tcg_out_opc_imm(s, opc, rt, rs, offset);
 378}
 379
 380/*
 381 * Type sa
 382 */
 383static inline void tcg_out_opc_sa(TCGContext *s, int opc,
 384                                  TCGReg rd, TCGReg rt, TCGArg sa)
 385{
 386    int32_t inst;
 387
 388    inst = opc;
 389    inst |= (rt & 0x1F) << 16;
 390    inst |= (rd & 0x1F) << 11;
 391    inst |= (sa & 0x1F) <<  6;
 392    tcg_out32(s, inst);
 393
 394}
 395
 396static inline void tcg_out_nop(TCGContext *s)
 397{
 398    tcg_out32(s, 0);
 399}
 400
 401static inline void tcg_out_mov(TCGContext *s, TCGType type,
 402                               TCGReg ret, TCGReg arg)
 403{
 404    /* Simple reg-reg move, optimising out the 'do nothing' case */
 405    if (ret != arg) {
 406        tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
 407    }
 408}
 409
 410static inline void tcg_out_movi(TCGContext *s, TCGType type,
 411                                TCGReg reg, tcg_target_long arg)
 412{
 413    if (arg == (int16_t)arg) {
 414        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
 415    } else if (arg == (uint16_t)arg) {
 416        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
 417    } else {
 418        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
 419        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
 420    }
 421}
 422
 423static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
 424{
 425#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 426    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 427#else
 428    /* ret and arg can't be register at */
 429    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
 430        tcg_abort();
 431    }
 432
 433    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 434    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
 435    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
 436    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 437#endif
 438}
 439
 440static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
 441{
 442#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 443    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 444    tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
 445#else
 446    /* ret and arg can't be register at */
 447    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
 448        tcg_abort();
 449    }
 450
 451    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 452    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 453    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 454    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 455#endif
 456}
 457
 458static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
 459{
 460#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 461    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 462    tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
 463#else
 464    /* ret and arg must be different and can't be register at */
 465    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
 466        tcg_abort();
 467    }
 468
 469    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 470
 471    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
 472    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 473
 474    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
 475    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
 476    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 477
 478    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 479    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
 480    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 481#endif
 482}
 483
 484static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
 485{
 486#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 487    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
 488#else
 489    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 490    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
 491#endif
 492}
 493
 494static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
 495{
 496#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 497    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
 498#else
 499    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
 500    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 501#endif
 502}
 503
 504static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
 505                                TCGReg arg1, TCGArg arg2)
 506{
 507    if (arg2 == (int16_t) arg2) {
 508        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
 509    } else {
 510        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
 511        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
 512        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
 513    }
 514}
 515
 516static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
 517                              TCGReg arg1, tcg_target_long arg2)
 518{
 519    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
 520}
 521
 522static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 523                              TCGReg arg1, tcg_target_long arg2)
 524{
 525    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
 526}
 527
 528static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
 529{
 530    if (val == (int16_t)val) {
 531        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
 532    } else {
 533        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
 534        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
 535    }
 536}
 537
 538/* Helper routines for marshalling helper function arguments into
 539 * the correct registers and stack.
 540 * arg_num is where we want to put this argument, and is updated to be ready
 541 * for the next call. arg is the argument itself. Note that arg_num 0..3 is
 542 * real registers, 4+ on stack.
 543 *
 544 * We provide routines for arguments which are: immediate, 32 bit
 545 * value in register, 16 and 8 bit values in register (which must be zero
 546 * extended before use) and 64 bit value in a lo:hi register pair.
 547 */
 548#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM)                               \
 549    static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM)             \
 550    {                                                                          \
 551    if (*arg_num < 4) {                                                        \
 552        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
 553    } else {                                                                   \
 554        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT);                          \
 555        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num));   \
 556    }                                                                          \
 557    (*arg_num)++;                                                              \
 558}
 559#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
 560    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
 561DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg)
 562#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
 563#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
 564    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
 565DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
 566#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
 567#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
 568    tcg_out_movi(s, TCG_TYPE_I32, A, arg);
 569DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
 570#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
 571
 572/* We don't use the macro for this one to avoid an unnecessary reg-reg
 573   move when storing to the stack. */
 574static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num,
 575                                           TCGReg arg)
 576{
 577    if (*arg_num < 4) {
 578        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg);
 579    } else {
 580        tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num));
 581    }
 582    (*arg_num)++;
 583}
 584
 585static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
 586                                           TCGReg arg_low, TCGReg arg_high)
 587{
 588    (*arg_num) = (*arg_num + 1) & ~1;
 589
 590#if defined(TCG_TARGET_WORDS_BIGENDIAN)
 591    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
 592    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
 593#else
 594    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
 595    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
 596#endif
 597}
 598
 599static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
 600                           TCGArg arg2, int label_index)
 601{
 602    TCGLabel *l = &s->labels[label_index];
 603
 604    switch (cond) {
 605    case TCG_COND_EQ:
 606        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
 607        break;
 608    case TCG_COND_NE:
 609        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
 610        break;
 611    case TCG_COND_LT:
 612        if (arg2 == 0) {
 613            tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
 614        } else {
 615            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
 616            tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 617        }
 618        break;
 619    case TCG_COND_LTU:
 620        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
 621        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 622        break;
 623    case TCG_COND_GE:
 624        if (arg2 == 0) {
 625            tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
 626        } else {
 627            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
 628            tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 629        }
 630        break;
 631    case TCG_COND_GEU:
 632        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
 633        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 634        break;
 635    case TCG_COND_LE:
 636        if (arg2 == 0) {
 637            tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
 638        } else {
 639            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
 640            tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 641        }
 642        break;
 643    case TCG_COND_LEU:
 644        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
 645        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 646        break;
 647    case TCG_COND_GT:
 648        if (arg2 == 0) {
 649            tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
 650        } else {
 651            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
 652            tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 653        }
 654        break;
 655    case TCG_COND_GTU:
 656        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
 657        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 658        break;
 659    default:
 660        tcg_abort();
 661        break;
 662    }
 663    if (l->has_value) {
 664        reloc_pc16(s->code_ptr - 4, l->u.value);
 665    } else {
 666        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
 667    }
 668    tcg_out_nop(s);
 669}
 670
 671/* XXX: we implement it at the target level to avoid having to
 672   handle cross basic blocks temporaries */
 673static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
 674                            TCGArg arg2, TCGArg arg3, TCGArg arg4,
 675                            int label_index)
 676{
 677    void *label_ptr;
 678
 679    switch(cond) {
 680    case TCG_COND_NE:
 681        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
 682        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
 683        return;
 684    case TCG_COND_EQ:
 685        break;
 686    case TCG_COND_LT:
 687    case TCG_COND_LE:
 688        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
 689        break;
 690    case TCG_COND_GT:
 691    case TCG_COND_GE:
 692        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
 693        break;
 694    case TCG_COND_LTU:
 695    case TCG_COND_LEU:
 696        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
 697        break;
 698    case TCG_COND_GTU:
 699    case TCG_COND_GEU:
 700        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
 701        break;
 702    default:
 703        tcg_abort();
 704    }
 705
 706    label_ptr = s->code_ptr;
 707    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
 708    tcg_out_nop(s);
 709
 710    switch(cond) {
 711    case TCG_COND_EQ:
 712        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
 713        break;
 714    case TCG_COND_LT:
 715    case TCG_COND_LTU:
 716        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
 717        break;
 718    case TCG_COND_LE:
 719    case TCG_COND_LEU:
 720        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
 721        break;
 722    case TCG_COND_GT:
 723    case TCG_COND_GTU:
 724        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
 725        break;
 726    case TCG_COND_GE:
 727    case TCG_COND_GEU:
 728        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
 729        break;
 730    default:
 731        tcg_abort();
 732    }
 733
 734    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
 735}
 736
 737static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
 738                            TCGArg c1, TCGArg c2, TCGArg v)
 739{
 740    switch (cond) {
 741    case TCG_COND_EQ:
 742        if (c1 == 0) {
 743            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c2);
 744        } else if (c2 == 0) {
 745            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c1);
 746        } else {
 747            tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
 748            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
 749        }
 750        break;
 751    case TCG_COND_NE:
 752        if (c1 == 0) {
 753            tcg_out_opc_reg(s, OPC_MOVN, ret, v, c2);
 754        } else if (c2 == 0) {
 755            tcg_out_opc_reg(s, OPC_MOVN, ret, v, c1);
 756        } else {
 757            tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
 758            tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
 759        }
 760        break;
 761    case TCG_COND_LT:
 762        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
 763        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
 764        break;
 765    case TCG_COND_LTU:
 766        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
 767        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
 768        break;
 769    case TCG_COND_GE:
 770        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
 771        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
 772        break;
 773    case TCG_COND_GEU:
 774        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
 775        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
 776        break;
 777    case TCG_COND_LE:
 778        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
 779        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
 780        break;
 781    case TCG_COND_LEU:
 782        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
 783        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
 784        break;
 785    case TCG_COND_GT:
 786        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
 787        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
 788        break;
 789    case TCG_COND_GTU:
 790        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
 791        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
 792        break;
 793    default:
 794        tcg_abort();
 795        break;
 796    }
 797}
 798
 799static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
 800                            TCGArg arg1, TCGArg arg2)
 801{
 802    switch (cond) {
 803    case TCG_COND_EQ:
 804        if (arg1 == 0) {
 805            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
 806        } else if (arg2 == 0) {
 807            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
 808        } else {
 809            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 810            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
 811        }
 812        break;
 813    case TCG_COND_NE:
 814        if (arg1 == 0) {
 815            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
 816        } else if (arg2 == 0) {
 817            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
 818        } else {
 819            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 820            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
 821        }
 822        break;
 823    case TCG_COND_LT:
 824        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
 825        break;
 826    case TCG_COND_LTU:
 827        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
 828        break;
 829    case TCG_COND_GE:
 830        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
 831        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 832        break;
 833    case TCG_COND_GEU:
 834        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
 835        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 836        break;
 837    case TCG_COND_LE:
 838        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
 839        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 840        break;
 841    case TCG_COND_LEU:
 842        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
 843        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 844        break;
 845    case TCG_COND_GT:
 846        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
 847        break;
 848    case TCG_COND_GTU:
 849        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
 850        break;
 851    default:
 852        tcg_abort();
 853        break;
 854    }
 855}
 856
 857/* XXX: we implement it at the target level to avoid having to
 858   handle cross basic blocks temporaries */
 859static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
 860                             TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
 861{
 862    switch (cond) {
 863    case TCG_COND_EQ:
 864        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
 865        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
 866        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
 867        return;
 868    case TCG_COND_NE:
 869        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
 870        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
 871        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
 872        return;
 873    case TCG_COND_LT:
 874    case TCG_COND_LE:
 875        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
 876        break;
 877    case TCG_COND_GT:
 878    case TCG_COND_GE:
 879        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
 880        break;
 881    case TCG_COND_LTU:
 882    case TCG_COND_LEU:
 883        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
 884        break;
 885    case TCG_COND_GTU:
 886    case TCG_COND_GEU:
 887        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
 888        break;
 889    default:
 890        tcg_abort();
 891        break;
 892    }
 893
 894    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
 895
 896    switch(cond) {
 897    case TCG_COND_LT:
 898    case TCG_COND_LTU:
 899        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
 900        break;
 901    case TCG_COND_LE:
 902    case TCG_COND_LEU:
 903        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
 904        break;
 905    case TCG_COND_GT:
 906    case TCG_COND_GTU:
 907        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
 908        break;
 909    case TCG_COND_GE:
 910    case TCG_COND_GEU:
 911        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
 912        break;
 913    default:
 914        tcg_abort();
 915    }
 916
 917    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
 918    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 919}
 920
 921#if defined(CONFIG_SOFTMMU)
 922
 923#include "exec/softmmu_defs.h"
 924
 925/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
 926   int mmu_idx) */
 927static const void * const qemu_ld_helpers[4] = {
 928    helper_ldb_mmu,
 929    helper_ldw_mmu,
 930    helper_ldl_mmu,
 931    helper_ldq_mmu,
 932};
 933
 934/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
 935   uintxx_t val, int mmu_idx) */
 936static const void * const qemu_st_helpers[4] = {
 937    helper_stb_mmu,
 938    helper_stw_mmu,
 939    helper_stl_mmu,
 940    helper_stq_mmu,
 941};
 942#endif
 943
 944static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
 945                            int opc)
 946{
 947    TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
 948#if defined(CONFIG_SOFTMMU)
 949    void *label1_ptr, *label2_ptr;
 950    int arg_num;
 951    int mem_index, s_bits;
 952    int addr_meml;
 953# if TARGET_LONG_BITS == 64
 954    uint8_t *label3_ptr;
 955    TCGReg addr_regh;
 956    int addr_memh;
 957# endif
 958#endif
 959    data_regl = *args++;
 960    if (opc == 3)
 961        data_regh = *args++;
 962    else
 963        data_regh = 0;
 964    addr_regl = *args++;
 965#if defined(CONFIG_SOFTMMU)
 966# if TARGET_LONG_BITS == 64
 967    addr_regh = *args++;
 968#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
 969    addr_memh = 0;
 970    addr_meml = 4;
 971#  else
 972    addr_memh = 4;
 973    addr_meml = 0;
 974#  endif
 975# else
 976    addr_meml = 0;
 977# endif
 978    mem_index = *args;
 979    s_bits = opc & 3;
 980#endif
 981
 982    if (opc == 3) {
 983#if defined(TCG_TARGET_WORDS_BIGENDIAN)
 984        data_reg1 = data_regh;
 985        data_reg2 = data_regl;
 986#else
 987        data_reg1 = data_regl;
 988        data_reg2 = data_regh;
 989#endif
 990    } else {
 991        data_reg1 = data_regl;
 992        data_reg2 = 0;
 993    }
 994#if defined(CONFIG_SOFTMMU)
 995    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 996    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
 997    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
 998    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 999                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
1000    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1001    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1002
1003# if TARGET_LONG_BITS == 64
1004    label3_ptr = s->code_ptr;
1005    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1006    tcg_out_nop(s);
1007
1008    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1009                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
1010
1011    label1_ptr = s->code_ptr;
1012    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1013    tcg_out_nop(s);
1014
1015    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1016# else
1017    label1_ptr = s->code_ptr;
1018    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1019    tcg_out_nop(s);
1020# endif
1021
1022    /* slow path */
1023    arg_num = 0;
1024    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1025# if TARGET_LONG_BITS == 64
1026    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1027# else
1028    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1029# endif
1030    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1031    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
1032    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1033    tcg_out_nop(s);
1034
1035    switch(opc) {
1036    case 0:
1037        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
1038        break;
1039    case 0 | 4:
1040        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
1041        break;
1042    case 1:
1043        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
1044        break;
1045    case 1 | 4:
1046        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
1047        break;
1048    case 2:
1049        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1050        break;
1051    case 3:
1052        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
1053        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1054        break;
1055    default:
1056        tcg_abort();
1057    }
1058
1059    label2_ptr = s->code_ptr;
1060    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1061    tcg_out_nop(s);
1062
1063    /* label1: fast path */
1064    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1065
1066    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1067                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1068    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
1069#else
1070    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1071        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
1072    } else {
1073        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
1074        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
1075    }
1076#endif
1077
1078    switch(opc) {
1079    case 0:
1080        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
1081        break;
1082    case 0 | 4:
1083        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
1084        break;
1085    case 1:
1086        if (TCG_NEED_BSWAP) {
1087            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1088            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
1089        } else {
1090            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
1091        }
1092        break;
1093    case 1 | 4:
1094        if (TCG_NEED_BSWAP) {
1095            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1096            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
1097        } else {
1098            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
1099        }
1100        break;
1101    case 2:
1102        if (TCG_NEED_BSWAP) {
1103            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1104            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1105        } else {
1106            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1107        }
1108        break;
1109    case 3:
1110        if (TCG_NEED_BSWAP) {
1111            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1112            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1113            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1114            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
1115        } else {
1116            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1117            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1118        }
1119        break;
1120    default:
1121        tcg_abort();
1122    }
1123
1124#if defined(CONFIG_SOFTMMU)
1125    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1126#endif
1127}
1128
1129static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1130                            int opc)
1131{
1132    TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
1133#if defined(CONFIG_SOFTMMU)
1134    uint8_t *label1_ptr, *label2_ptr;
1135    int arg_num;
1136    int mem_index, s_bits;
1137    int addr_meml;
1138#endif
1139#if TARGET_LONG_BITS == 64
1140# if defined(CONFIG_SOFTMMU)
1141    uint8_t *label3_ptr;
1142    TCGReg addr_regh;
1143    int addr_memh;
1144# endif
1145#endif
1146    data_regl = *args++;
1147    if (opc == 3) {
1148        data_regh = *args++;
1149    } else {
1150        data_regh = 0;
1151    }
1152    addr_regl = *args++;
1153#if defined(CONFIG_SOFTMMU)
1154# if TARGET_LONG_BITS == 64
1155    addr_regh = *args++;
1156#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
1157    addr_memh = 0;
1158    addr_meml = 4;
1159#  else
1160    addr_memh = 4;
1161    addr_meml = 0;
1162#  endif
1163# else
1164    addr_meml = 0;
1165# endif
1166    mem_index = *args;
1167    s_bits = opc;
1168#endif
1169
1170    if (opc == 3) {
1171#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1172        data_reg1 = data_regh;
1173        data_reg2 = data_regl;
1174#else
1175        data_reg1 = data_regl;
1176        data_reg2 = data_regh;
1177#endif
1178    } else {
1179        data_reg1 = data_regl;
1180        data_reg2 = 0;
1181    }
1182
1183#if defined(CONFIG_SOFTMMU)
1184    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1185    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1186    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1187    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1188                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1189    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1190    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1191
1192# if TARGET_LONG_BITS == 64
1193    label3_ptr = s->code_ptr;
1194    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1195    tcg_out_nop(s);
1196
1197    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1198                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1199
1200    label1_ptr = s->code_ptr;
1201    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1202    tcg_out_nop(s);
1203
1204    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1205# else
1206    label1_ptr = s->code_ptr;
1207    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1208    tcg_out_nop(s);
1209# endif
1210
1211    /* slow path */
1212    arg_num = 0;
1213    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1214# if TARGET_LONG_BITS == 64
1215    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1216# else
1217    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1218# endif
1219    switch(opc) {
1220    case 0:
1221        tcg_out_call_iarg_reg8(s, &arg_num, data_regl);
1222        break;
1223    case 1:
1224        tcg_out_call_iarg_reg16(s, &arg_num, data_regl);
1225        break;
1226    case 2:
1227        tcg_out_call_iarg_reg32(s, &arg_num, data_regl);
1228        break;
1229    case 3:
1230        tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh);
1231        break;
1232    default:
1233        tcg_abort();
1234    }
1235    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1236    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1237    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1238    tcg_out_nop(s);
1239
1240    label2_ptr = s->code_ptr;
1241    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1242    tcg_out_nop(s);
1243
1244    /* label1: fast path */
1245    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1246
1247    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1248                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1249    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1250#else
1251    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1252        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1253    } else {
1254        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1255        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1256    }
1257
1258#endif
1259
1260    switch(opc) {
1261    case 0:
1262        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1263        break;
1264    case 1:
1265        if (TCG_NEED_BSWAP) {
1266            tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_T0, data_reg1, 0xffff);
1267            tcg_out_bswap16(s, TCG_REG_T0, TCG_REG_T0);
1268            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1269        } else {
1270            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1271        }
1272        break;
1273    case 2:
1274        if (TCG_NEED_BSWAP) {
1275            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1276            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1277        } else {
1278            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1279        }
1280        break;
1281    case 3:
1282        if (TCG_NEED_BSWAP) {
1283            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1284            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1285            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1286            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1287        } else {
1288            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1289            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1290        }
1291        break;
1292    default:
1293        tcg_abort();
1294    }
1295
1296#if defined(CONFIG_SOFTMMU)
1297    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1298#endif
1299}
1300
1301static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1302                              const TCGArg *args, const int *const_args)
1303{
1304    switch(opc) {
1305    case INDEX_op_exit_tb:
1306        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1307        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1308        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1309        tcg_out_nop(s);
1310        break;
1311    case INDEX_op_goto_tb:
1312        if (s->tb_jmp_offset) {
1313            /* direct jump method */
1314            tcg_abort();
1315        } else {
1316            /* indirect jump method */
1317            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1318            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1319            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1320        }
1321        tcg_out_nop(s);
1322        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1323        break;
1324    case INDEX_op_call:
1325        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1326        tcg_out_nop(s);
1327        break;
1328    case INDEX_op_br:
1329        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1330        break;
1331
1332    case INDEX_op_mov_i32:
1333        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1334        break;
1335    case INDEX_op_movi_i32:
1336        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1337        break;
1338
1339    case INDEX_op_ld8u_i32:
1340        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1341        break;
1342    case INDEX_op_ld8s_i32:
1343        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1344        break;
1345    case INDEX_op_ld16u_i32:
1346        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1347        break;
1348    case INDEX_op_ld16s_i32:
1349        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1350        break;
1351    case INDEX_op_ld_i32:
1352        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1353        break;
1354    case INDEX_op_st8_i32:
1355        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1356        break;
1357    case INDEX_op_st16_i32:
1358        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1359        break;
1360    case INDEX_op_st_i32:
1361        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1362        break;
1363
1364    case INDEX_op_add_i32:
1365        if (const_args[2]) {
1366            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1367        } else {
1368            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1369        }
1370        break;
1371    case INDEX_op_add2_i32:
1372        if (const_args[4]) {
1373            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1374        } else {
1375            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1376        }
1377        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1378        if (const_args[5]) {
1379            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1380        } else {
1381             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1382        }
1383        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1384        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1385        break;
1386    case INDEX_op_sub_i32:
1387        if (const_args[2]) {
1388            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1389        } else {
1390            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1391        }
1392        break;
1393    case INDEX_op_sub2_i32:
1394        if (const_args[4]) {
1395            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1396        } else {
1397            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1398        }
1399        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1400        if (const_args[5]) {
1401            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1402        } else {
1403             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1404        }
1405        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1406        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1407        break;
1408    case INDEX_op_mul_i32:
1409#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
1410        tcg_out_opc_reg(s, OPC_MUL, args[0], args[1], args[2]);
1411#else
1412        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1413        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1414#endif
1415        break;
1416    case INDEX_op_mulu2_i32:
1417        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1418        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1419        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1420        break;
1421    case INDEX_op_div_i32:
1422        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1423        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1424        break;
1425    case INDEX_op_divu_i32:
1426        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1427        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1428        break;
1429    case INDEX_op_rem_i32:
1430        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1431        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1432        break;
1433    case INDEX_op_remu_i32:
1434        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1435        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1436        break;
1437
1438    case INDEX_op_and_i32:
1439        if (const_args[2]) {
1440            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1441        } else {
1442            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1443        }
1444        break;
1445    case INDEX_op_or_i32:
1446        if (const_args[2]) {
1447            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1448        } else {
1449            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1450        }
1451        break;
1452    case INDEX_op_nor_i32:
1453        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1454        break;
1455    case INDEX_op_not_i32:
1456        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1457        break;
1458    case INDEX_op_xor_i32:
1459        if (const_args[2]) {
1460            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1461        } else {
1462            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1463        }
1464        break;
1465
1466    case INDEX_op_sar_i32:
1467        if (const_args[2]) {
1468            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1469        } else {
1470            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1471        }
1472        break;
1473    case INDEX_op_shl_i32:
1474        if (const_args[2]) {
1475            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1476        } else {
1477            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1478        }
1479        break;
1480    case INDEX_op_shr_i32:
1481        if (const_args[2]) {
1482            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1483        } else {
1484            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1485        }
1486        break;
1487    case INDEX_op_rotl_i32:
1488        if (const_args[2]) {
1489            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
1490        } else {
1491            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
1492            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
1493            tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
1494        }
1495        break;
1496    case INDEX_op_rotr_i32:
1497        if (const_args[2]) {
1498            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
1499        } else {
1500            tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
1501        }
1502        break;
1503
1504    /* The bswap routines do not work on non-R2 CPU. In that case
1505       we let TCG generating the corresponding code. */
1506    case INDEX_op_bswap16_i32:
1507        tcg_out_bswap16(s, args[0], args[1]);
1508        break;
1509    case INDEX_op_bswap32_i32:
1510        tcg_out_bswap32(s, args[0], args[1]);
1511        break;
1512
1513    case INDEX_op_ext8s_i32:
1514        tcg_out_ext8s(s, args[0], args[1]);
1515        break;
1516    case INDEX_op_ext16s_i32:
1517        tcg_out_ext16s(s, args[0], args[1]);
1518        break;
1519
1520    case INDEX_op_deposit_i32:
1521        tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
1522                        ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
1523        break;
1524
1525    case INDEX_op_brcond_i32:
1526        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1527        break;
1528    case INDEX_op_brcond2_i32:
1529        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1530        break;
1531
1532    case INDEX_op_movcond_i32:
1533        tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
1534        break;
1535
1536    case INDEX_op_setcond_i32:
1537        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1538        break;
1539    case INDEX_op_setcond2_i32:
1540        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1541        break;
1542
1543    case INDEX_op_qemu_ld8u:
1544        tcg_out_qemu_ld(s, args, 0);
1545        break;
1546    case INDEX_op_qemu_ld8s:
1547        tcg_out_qemu_ld(s, args, 0 | 4);
1548        break;
1549    case INDEX_op_qemu_ld16u:
1550        tcg_out_qemu_ld(s, args, 1);
1551        break;
1552    case INDEX_op_qemu_ld16s:
1553        tcg_out_qemu_ld(s, args, 1 | 4);
1554        break;
1555    case INDEX_op_qemu_ld32:
1556        tcg_out_qemu_ld(s, args, 2);
1557        break;
1558    case INDEX_op_qemu_ld64:
1559        tcg_out_qemu_ld(s, args, 3);
1560        break;
1561    case INDEX_op_qemu_st8:
1562        tcg_out_qemu_st(s, args, 0);
1563        break;
1564    case INDEX_op_qemu_st16:
1565        tcg_out_qemu_st(s, args, 1);
1566        break;
1567    case INDEX_op_qemu_st32:
1568        tcg_out_qemu_st(s, args, 2);
1569        break;
1570    case INDEX_op_qemu_st64:
1571        tcg_out_qemu_st(s, args, 3);
1572        break;
1573
1574    default:
1575        tcg_abort();
1576    }
1577}
1578
1579static const TCGTargetOpDef mips_op_defs[] = {
1580    { INDEX_op_exit_tb, { } },
1581    { INDEX_op_goto_tb, { } },
1582    { INDEX_op_call, { "C" } },
1583    { INDEX_op_br, { } },
1584
1585    { INDEX_op_mov_i32, { "r", "r" } },
1586    { INDEX_op_movi_i32, { "r" } },
1587    { INDEX_op_ld8u_i32, { "r", "r" } },
1588    { INDEX_op_ld8s_i32, { "r", "r" } },
1589    { INDEX_op_ld16u_i32, { "r", "r" } },
1590    { INDEX_op_ld16s_i32, { "r", "r" } },
1591    { INDEX_op_ld_i32, { "r", "r" } },
1592    { INDEX_op_st8_i32, { "rZ", "r" } },
1593    { INDEX_op_st16_i32, { "rZ", "r" } },
1594    { INDEX_op_st_i32, { "rZ", "r" } },
1595
1596    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1597    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1598    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1599    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1600    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1601    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1602    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1603    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1604
1605    { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1606    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1607    { INDEX_op_not_i32, { "r", "rZ" } },
1608    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1609    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1610
1611    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1612    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1613    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1614    { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1615    { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1616
1617    { INDEX_op_bswap16_i32, { "r", "r" } },
1618    { INDEX_op_bswap32_i32, { "r", "r" } },
1619
1620    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1621    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1622
1623    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1624
1625    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1626    { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1627    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1628    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1629
1630    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1631    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1632    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1633
1634#if TARGET_LONG_BITS == 32
1635    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1636    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1637    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1638    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1639    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1640    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1641
1642    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1643    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1644    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1645    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1646#else
1647    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1648    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1649    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1650    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1651    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1652    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1653
1654    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1655    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1656    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1657    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1658#endif
1659    { -1 },
1660};
1661
1662static int tcg_target_callee_save_regs[] = {
1663    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1664    TCG_REG_S1,
1665    TCG_REG_S2,
1666    TCG_REG_S3,
1667    TCG_REG_S4,
1668    TCG_REG_S5,
1669    TCG_REG_S6,
1670    TCG_REG_S7,
1671    TCG_REG_FP,
1672    TCG_REG_RA,       /* should be last for ABI compliance */
1673};
1674
1675/* Generate global QEMU prologue and epilogue code */
1676static void tcg_target_qemu_prologue(TCGContext *s)
1677{
1678    int i, frame_size;
1679
1680    /* reserve some stack space, also for TCG temps. */
1681    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1682                 + TCG_STATIC_CALL_ARGS_SIZE
1683                 + CPU_TEMP_BUF_NLONGS * sizeof(long);
1684    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1685                 ~(TCG_TARGET_STACK_ALIGN - 1);
1686    tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1687                  + TCG_STATIC_CALL_ARGS_SIZE,
1688                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1689
1690    /* TB prologue */
1691    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1692    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1693        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1694                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1695    }
1696
1697    /* Call generated code */
1698    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1699    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1700    tb_ret_addr = s->code_ptr;
1701
1702    /* TB epilogue */
1703    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1704        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1705                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1706    }
1707
1708    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1709    tcg_out_addi(s, TCG_REG_SP, frame_size);
1710}
1711
1712static void tcg_target_init(TCGContext *s)
1713{
1714    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1715    tcg_regset_set(tcg_target_call_clobber_regs,
1716                   (1 << TCG_REG_V0) |
1717                   (1 << TCG_REG_V1) |
1718                   (1 << TCG_REG_A0) |
1719                   (1 << TCG_REG_A1) |
1720                   (1 << TCG_REG_A2) |
1721                   (1 << TCG_REG_A3) |
1722                   (1 << TCG_REG_T1) |
1723                   (1 << TCG_REG_T2) |
1724                   (1 << TCG_REG_T3) |
1725                   (1 << TCG_REG_T4) |
1726                   (1 << TCG_REG_T5) |
1727                   (1 << TCG_REG_T6) |
1728                   (1 << TCG_REG_T7) |
1729                   (1 << TCG_REG_T8) |
1730                   (1 << TCG_REG_T9));
1731
1732    tcg_regset_clear(s->reserved_regs);
1733    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1734    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1735    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1736    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1737    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1738    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1739    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1740    tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
1741
1742    tcg_add_target_add_op_defs(mips_op_defs);
1743}
1744