Annotation of qemu/tcg/mips/tcg-target.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * Tiny Code Generator for QEMU
                      3:  *
                      4:  * Copyright (c) 2008-2009 Arnaud Patard <[email protected]>
                      5:  * Copyright (c) 2009 Aurelien Jarno <[email protected]>
                      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
                     34: static 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 */
                     71: static 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: 
                     97: static 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: 
                    104: static const int tcg_target_call_oarg_regs[2] = {
                    105:     TCG_REG_V0,
                    106:     TCG_REG_V1
                    107: };
                    108: 
                    109: static uint8_t *tb_ret_addr;
                    110: 
                    111: static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
                    112: {
                    113:     return target & 0xffff;
                    114: }
                    115: 
                    116: static 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: 
                    122: static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
                    123: {
                    124:     return (target >> 16) & 0xffff;
                    125: }
                    126: 
                    127: static 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: 
                    133: static 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: 
                    145: static 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: 
                    151: static 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: 
                    160: static 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: 
                    166: static 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 */
                    189: static inline int tcg_target_get_call_iarg_regs_count(int flags)
                    190: {
                    191:     return 4;
                    192: }
                    193: 
                    194: /* parse target specific constraints */
                    195: static 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);
1.1.1.4 ! root      226: #if defined(CONFIG_SOFTMMU)
1.1       root      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 */
                    254: static 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 */
                    272: enum {
                    273:     OPC_BEQ      = 0x04 << 26,
                    274:     OPC_BNE      = 0x05 << 26,
                    275:     OPC_ADDIU    = 0x09 << 26,
1.1.1.4 ! root      276:     OPC_SLTI     = 0x0A << 26,
        !           277:     OPC_SLTIU    = 0x0B << 26,
1.1       root      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,
1.1.1.4 ! root      291: 
        !           292:     OPC_SPECIAL  = 0x00 << 26,
1.1       root      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,
1.1.1.4 ! root      315: 
        !           316:     OPC_SPECIAL3 = 0x1f << 26,
        !           317:     OPC_SEB      = OPC_SPECIAL3 | 0x420,
        !           318:     OPC_SEH      = OPC_SPECIAL3 | 0x620,
1.1       root      319: };
                    320: 
                    321: /*
                    322:  * Type reg
                    323:  */
                    324: static 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:  */
                    338: static 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: /*
1.1.1.3   root      350:  * Type branch
                    351:  */
                    352: static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
                    353: {
                    354:     /* We need to keep the offset unchanged for retranslation */
                    355:     uint16_t offset = (uint16_t)(*(uint32_t *) &s->code_ptr);
                    356: 
                    357:     tcg_out_opc_imm(s, opc, rt, rs, offset);
                    358: }
                    359: 
                    360: /*
1.1       root      361:  * Type sa
                    362:  */
                    363: static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
                    364: {
                    365:     int32_t inst;
                    366: 
                    367:     inst = opc;
                    368:     inst |= (rt & 0x1F) << 16;
                    369:     inst |= (rd & 0x1F) << 11;
                    370:     inst |= (sa & 0x1F) <<  6;
                    371:     tcg_out32(s, inst);
                    372: 
                    373: }
                    374: 
                    375: static inline void tcg_out_nop(TCGContext *s)
                    376: {
                    377:     tcg_out32(s, 0);
                    378: }
                    379: 
1.1.1.4 ! root      380: static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
1.1       root      381: {
                    382:     tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
                    383: }
                    384: 
                    385: static inline void tcg_out_movi(TCGContext *s, TCGType type,
                    386:                                 int reg, int32_t arg)
                    387: {
                    388:     if (arg == (int16_t)arg) {
                    389:         tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
                    390:     } else if (arg == (uint16_t)arg) {
                    391:         tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
                    392:     } else {
                    393:         tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
                    394:         tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
                    395:     }
                    396: }
                    397: 
                    398: static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
                    399: {
                    400:     /* ret and arg can't be register at */
                    401:     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
                    402:         tcg_abort();
                    403:     }
                    404: 
                    405:     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
                    406:     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
                    407: 
                    408:     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
                    409:     tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
                    410:     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
                    411: }
                    412: 
                    413: static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
                    414: {
                    415:     /* ret and arg can't be register at */
                    416:     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
                    417:         tcg_abort();
                    418:     }
                    419: 
                    420:     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
                    421:     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
                    422: 
                    423:     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
                    424:     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
                    425:     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
                    426: }
                    427: 
                    428: static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
                    429: {
                    430:     /* ret and arg must be different and can't be register at */
                    431:     if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
                    432:         tcg_abort();
                    433:     }
                    434: 
                    435:     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
                    436: 
                    437:     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
                    438:     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
                    439: 
                    440:     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
                    441:     tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
                    442:     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
                    443: 
                    444:     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
                    445:     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
                    446:     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
                    447: }
                    448: 
1.1.1.4 ! root      449: static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
        !           450: {
        !           451: #ifdef _MIPS_ARCH_MIPS32R2
        !           452:     tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
        !           453: #else
        !           454:     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
        !           455:     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
        !           456: #endif
        !           457: }
        !           458: 
        !           459: static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
        !           460: {
        !           461: #ifdef _MIPS_ARCH_MIPS32R2
        !           462:     tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
        !           463: #else
        !           464:     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
        !           465:     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
        !           466: #endif
        !           467: }
        !           468: 
