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

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

unix.superglobalmegacorp.com

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