1.1       root      469: static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
                    470:                               int arg1, tcg_target_long arg2)
                    471: {
                    472:     if (arg2 == (int16_t) arg2) {
                    473:         tcg_out_opc_imm(s, opc, arg, arg1, arg2);
                    474:     } else {
                    475:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
                    476:         tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
                    477:         tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
                    478:     }
                    479: }
                    480: 
                    481: static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
                    482:                               int arg1, tcg_target_long arg2)
                    483: {
                    484:     tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
                    485: }
                    486: 
                    487: static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
                    488:                               int arg1, tcg_target_long arg2)
                    489: {
                    490:     tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
                    491: }
                    492: 
                    493: static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
                    494: {
                    495:     if (val == (int16_t)val) {
                    496:         tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
                    497:     } else {
                    498:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
                    499:         tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
                    500:     }
                    501: }
                    502: 
1.1.1.4 ! root      503: static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
1.1       root      504:                            int arg2, int label_index)
                    505: {
                    506:     TCGLabel *l = &s->labels[label_index];
                    507: 
                    508:     switch (cond) {
                    509:     case TCG_COND_EQ:
1.1.1.3   root      510:         tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
1.1       root      511:         break;
                    512:     case TCG_COND_NE:
1.1.1.3   root      513:         tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
1.1       root      514:         break;
                    515:     case TCG_COND_LT:
                    516:         tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
1.1.1.3   root      517:         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      518:         break;
                    519:     case TCG_COND_LTU:
                    520:         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
1.1.1.3   root      521:         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      522:         break;
                    523:     case TCG_COND_GE:
                    524:         tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
1.1.1.3   root      525:         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      526:         break;
                    527:     case TCG_COND_GEU:
                    528:         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
1.1.1.3   root      529:         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      530:         break;
                    531:     case TCG_COND_LE:
                    532:         tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
1.1.1.3   root      533:         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      534:         break;
                    535:     case TCG_COND_LEU:
                    536:         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
1.1.1.3   root      537:         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      538:         break;
                    539:     case TCG_COND_GT:
                    540:         tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
1.1.1.3   root      541:         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      542:         break;
                    543:     case TCG_COND_GTU:
                    544:         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
1.1.1.3   root      545:         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
1.1       root      546:         break;
                    547:     default:
                    548:         tcg_abort();
                    549:         break;
                    550:     }
                    551:     if (l->has_value) {
                    552:         reloc_pc16(s->code_ptr - 4, l->u.value);
                    553:     } else {
                    554:         tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
                    555:     }
                    556:     tcg_out_nop(s);
                    557: }
                    558: 
                    559: /* XXX: we implement it at the target level to avoid having to
                    560:    handle cross basic blocks temporaries */
1.1.1.4 ! root      561: static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
1.1       root      562:                             int arg2, int arg3, int arg4, int label_index)
                    563: {
                    564:     void *label_ptr;
                    565: 
                    566:     switch(cond) {
                    567:     case TCG_COND_NE:
                    568:         tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
                    569:         tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
                    570:         return;
                    571:     case TCG_COND_EQ:
                    572:         break;
                    573:     case TCG_COND_LT:
                    574:     case TCG_COND_LE:
                    575:         tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
                    576:         break;
                    577:     case TCG_COND_GT:
                    578:     case TCG_COND_GE:
                    579:         tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
                    580:         break;
                    581:     case TCG_COND_LTU:
                    582:     case TCG_COND_LEU:
                    583:         tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
                    584:         break;
                    585:     case TCG_COND_GTU:
                    586:     case TCG_COND_GEU:
                    587:         tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
                    588:         break;
                    589:     default:
                    590:         tcg_abort();
                    591:     }
                    592: 
                    593:     label_ptr = s->code_ptr;
1.1.1.3   root      594:     tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
1.1       root      595:     tcg_out_nop(s);
                    596: 
                    597:     switch(cond) {
                    598:     case TCG_COND_EQ:
                    599:         tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
                    600:         break;
                    601:     case TCG_COND_LT:
                    602:     case TCG_COND_LTU:
                    603:         tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
                    604:         break;
                    605:     case TCG_COND_LE:
                    606:     case TCG_COND_LEU:
                    607:         tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
                    608:         break;
                    609:     case TCG_COND_GT:
                    610:     case TCG_COND_GTU:
                    611:         tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
                    612:         break;
                    613:     case TCG_COND_GE:
                    614:     case TCG_COND_GEU:
                    615:         tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
                    616:         break;
                    617:     default:
                    618:         tcg_abort();
                    619:     }
                    620: 
                    621:     reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
                    622: }
                    623: 
1.1.1.4 ! root      624: static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
        !           625:                             int arg1, int arg2)
        !           626: {
        !           627:     switch (cond) {
        !           628:     case TCG_COND_EQ:
        !           629:         if (arg1 == 0) {
        !           630:             tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
        !           631:         } else if (arg2 == 0) {
        !           632:             tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
        !           633:         } else {
        !           634:             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
        !           635:             tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
        !           636:         }
        !           637:         break;
        !           638:     case TCG_COND_NE:
        !           639:         if (arg1 == 0) {
        !           640:             tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
        !           641:         } else if (arg2 == 0) {
        !           642:             tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
        !           643:         } else {
        !           644:             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
        !           645:             tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
        !           646:         }
        !           647:         break;
        !           648:     case TCG_COND_LT:
        !           649:         tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
        !           650:         break;
        !           651:     case TCG_COND_LTU:
        !           652:         tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
        !           653:         break;
        !           654:     case TCG_COND_GE:
        !           655:         tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
        !           656:         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
        !           657:         break;
        !           658:     case TCG_COND_GEU:
        !           659:         tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
        !           660:         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
        !           661:         break;
        !           662:     case TCG_COND_LE:
        !           663:         tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
        !           664:         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
        !           665:         break;
        !           666:     case TCG_COND_LEU:
        !           667:         tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
        !           668:         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
        !           669:         break;
        !           670:     case TCG_COND_GT:
        !           671:         tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
        !           672:         break;
        !           673:     case TCG_COND_GTU:
        !           674:         tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
        !           675:         break;
        !           676:     default:
        !           677:         tcg_abort();
        !           678:         break;
        !           679:     }
        !           680: }
        !           681: 
        !           682: /* XXX: we implement it at the target level to avoid having to
        !           683:    handle cross basic blocks temporaries */
        !           684: static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
        !           685:                              int arg1, int arg2, int arg3, int arg4)
        !           686: {
        !           687:     switch (cond) {
        !           688:     case TCG_COND_EQ:
        !           689:         tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
        !           690:         tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
        !           691:         tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
        !           692:         return;
        !           693:     case TCG_COND_NE:
        !           694:         tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
        !           695:         tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
        !           696:         tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
        !           697:         return;
        !           698:     case TCG_COND_LT:
        !           699:     case TCG_COND_LE:
        !           700:         tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
        !           701:         break;
        !           702:     case TCG_COND_GT:
        !           703:     case TCG_COND_GE:
        !           704:         tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
        !           705:         break;
        !           706:     case TCG_COND_LTU:
        !           707:     case TCG_COND_LEU:
        !           708:         tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
        !           709:         break;
        !           710:     case TCG_COND_GTU:
        !           711:     case TCG_COND_GEU:
        !           712:         tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
        !           713:         break;
        !           714:     default:
        !           715:         tcg_abort();
        !           716:         break;
        !           717:     }
        !           718: 
        !           719:     tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
        !           720: 
        !           721:     switch(cond) {
        !           722:     case TCG_COND_LT:
        !           723:     case TCG_COND_LTU:
        !           724:         tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
        !           725:         break;
        !           726:     case TCG_COND_LE:
        !           727:     case TCG_COND_LEU:
        !           728:         tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
        !           729:         break;
        !           730:     case TCG_COND_GT:
        !           731:     case TCG_COND_GTU:
        !           732:         tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
        !           733:         break;
        !           734:     case TCG_COND_GE:
        !           735:     case TCG_COND_GEU:
        !           736:         tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
        !           737:         break;
        !           738:     default:
        !           739:         tcg_abort();
        !           740:     }
        !           741: 
        !           742:     tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
        !           743:     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
        !           744: }
        !           745: 
1.1       root      746: #if defined(CONFIG_SOFTMMU)
                    747: 
                    748: #include "../../softmmu_defs.h"
                    749: 
                    750: static void *qemu_ld_helpers[4] = {
                    751:     __ldb_mmu,
                    752:     __ldw_mmu,
                    753:     __ldl_mmu,
                    754:     __ldq_mmu,
                    755: };
                    756: 
                    757: static void *qemu_st_helpers[4] = {
                    758:     __stb_mmu,
                    759:     __stw_mmu,
                    760:     __stl_mmu,
                    761:     __stq_mmu,
                    762: };
                    763: #endif
                    764: 
                    765: static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
                    766:                             int opc)
                    767: {
                    768:     int addr_regl, addr_reg1, addr_meml;
                    769:     int data_regl, data_regh, data_reg1, data_reg2;
                    770:     int mem_index, s_bits;
                    771: #if defined(CONFIG_SOFTMMU)
                    772:     void *label1_ptr, *label2_ptr;
                    773:     int sp_args;
                    774: #endif
                    775: #if TARGET_LONG_BITS == 64
                    776: # if defined(CONFIG_SOFTMMU)
                    777:     uint8_t *label3_ptr;
                    778: # endif
                    779:     int addr_regh, addr_reg2, addr_memh;
                    780: #endif
                    781:     data_regl = *args++;
                    782:     if (opc == 3)
                    783:         data_regh = *args++;
                    784:     else
                    785:         data_regh = 0;
                    786:     addr_regl = *args++;
                    787: #if TARGET_LONG_BITS == 64
                    788:     addr_regh = *args++;
                    789: #endif
                    790:     mem_index = *args;
                    791:     s_bits = opc & 3;
                    792: 
                    793:     if (opc == 3) {
                    794: #if defined(TCG_TARGET_WORDS_BIGENDIAN)
                    795:         data_reg1 = data_regh;
                    796:         data_reg2 = data_regl;
                    797: #else
                    798:         data_reg1 = data_regl;
                    799:         data_reg2 = data_regh;
                    800: #endif
                    801:     } else {
                    802:         data_reg1 = data_regl;
                    803:         data_reg2 = 0;
                    804:     }
                    805: #if TARGET_LONG_BITS == 64
                    806: # if defined(TCG_TARGET_WORDS_BIGENDIAN)
                    807:     addr_reg1 = addr_regh;
                    808:     addr_reg2 = addr_regl;
                    809:     addr_memh = 0;
                    810:     addr_meml = 4;
                    811: # else
                    812:     addr_reg1 = addr_regl;
                    813:     addr_reg2 = addr_regh;
                    814:     addr_memh = 4;
                    815:     addr_meml = 0;
                    816: # endif
                    817: #else
                    818:     addr_reg1 = addr_regl;
                    819:     addr_meml = 0;
                    820: #endif
                    821: 
                    822: #if defined(CONFIG_SOFTMMU)
                    823:     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
                    824:     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
                    825:     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
                    826:     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
                    827:                     offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml);
                    828:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
                    829:     tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
                    830: 
                    831: # if TARGET_LONG_BITS == 64
                    832:     label3_ptr = s->code_ptr;
1.1.1.3   root      833:     tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1.1       root      834:     tcg_out_nop(s);
                    835: 
                    836:     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
                    837:                     offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);
                    838: 
                    839:     label1_ptr = s->code_ptr;
1.1.1.3   root      840:     tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1.1       root      841:     tcg_out_nop(s);
                    842: 
                    843:     reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
                    844: # else
                    845:     label1_ptr = s->code_ptr;
1.1.1.3   root      846:     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1.1       root      847:     tcg_out_nop(s);
                    848: # endif
                    849: 
                    850:     /* slow path */
                    851:     sp_args = TCG_REG_A0;
1.1.1.4 ! root      852:     tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1.1       root      853: # if TARGET_LONG_BITS == 64
1.1.1.4 ! root      854:     tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1.1       root      855: # endif
                    856:     tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
                    857:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
                    858:     tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
                    859:     tcg_out_nop(s);
                    860: 
                    861:     switch(opc) {
                    862:     case 0:
                    863:         tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
                    864:         break;
                    865:     case 0 | 4:
1.1.1.4 ! root      866:         tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
1.1       root      867:         break;
                    868:     case 1:
                    869:         tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
                    870:         break;
                    871:     case 1 | 4:
1.1.1.4 ! root      872:         tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
1.1       root      873:         break;
                    874:     case 2:
1.1.1.4 ! root      875:         tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1.1       root      876:         break;
                    877:     case 3:
1.1.1.4 ! root      878:         tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
        !           879:         tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1.1       root      880:         break;
                    881:     default:
                    882:         tcg_abort();
                    883:     }
                    884: 
                    885:     label2_ptr = s->code_ptr;
1.1.1.3   root      886:     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1.1       root      887:     tcg_out_nop(s);
                    888: 
                    889:     /* label1: fast path */
                    890:     reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
                    891: 
1.1.1.2   root      892:     tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1.1.1.4 ! root      893:                     offsetof(CPUState, tlb_table[mem_index][0].addend));
1.1.1.2   root      894:     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
1.1.1.4 ! root      895: #else
        !           896:     if (GUEST_BASE == (int16_t)GUEST_BASE) {
        !           897:         tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
        !           898:     } else {
        !           899:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
        !           900:         tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
        !           901:     }
1.1       root      902: #endif
                    903: 
                    904:     switch(opc) {
                    905:     case 0:
1.1.1.4 ! root      906:         tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
1.1       root      907:         break;
                    908:     case 0 | 4:
1.1.1.4 ! root      909:         tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
1.1       root      910:         break;
                    911:     case 1:
                    912:         if (TCG_NEED_BSWAP) {
1.1.1.4 ! root      913:             tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1.1       root      914:             tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
                    915:         } else {
1.1.1.4 ! root      916:             tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
1.1       root      917:         }
                    918:         break;
                    919:     case 1 | 4:
                    920:         if (TCG_NEED_BSWAP) {
1.1.1.4 ! root      921:             tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1.1       root      922:             tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
                    923:         } else {
1.1.1.4 ! root      924:             tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
1.1       root      925:         }
                    926:         break;
                    927:     case 2:
                    928:         if (TCG_NEED_BSWAP) {
1.1.1.4 ! root      929:             tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1.1       root      930:             tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
                    931:         } else {
1.1.1.4 ! root      932:             tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1.1       root      933:         }
                    934:         break;
                    935:     case 3:
                    936:         if (TCG_NEED_BSWAP) {
1.1.1.4 ! root      937:             tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1.1       root      938:             tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1.1.1.4 ! root      939:             tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1.1       root      940:             tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
                    941:         } else {
1.1.1.4 ! root      942:             tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
        !           943:             tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1.1       root      944:         }
                    945:         break;
                    946:     default:
                    947:         tcg_abort();
                    948:     }
                    949: 
                    950: #if defined(CONFIG_SOFTMMU)
                    951:     reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
                    952: #endif
                    953: }
                    954: 
                    955: static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
                    956:                             int opc)
                    957: {
                    958:     int addr_regl, addr_reg1, addr_meml;
                    959:     int data_regl, data_regh, data_reg1, data_reg2;
                    960:     int mem_index, s_bits;
                    961: #if defined(CONFIG_SOFTMMU)
                    962:     uint8_t *label1_ptr, *label2_ptr;
                    963:     int sp_args;
                    964: #endif
                    965: #if TARGET_LONG_BITS == 64
                    966: # if defined(CONFIG_SOFTMMU)
                    967:     uint8_t *label3_ptr;
                    968: # endif
                    969:     int addr_regh, addr_reg2, addr_memh;
                    970: #endif
                    971: 
                    972:     data_regl = *args++;
                    973:     if (opc == 3) {
                    974:         data_regh = *args++;
                    975: #if defined(TCG_TARGET_WORDS_BIGENDIAN)
                    976:         data_reg1 = data_regh;
                    977:         data_reg2 = data_regl;
                    978: #else
                    979:         data_reg1 = data_regl;
                    980:         data_reg2 = data_regh;
                    981: #endif
                    982:     } else {
                    983:         data_reg1 = data_regl;
                    984:         data_reg2 = 0;
                    985:         data_regh = 0;
                    986:     }
                    987:     addr_regl = *args++;
                    988: #if TARGET_LONG_BITS == 64
                    989:     addr_regh = *args++;
                    990: # if defined(TCG_TARGET_WORDS_BIGENDIAN)
                    991:     addr_reg1 = addr_regh;
                    992:     addr_reg2 = addr_regl;
                    993:     addr_memh = 0;
                    994:     addr_meml = 4;
                    995: # else
                    996:     addr_reg1 = addr_regl;
                    997:     addr_reg2 = addr_regh;
                    998:     addr_memh = 4;
                    999:     addr_meml = 0;
                   1000: # endif
                   1001: #else
                   1002:     addr_reg1 = addr_regl;
                   1003:     addr_meml = 0;
                   1004: #endif
                   1005:     mem_index = *args;
                   1006:     s_bits = opc;
                   1007: 
                   1008: #if defined(CONFIG_SOFTMMU)
                   1009:     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
                   1010:     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
                   1011:     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
                   1012:     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
                   1013:                     offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_meml);
                   1014:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
                   1015:     tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
                   1016: 
                   1017: # if TARGET_LONG_BITS == 64
                   1018:     label3_ptr = s->code_ptr;
1.1.1.3   root     1019:     tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1.1       root     1020:     tcg_out_nop(s);
                   1021: 
                   1022:     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
                   1023:                     offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_memh);
                   1024: 
                   1025:     label1_ptr = s->code_ptr;
1.1.1.3   root     1026:     tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1.1       root     1027:     tcg_out_nop(s);
                   1028: 
                   1029:     reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
                   1030: # else
                   1031:     label1_ptr = s->code_ptr;
1.1.1.3   root     1032:     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1.1       root     1033:     tcg_out_nop(s);
                   1034: # endif
                   1035: 
                   1036:     /* slow path */
                   1037:     sp_args = TCG_REG_A0;
1.1.1.4 ! root     1038:     tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1.1       root     1039: # if TARGET_LONG_BITS == 64
1.1.1.4 ! root     1040:     tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1.1       root     1041: # endif
                   1042:     switch(opc) {
                   1043:     case 0:
                   1044:         tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
                   1045:         break;
                   1046:     case 1:
                   1047:         tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
                   1048:         break;
                   1049:     case 2:
1.1.1.4 ! root     1050:         tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1.1       root     1051:         break;
                   1052:     case 3:
                   1053:         sp_args = (sp_args + 1) & ~1;
1.1.1.4 ! root     1054:         tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
        !          1055:         tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
1.1       root     1056:         break;
                   1057:     default:
                   1058:         tcg_abort();
                   1059:     }
                   1060:     if (sp_args > TCG_REG_A3) {
                   1061:         /* Push mem_index on the stack */
                   1062:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
                   1063:         tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
                   1064:     } else {
                   1065:         tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
                   1066:     }
                   1067: 
                   1068:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
                   1069:     tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
                   1070:     tcg_out_nop(s);
                   1071: 
                   1072:     label2_ptr = s->code_ptr;
1.1.1.3   root     1073:     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1.1       root     1074:     tcg_out_nop(s);
                   1075: 
                   1076:     /* label1: fast path */
                   1077:     reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
                   1078: 
                   1079:     tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1.1.1.4 ! root     1080:                     offsetof(CPUState, tlb_table[mem_index][0].addend));
1.1       root     1081:     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1.1.1.4 ! root     1082: #else
        !          1083:     if (GUEST_BASE == (int16_t)GUEST_BASE) {
        !          1084:         tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
        !          1085:     } else {
        !          1086:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
        !          1087:         tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
        !          1088:     }
1.1       root     1089: 
                   1090: #endif
                   1091: 
                   1092:     switch(opc) {
                   1093:     case 0:
1.1.1.4 ! root     1094:         tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1.1       root     1095:         break;
                   1096:     case 1:
                   1097:         if (TCG_NEED_BSWAP) {
                   1098:             tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1.1.1.4 ! root     1099:             tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1.1       root     1100:         } else {
1.1.1.4 ! root     1101:             tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1.1       root     1102:         }
                   1103:         break;
                   1104:     case 2:
                   1105:         if (TCG_NEED_BSWAP) {
                   1106:             tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1.1.1.4 ! root     1107:             tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1.1       root     1108:         } else {
1.1.1.4 ! root     1109:             tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1.1       root     1110:         }
                   1111:         break;
                   1112:     case 3:
                   1113:         if (TCG_NEED_BSWAP) {
                   1114:             tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1.1.1.4 ! root     1115:             tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1.1       root     1116:             tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1.1.1.4 ! root     1117:             tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1.1       root     1118:         } else {
1.1.1.4 ! root     1119:             tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
        !          1120:             tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1.1       root     1121:         }
                   1122:         break;
                   1123:     default:
                   1124:         tcg_abort();
                   1125:     }
                   1126: 
                   1127: #if defined(CONFIG_SOFTMMU)
                   1128:     reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
                   1129: #endif
                   1130: }
                   1131: 
1.1.1.4 ! root     1132: static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1.1       root     1133:                               const TCGArg *args, const int *const_args)
                   1134: {
                   1135:     switch(opc) {
                   1136:     case INDEX_op_exit_tb:
                   1137:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
                   1138:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
                   1139:         tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
                   1140:         tcg_out_nop(s);
                   1141:         break;
                   1142:     case INDEX_op_goto_tb:
                   1143:         if (s->tb_jmp_offset) {
                   1144:             /* direct jump method */
                   1145:             tcg_abort();
                   1146:         } else {
                   1147:             /* indirect jump method */
                   1148:             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
                   1149:             tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
                   1150:             tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
                   1151:         }
                   1152:         tcg_out_nop(s);
                   1153:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                   1154:         break;
                   1155:     case INDEX_op_call:
                   1156:         tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
                   1157:         tcg_out_nop(s);
                   1158:         break;
                   1159:     case INDEX_op_jmp:
                   1160:         tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
                   1161:         tcg_out_nop(s);
                   1162:         break;
                   1163:     case INDEX_op_br:
                   1164:         tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
                   1165:         break;
                   1166: 
                   1167:     case INDEX_op_mov_i32:
1.1.1.4 ! root     1168:         tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1.1       root     1169:         break;
                   1170:     case INDEX_op_movi_i32:
                   1171:         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
                   1172:         break;
                   1173: 
                   1174:     case INDEX_op_ld8u_i32:
1.1.1.4 ! root     1175:         tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1.1       root     1176:         break;
                   1177:     case INDEX_op_ld8s_i32:
                   1178:         tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
                   1179:         break;
                   1180:     case INDEX_op_ld16u_i32:
                   1181:         tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
                   1182:         break;
                   1183:     case INDEX_op_ld16s_i32:
                   1184:         tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
                   1185:         break;
                   1186:     case INDEX_op_ld_i32:
                   1187:         tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
                   1188:         break;
                   1189:     case INDEX_op_st8_i32:
                   1190:         tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
                   1191:         break;
                   1192:     case INDEX_op_st16_i32:
                   1193:         tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
                   1194:         break;
                   1195:     case INDEX_op_st_i32:
                   1196:         tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
                   1197:         break;
                   1198: 
                   1199:     case INDEX_op_add_i32:
                   1200:         if (const_args[2]) {
                   1201:             tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
                   1202:         } else {
                   1203:             tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
                   1204:         }
                   1205:         break;
                   1206:     case INDEX_op_add2_i32:
                   1207:         if (const_args[4]) {
                   1208:             tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
                   1209:         } else {
                   1210:             tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
                   1211:         }
                   1212:         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
                   1213:         if (const_args[5]) {
                   1214:             tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
                   1215:         } else {
                   1216:              tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
                   1217:         }
                   1218:         tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1.1.1.4 ! root     1219:         tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1.1       root     1220:         break;
                   1221:     case INDEX_op_sub_i32:
                   1222:         if (const_args[2]) {
                   1223:             tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
                   1224:         } else {
                   1225:             tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
                   1226:         }
                   1227:         break;
                   1228:     case INDEX_op_sub2_i32:
                   1229:         if (const_args[4]) {
                   1230:             tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
                   1231:         } else {
                   1232:             tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
                   1233:         }
                   1234:         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
                   1235:         if (const_args[5]) {
                   1236:             tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
                   1237:         } else {
                   1238:              tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
                   1239:         }
                   1240:         tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1.1.1.4 ! root     1241:         tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1.1       root     1242:         break;
                   1243:     case INDEX_op_mul_i32:
                   1244:         tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
                   1245:         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
                   1246:         break;
                   1247:     case INDEX_op_mulu2_i32:
                   1248:         tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
                   1249:         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
                   1250:         tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
                   1251:         break;
                   1252:     case INDEX_op_div_i32:
                   1253:         tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
                   1254:         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
                   1255:         break;
                   1256:     case INDEX_op_divu_i32:
                   1257:         tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
                   1258:         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
                   1259:         break;
                   1260:     case INDEX_op_rem_i32:
                   1261:         tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
                   1262:         tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
                   1263:         break;
                   1264:     case INDEX_op_remu_i32:
                   1265:         tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
                   1266:         tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
                   1267:         break;
                   1268: 
                   1269:     case INDEX_op_and_i32:
                   1270:         if (const_args[2]) {
                   1271:             tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
                   1272:         } else {
                   1273:             tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
                   1274:         }
                   1275:         break;
                   1276:     case INDEX_op_or_i32:
                   1277:         if (const_args[2]) {
                   1278:             tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
                   1279:         } else {
                   1280:             tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
                   1281:         }
                   1282:         break;
1.1.1.4 ! root     1283:     case INDEX_op_nor_i32:
        !          1284:         tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
        !          1285:         break;
1.1       root     1286:     case INDEX_op_not_i32:
1.1.1.4 ! root     1287:         tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1.1       root     1288:         break;
                   1289:     case INDEX_op_xor_i32:
                   1290:         if (const_args[2]) {
                   1291:             tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
                   1292:         } else {
                   1293:             tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
                   1294:         }
                   1295:         break;
                   1296: 
                   1297:     case INDEX_op_sar_i32:
                   1298:         if (const_args[2]) {
                   1299:             tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
                   1300:         } else {
                   1301:             tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
                   1302:         }
                   1303:         break;
                   1304:     case INDEX_op_shl_i32:
                   1305:         if (const_args[2]) {
                   1306:             tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
                   1307:         } else {
                   1308:             tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
                   1309:         }
                   1310:         break;
                   1311:     case INDEX_op_shr_i32:
                   1312:         if (const_args[2]) {
                   1313:             tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
                   1314:         } else {
                   1315:             tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
                   1316:         }
                   1317:         break;
                   1318: 
1.1.1.4 ! root     1319:     case INDEX_op_ext8s_i32:
        !          1320:         tcg_out_ext8s(s, args[0], args[1]);
        !          1321:         break;
        !          1322:     case INDEX_op_ext16s_i32:
        !          1323:         tcg_out_ext16s(s, args[0], args[1]);
        !          1324:         break;
        !          1325: 
1.1       root     1326:     case INDEX_op_brcond_i32:
                   1327:         tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
                   1328:         break;
                   1329:     case INDEX_op_brcond2_i32:
                   1330:         tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
                   1331:         break;
                   1332: 
1.1.1.4 ! root     1333:     case INDEX_op_setcond_i32:
        !          1334:         tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
        !          1335:         break;
        !          1336:     case INDEX_op_setcond2_i32:
        !          1337:         tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
        !          1338:         break;
        !          1339: 
1.1       root     1340:     case INDEX_op_qemu_ld8u:
                   1341:         tcg_out_qemu_ld(s, args, 0);
                   1342:         break;
                   1343:     case INDEX_op_qemu_ld8s:
                   1344:         tcg_out_qemu_ld(s, args, 0 | 4);
                   1345:         break;
                   1346:     case INDEX_op_qemu_ld16u:
                   1347:         tcg_out_qemu_ld(s, args, 1);
                   1348:         break;
                   1349:     case INDEX_op_qemu_ld16s:
                   1350:         tcg_out_qemu_ld(s, args, 1 | 4);
                   1351:         break;
1.1.1.4 ! root     1352:     case INDEX_op_qemu_ld32:
1.1       root     1353:         tcg_out_qemu_ld(s, args, 2);
                   1354:         break;
                   1355:     case INDEX_op_qemu_ld64:
                   1356:         tcg_out_qemu_ld(s, args, 3);
                   1357:         break;
                   1358:     case INDEX_op_qemu_st8:
                   1359:         tcg_out_qemu_st(s, args, 0);
                   1360:         break;
                   1361:     case INDEX_op_qemu_st16:
                   1362:         tcg_out_qemu_st(s, args, 1);
                   1363:         break;
                   1364:     case INDEX_op_qemu_st32:
                   1365:         tcg_out_qemu_st(s, args, 2);
                   1366:         break;
                   1367:     case INDEX_op_qemu_st64:
                   1368:         tcg_out_qemu_st(s, args, 3);
                   1369:         break;
                   1370: 
                   1371:     default:
                   1372:         tcg_abort();
                   1373:     }
                   1374: }
                   1375: 
                   1376: static const TCGTargetOpDef mips_op_defs[] = {
                   1377:     { INDEX_op_exit_tb, { } },
                   1378:     { INDEX_op_goto_tb, { } },
                   1379:     { INDEX_op_call, { "C" } },
                   1380:     { INDEX_op_jmp, { "r" } },
                   1381:     { INDEX_op_br, { } },
                   1382: 
                   1383:     { INDEX_op_mov_i32, { "r", "r" } },
                   1384:     { INDEX_op_movi_i32, { "r" } },
                   1385:     { INDEX_op_ld8u_i32, { "r", "r" } },
                   1386:     { INDEX_op_ld8s_i32, { "r", "r" } },
                   1387:     { INDEX_op_ld16u_i32, { "r", "r" } },
                   1388:     { INDEX_op_ld16s_i32, { "r", "r" } },
                   1389:     { INDEX_op_ld_i32, { "r", "r" } },
                   1390:     { INDEX_op_st8_i32, { "rZ", "r" } },
                   1391:     { INDEX_op_st16_i32, { "rZ", "r" } },
                   1392:     { INDEX_op_st_i32, { "rZ", "r" } },
                   1393: 
                   1394:     { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
                   1395:     { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
                   1396:     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
                   1397:     { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
                   1398:     { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
                   1399:     { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
                   1400:     { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
                   1401:     { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
                   1402: 
                   1403:     { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
1.1.1.4 ! root     1404:     { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1.1       root     1405:     { INDEX_op_not_i32, { "r", "rZ" } },
                   1406:     { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
                   1407:     { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
                   1408: 
                   1409:     { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
                   1410:     { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
                   1411:     { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
                   1412: 
1.1.1.4 ! root     1413:     { INDEX_op_ext8s_i32, { "r", "rZ" } },
        !          1414:     { INDEX_op_ext16s_i32, { "r", "rZ" } },
        !          1415: 
1.1       root     1416:     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1.1.1.4 ! root     1417:     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
        !          1418:     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1.1       root     1419: 
                   1420:     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
                   1421:     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
                   1422:     { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
                   1423: 
                   1424: #if TARGET_LONG_BITS == 32
                   1425:     { INDEX_op_qemu_ld8u, { "L", "lZ" } },
                   1426:     { INDEX_op_qemu_ld8s, { "L", "lZ" } },
                   1427:     { INDEX_op_qemu_ld16u, { "L", "lZ" } },
                   1428:     { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1.1.1.4 ! root     1429:     { INDEX_op_qemu_ld32, { "L", "lZ" } },
1.1       root     1430:     { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
                   1431: 
                   1432:     { INDEX_op_qemu_st8, { "SZ", "SZ" } },
                   1433:     { INDEX_op_qemu_st16, { "SZ", "SZ" } },
                   1434:     { INDEX_op_qemu_st32, { "SZ", "SZ" } },
                   1435:     { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
                   1436: #else
                   1437:     { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
                   1438:     { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
                   1439:     { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
                   1440:     { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1.1.1.4 ! root     1441:     { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1.1       root     1442:     { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
                   1443: 
                   1444:     { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
                   1445:     { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
                   1446:     { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
                   1447:     { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
                   1448: #endif
                   1449:     { -1 },
                   1450: };
                   1451: 
                   1452: static int tcg_target_callee_save_regs[] = {
1.1.1.3   root     1453: #if 0 /* used for the global env (TCG_AREG0), so no need to save */
1.1       root     1454:     TCG_REG_S0,
1.1.1.3   root     1455: #endif
1.1       root     1456:     TCG_REG_S1,
                   1457:     TCG_REG_S2,
                   1458:     TCG_REG_S3,
                   1459:     TCG_REG_S4,
                   1460:     TCG_REG_S5,
                   1461:     TCG_REG_S6,
                   1462:     TCG_REG_S7,
                   1463:     TCG_REG_GP,
1.1.1.3   root     1464:     TCG_REG_FP,
1.1       root     1465:     TCG_REG_RA,       /* should be last for ABI compliance */
                   1466: };
                   1467: 
                   1468: /* Generate global QEMU prologue and epilogue code */
1.1.1.4 ! root     1469: static void tcg_target_qemu_prologue(TCGContext *s)
1.1       root     1470: {
                   1471:     int i, frame_size;
                   1472: 
                   1473:     /* reserve some stack space */
                   1474:     frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
                   1475:                  + TCG_STATIC_CALL_ARGS_SIZE;
                   1476:     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
                   1477:                  ~(TCG_TARGET_STACK_ALIGN - 1);
                   1478: 
                   1479:     /* TB prologue */
                   1480:     tcg_out_addi(s, TCG_REG_SP, -frame_size);
                   1481:     for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
                   1482:         tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
                   1483:                    TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
                   1484:     }
                   1485: 
                   1486:     /* Call generated code */
                   1487:     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0);
                   1488:     tcg_out_nop(s);
                   1489:     tb_ret_addr = s->code_ptr;
                   1490: 
                   1491:     /* TB epilogue */
                   1492:     for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
                   1493:         tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
                   1494:                    TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
                   1495:     }
                   1496: 
                   1497:     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
                   1498:     tcg_out_addi(s, TCG_REG_SP, frame_size);
                   1499: }
                   1500: 
1.1.1.4 ! root     1501: static void tcg_target_init(TCGContext *s)
1.1       root     1502: {
                   1503:     tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
                   1504:     tcg_regset_set(tcg_target_call_clobber_regs,
                   1505:                    (1 << TCG_REG_V0) |
                   1506:                    (1 << TCG_REG_V1) |
                   1507:                    (1 << TCG_REG_A0) |
                   1508:                    (1 << TCG_REG_A1) |
                   1509:                    (1 << TCG_REG_A2) |
                   1510:                    (1 << TCG_REG_A3) |
                   1511:                    (1 << TCG_REG_T1) |
                   1512:                    (1 << TCG_REG_T2) |
                   1513:                    (1 << TCG_REG_T3) |
                   1514:                    (1 << TCG_REG_T4) |
                   1515:                    (1 << TCG_REG_T5) |
                   1516:                    (1 << TCG_REG_T6) |
                   1517:                    (1 << TCG_REG_T7) |
                   1518:                    (1 << TCG_REG_T8) |
                   1519:                    (1 << TCG_REG_T9));
                   1520: 
                   1521:     tcg_regset_clear(s->reserved_regs);
                   1522:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
                   1523:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
                   1524:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
                   1525:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
                   1526:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
                   1527:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
                   1528:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
                   1529: 
                   1530:     tcg_add_target_add_op_defs(mips_op_defs);
                   1531: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.