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

1.1       root        1: /*
                      2:  * Tiny Code Generator for QEMU
                      3:  *
                      4:  * Copyright (c) 2008 Fabrice Bellard
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: static uint8_t *tb_ret_addr;
                     26: 
1.1.1.7 ! root       27: #if defined _CALL_DARWIN || defined __APPLE__
        !            28: #define TCG_TARGET_CALL_DARWIN
        !            29: #endif
        !            30: 
        !            31: #ifdef TCG_TARGET_CALL_DARWIN
1.1       root       32: #define LINKAGE_AREA_SIZE 24
                     33: #define LR_OFFSET 8
1.1.1.4   root       34: #elif defined _CALL_AIX
1.1       root       35: #define LINKAGE_AREA_SIZE 52
                     36: #define LR_OFFSET 8
                     37: #else
                     38: #define LINKAGE_AREA_SIZE 8
                     39: #define LR_OFFSET 4
                     40: #endif
                     41: 
                     42: #define FAST_PATH
                     43: 
1.1.1.3   root       44: #ifndef GUEST_BASE
                     45: #define GUEST_BASE 0
                     46: #endif
                     47: 
                     48: #ifdef CONFIG_USE_GUEST_BASE
                     49: #define TCG_GUEST_BASE_REG 30
                     50: #else
                     51: #define TCG_GUEST_BASE_REG 0
                     52: #endif
                     53: 
1.1       root       54: #ifndef NDEBUG
                     55: static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
                     56:     "r0",
                     57:     "r1",
1.1.1.4   root       58:     "r2",
1.1       root       59:     "r3",
                     60:     "r4",
                     61:     "r5",
                     62:     "r6",
                     63:     "r7",
                     64:     "r8",
                     65:     "r9",
                     66:     "r10",
                     67:     "r11",
                     68:     "r12",
                     69:     "r13",
                     70:     "r14",
                     71:     "r15",
                     72:     "r16",
                     73:     "r17",
                     74:     "r18",
                     75:     "r19",
                     76:     "r20",
                     77:     "r21",
                     78:     "r22",
                     79:     "r23",
                     80:     "r24",
                     81:     "r25",
                     82:     "r26",
                     83:     "r27",
                     84:     "r28",
                     85:     "r29",
                     86:     "r30",
                     87:     "r31"
                     88: };
                     89: #endif
                     90: 
                     91: static const int tcg_target_reg_alloc_order[] = {
                     92:     TCG_REG_R14,
                     93:     TCG_REG_R15,
                     94:     TCG_REG_R16,
                     95:     TCG_REG_R17,
                     96:     TCG_REG_R18,
                     97:     TCG_REG_R19,
                     98:     TCG_REG_R20,
                     99:     TCG_REG_R21,
                    100:     TCG_REG_R22,
                    101:     TCG_REG_R23,
                    102:     TCG_REG_R28,
                    103:     TCG_REG_R29,
                    104:     TCG_REG_R30,
                    105:     TCG_REG_R31,
1.1.1.7 ! root      106: #ifdef TCG_TARGET_CALL_DARWIN
1.1       root      107:     TCG_REG_R2,
                    108: #endif
                    109:     TCG_REG_R3,
                    110:     TCG_REG_R4,
                    111:     TCG_REG_R5,
                    112:     TCG_REG_R6,
                    113:     TCG_REG_R7,
                    114:     TCG_REG_R8,
                    115:     TCG_REG_R9,
                    116:     TCG_REG_R10,
1.1.1.7 ! root      117: #ifndef TCG_TARGET_CALL_DARWIN
1.1       root      118:     TCG_REG_R11,
                    119: #endif
                    120:     TCG_REG_R12,
1.1.1.4   root      121: #ifndef _CALL_SYSV
1.1       root      122:     TCG_REG_R13,
                    123: #endif
                    124:     TCG_REG_R24,
                    125:     TCG_REG_R25,
                    126:     TCG_REG_R26,
                    127:     TCG_REG_R27
                    128: };
                    129: 
                    130: static const int tcg_target_call_iarg_regs[] = {
                    131:     TCG_REG_R3,
                    132:     TCG_REG_R4,
                    133:     TCG_REG_R5,
                    134:     TCG_REG_R6,
                    135:     TCG_REG_R7,
                    136:     TCG_REG_R8,
                    137:     TCG_REG_R9,
                    138:     TCG_REG_R10
                    139: };
                    140: 
                    141: static const int tcg_target_call_oarg_regs[2] = {
                    142:     TCG_REG_R3,
                    143:     TCG_REG_R4
                    144: };
                    145: 
                    146: static const int tcg_target_callee_save_regs[] = {
1.1.1.7 ! root      147: #ifdef TCG_TARGET_CALL_DARWIN
1.1       root      148:     TCG_REG_R11,
                    149:     TCG_REG_R13,
                    150: #endif
1.1.1.4   root      151: #ifdef _CALL_AIX
1.1       root      152:     TCG_REG_R13,
                    153: #endif
                    154:     TCG_REG_R14,
                    155:     TCG_REG_R15,
                    156:     TCG_REG_R16,
                    157:     TCG_REG_R17,
                    158:     TCG_REG_R18,
                    159:     TCG_REG_R19,
                    160:     TCG_REG_R20,
                    161:     TCG_REG_R21,
                    162:     TCG_REG_R22,
                    163:     TCG_REG_R23,
                    164:     TCG_REG_R24,
                    165:     TCG_REG_R25,
                    166:     TCG_REG_R26,
1.1.1.5   root      167:     TCG_REG_R27, /* currently used for the global env */
1.1       root      168:     TCG_REG_R28,
                    169:     TCG_REG_R29,
                    170:     TCG_REG_R30,
                    171:     TCG_REG_R31
                    172: };
                    173: 
                    174: static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
                    175: {
                    176:     tcg_target_long disp;
                    177: 
                    178:     disp = target - (tcg_target_long) pc;
                    179:     if ((disp << 6) >> 6 != disp)
                    180:         tcg_abort ();
                    181: 
                    182:     return disp & 0x3fffffc;
                    183: }
                    184: 
                    185: static void reloc_pc24 (void *pc, tcg_target_long target)
                    186: {
                    187:     *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
                    188:         | reloc_pc24_val (pc, target);
                    189: }
                    190: 
                    191: static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
                    192: {
                    193:     tcg_target_long disp;
                    194: 
                    195:     disp = target - (tcg_target_long) pc;
                    196:     if (disp != (int16_t) disp)
                    197:         tcg_abort ();
                    198: 
                    199:     return disp & 0xfffc;
                    200: }
                    201: 
                    202: static void reloc_pc14 (void *pc, tcg_target_long target)
                    203: {
                    204:     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
                    205:         | reloc_pc14_val (pc, target);
                    206: }
                    207: 
                    208: static void patch_reloc(uint8_t *code_ptr, int type,
                    209:                         tcg_target_long value, tcg_target_long addend)
                    210: {
                    211:     value += addend;
                    212:     switch (type) {
                    213:     case R_PPC_REL14:
                    214:         reloc_pc14 (code_ptr, value);
                    215:         break;
                    216:     case R_PPC_REL24:
                    217:         reloc_pc24 (code_ptr, value);
                    218:         break;
                    219:     default:
                    220:         tcg_abort();
                    221:     }
                    222: }
                    223: 
                    224: /* maximum number of register used for input function arguments */
                    225: static int tcg_target_get_call_iarg_regs_count(int flags)
                    226: {
                    227:     return ARRAY_SIZE (tcg_target_call_iarg_regs);
                    228: }
                    229: 
                    230: /* parse target specific constraints */
                    231: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    232: {
                    233:     const char *ct_str;
                    234: 
                    235:     ct_str = *pct_str;
                    236:     switch (ct_str[0]) {
                    237:     case 'A': case 'B': case 'C': case 'D':
                    238:         ct->ct |= TCG_CT_REG;
                    239:         tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
                    240:         break;
                    241:     case 'r':
                    242:         ct->ct |= TCG_CT_REG;
                    243:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    244:         break;
                    245: #ifdef CONFIG_SOFTMMU
                    246:     case 'L':                   /* qemu_ld constraint */
                    247:         ct->ct |= TCG_CT_REG;
                    248:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    249:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    250:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
1.1.1.7 ! root      251: #ifdef CONFIG_TCG_PASS_AREG0
        !           252:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
        !           253: #if TARGET_LONG_BITS == 64
        !           254:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
        !           255: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
        !           256:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
        !           257: #endif
        !           258: #endif
        !           259: #else /* !AREG0 */
        !           260: #if TARGET_LONG_BITS == 64
        !           261:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
        !           262: #endif
        !           263: #endif
1.1       root      264:         break;
                    265:     case 'K':                   /* qemu_st[8..32] constraint */
                    266:         ct->ct |= TCG_CT_REG;
                    267:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    268:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    269:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
                    270:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
1.1.1.7 ! root      271: #ifdef CONFIG_TCG_PASS_AREG0
        !           272:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
        !           273: #if TARGET_LONG_BITS == 64
        !           274:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
        !           275: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
        !           276:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R8);
        !           277: #endif
        !           278: #endif
        !           279: #else /* !AREG0 */
1.1       root      280: #if TARGET_LONG_BITS == 64
                    281:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
                    282: #endif
1.1.1.7 ! root      283: #endif
1.1       root      284:         break;
                    285:     case 'M':                   /* qemu_st64 constraint */
                    286:         ct->ct |= TCG_CT_REG;
                    287:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    288:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    289:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
                    290:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
                    291:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
                    292:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
1.1.1.7 ! root      293: #if defined(CONFIG_TCG_PASS_AREG0)
        !           294:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R8);
        !           295: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
        !           296:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R9);
        !           297: #endif
        !           298: #endif
1.1       root      299:         break;
                    300: #else
                    301:     case 'L':
                    302:     case 'K':
                    303:         ct->ct |= TCG_CT_REG;
                    304:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    305:         break;
                    306:     case 'M':
                    307:         ct->ct |= TCG_CT_REG;
                    308:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    309:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    310:         break;
                    311: #endif
                    312:     default:
                    313:         return -1;
                    314:     }
                    315:     ct_str++;
                    316:     *pct_str = ct_str;
                    317:     return 0;
                    318: }
                    319: 
                    320: /* test if a constant matches the constraint */
                    321: static int tcg_target_const_match(tcg_target_long val,
                    322:                                   const TCGArgConstraint *arg_ct)
                    323: {
                    324:     int ct;
                    325: 
                    326:     ct = arg_ct->ct;
                    327:     if (ct & TCG_CT_CONST)
                    328:         return 1;
                    329:     return 0;
                    330: }
                    331: 
                    332: #define OPCD(opc) ((opc)<<26)
                    333: #define XO31(opc) (OPCD(31)|((opc)<<1))
                    334: #define XO19(opc) (OPCD(19)|((opc)<<1))
                    335: 
                    336: #define B      OPCD(18)
                    337: #define BC     OPCD(16)
                    338: #define LBZ    OPCD(34)
                    339: #define LHZ    OPCD(40)
                    340: #define LHA    OPCD(42)
                    341: #define LWZ    OPCD(32)
                    342: #define STB    OPCD(38)
                    343: #define STH    OPCD(44)
                    344: #define STW    OPCD(36)
                    345: 
1.1.1.4   root      346: #define ADDIC  OPCD(12)
1.1       root      347: #define ADDI   OPCD(14)
                    348: #define ADDIS  OPCD(15)
                    349: #define ORI    OPCD(24)
                    350: #define ORIS   OPCD(25)
                    351: #define XORI   OPCD(26)
                    352: #define XORIS  OPCD(27)
                    353: #define ANDI   OPCD(28)
                    354: #define ANDIS  OPCD(29)
                    355: #define MULLI  OPCD( 7)
                    356: #define CMPLI  OPCD(10)
                    357: #define CMPI   OPCD(11)
1.1.1.4   root      358: #define SUBFIC OPCD( 8)
1.1       root      359: 
                    360: #define LWZU   OPCD(33)
                    361: #define STWU   OPCD(37)
                    362: 
1.1.1.4   root      363: #define RLWIMI OPCD(20)
1.1       root      364: #define RLWINM OPCD(21)
1.1.1.4   root      365: #define RLWNM  OPCD(23)
1.1       root      366: 
                    367: #define BCLR   XO19( 16)
                    368: #define BCCTR  XO19(528)
                    369: #define CRAND  XO19(257)
                    370: #define CRANDC XO19(129)
                    371: #define CRNAND XO19(225)
                    372: #define CROR   XO19(449)
1.1.1.4   root      373: #define CRNOR  XO19( 33)
1.1       root      374: 
                    375: #define EXTSB  XO31(954)
                    376: #define EXTSH  XO31(922)
                    377: #define ADD    XO31(266)
                    378: #define ADDE   XO31(138)
                    379: #define ADDC   XO31( 10)
                    380: #define AND    XO31( 28)
                    381: #define SUBF   XO31( 40)
                    382: #define SUBFC  XO31(  8)
                    383: #define SUBFE  XO31(136)
                    384: #define OR     XO31(444)
                    385: #define XOR    XO31(316)
                    386: #define MULLW  XO31(235)
                    387: #define MULHWU XO31( 11)
                    388: #define DIVW   XO31(491)
                    389: #define DIVWU  XO31(459)
                    390: #define CMP    XO31(  0)
                    391: #define CMPL   XO31( 32)
                    392: #define LHBRX  XO31(790)
                    393: #define LWBRX  XO31(534)
                    394: #define STHBRX XO31(918)
                    395: #define STWBRX XO31(662)
                    396: #define MFSPR  XO31(339)
                    397: #define MTSPR  XO31(467)
                    398: #define SRAWI  XO31(824)
                    399: #define NEG    XO31(104)
1.1.1.4   root      400: #define MFCR   XO31( 19)
                    401: #define CNTLZW XO31( 26)
                    402: #define NOR    XO31(124)
                    403: #define ANDC   XO31( 60)
                    404: #define ORC    XO31(412)
                    405: #define EQV    XO31(284)
                    406: #define NAND   XO31(476)
1.1       root      407: 
                    408: #define LBZX   XO31( 87)
1.1.1.3   root      409: #define LHZX   XO31(279)
1.1       root      410: #define LHAX   XO31(343)
                    411: #define LWZX   XO31( 23)
                    412: #define STBX   XO31(215)
                    413: #define STHX   XO31(407)
                    414: #define STWX   XO31(151)
                    415: 
                    416: #define SPR(a,b) ((((a)<<5)|(b))<<11)
                    417: #define LR     SPR(8, 0)
                    418: #define CTR    SPR(9, 0)
                    419: 
                    420: #define SLW    XO31( 24)
                    421: #define SRW    XO31(536)
                    422: #define SRAW   XO31(792)
                    423: 
                    424: #define TW     XO31(4)
                    425: #define TRAP   (TW | TO (31))
                    426: 
                    427: #define RT(r) ((r)<<21)
                    428: #define RS(r) ((r)<<21)
                    429: #define RA(r) ((r)<<16)
                    430: #define RB(r) ((r)<<11)
                    431: #define TO(t) ((t)<<21)
                    432: #define SH(s) ((s)<<11)
                    433: #define MB(b) ((b)<<6)
                    434: #define ME(e) ((e)<<1)
                    435: #define BO(o) ((o)<<21)
                    436: 
                    437: #define LK    1
                    438: 
                    439: #define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
                    440: #define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
                    441: 
                    442: #define BF(n)    ((n)<<23)
                    443: #define BI(n, c) (((c)+((n)*4))<<16)
                    444: #define BT(n, c) (((c)+((n)*4))<<21)
                    445: #define BA(n, c) (((c)+((n)*4))<<16)
                    446: #define BB(n, c) (((c)+((n)*4))<<11)
                    447: 
                    448: #define BO_COND_TRUE  BO (12)
                    449: #define BO_COND_FALSE BO (4)
                    450: #define BO_ALWAYS     BO (20)
                    451: 
                    452: enum {
                    453:     CR_LT,
                    454:     CR_GT,
                    455:     CR_EQ,
                    456:     CR_SO
                    457: };
                    458: 
                    459: static const uint32_t tcg_to_bc[10] = {
                    460:     [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
                    461:     [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
                    462:     [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
                    463:     [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
                    464:     [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
                    465:     [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
                    466:     [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
                    467:     [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
                    468:     [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
                    469:     [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
                    470: };
                    471: 
1.1.1.6   root      472: static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
1.1       root      473: {
                    474:     tcg_out32 (s, OR | SAB (arg, ret, arg));
                    475: }
                    476: 
                    477: static void tcg_out_movi(TCGContext *s, TCGType type,
1.1.1.6   root      478:                          TCGReg ret, tcg_target_long arg)
1.1       root      479: {
                    480:     if (arg == (int16_t) arg)
                    481:         tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
                    482:     else {
                    483:         tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
                    484:         if (arg & 0xffff)
                    485:             tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
                    486:     }
                    487: }
                    488: 
                    489: static void tcg_out_ldst (TCGContext *s, int ret, int addr,
                    490:                           int offset, int op1, int op2)
                    491: {
                    492:     if (offset == (int16_t) offset)
                    493:         tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
                    494:     else {
                    495:         tcg_out_movi (s, TCG_TYPE_I32, 0, offset);
                    496:         tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
                    497:     }
                    498: }
                    499: 
                    500: static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
                    501: {
                    502:     tcg_target_long disp;
                    503: 
                    504:     disp = target - (tcg_target_long) s->code_ptr;
                    505:     if ((disp << 6) >> 6 == disp)
                    506:         tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
                    507:     else {
                    508:         tcg_out_movi (s, TCG_TYPE_I32, 0, (tcg_target_long) target);
                    509:         tcg_out32 (s, MTSPR | RS (0) | CTR);
                    510:         tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
                    511:     }
                    512: }
                    513: 
                    514: static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
                    515: {
1.1.1.4   root      516: #ifdef _CALL_AIX
1.1       root      517:     int reg;
                    518: 
                    519:     if (const_arg) {
                    520:         reg = 2;
                    521:         tcg_out_movi (s, TCG_TYPE_I32, reg, arg);
                    522:     }
                    523:     else reg = arg;
                    524: 
                    525:     tcg_out32 (s, LWZ | RT (0) | RA (reg));
                    526:     tcg_out32 (s, MTSPR | RA (0) | CTR);
                    527:     tcg_out32 (s, LWZ | RT (2) | RA (reg) | 4);
                    528:     tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
1.1.1.3   root      529: #else
                    530:     if (const_arg) {
                    531:         tcg_out_b (s, LK, arg);
                    532:     }
                    533:     else {
                    534:         tcg_out32 (s, MTSPR | RS (arg) | LR);
                    535:         tcg_out32 (s, BCLR | BO_ALWAYS | LK);
                    536:     }
1.1       root      537: #endif
1.1.1.3   root      538: }
1.1       root      539: 
                    540: #if defined(CONFIG_SOFTMMU)
                    541: 
                    542: #include "../../softmmu_defs.h"
                    543: 
1.1.1.7 ! root      544: #ifdef CONFIG_TCG_PASS_AREG0
        !           545: /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
        !           546:    int mmu_idx) */
        !           547: static const void * const qemu_ld_helpers[4] = {
        !           548:     helper_ldb_mmu,
        !           549:     helper_ldw_mmu,
        !           550:     helper_ldl_mmu,
        !           551:     helper_ldq_mmu,
        !           552: };
        !           553: 
        !           554: /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
        !           555:    uintxx_t val, int mmu_idx) */
        !           556: static const void * const qemu_st_helpers[4] = {
        !           557:     helper_stb_mmu,
        !           558:     helper_stw_mmu,
        !           559:     helper_stl_mmu,
        !           560:     helper_stq_mmu,
        !           561: };
        !           562: #else
        !           563: /* legacy helper signature: __ld_mmu(target_ulong addr, int
        !           564:    mmu_idx) */
1.1       root      565: static void *qemu_ld_helpers[4] = {
                    566:     __ldb_mmu,
                    567:     __ldw_mmu,
                    568:     __ldl_mmu,
                    569:     __ldq_mmu,
                    570: };
                    571: 
1.1.1.7 ! root      572: /* legacy helper signature: __ld_mmu(target_ulong addr, int
        !           573:    mmu_idx) */
1.1       root      574: static void *qemu_st_helpers[4] = {
                    575:     __stb_mmu,
                    576:     __stw_mmu,
                    577:     __stl_mmu,
                    578:     __stq_mmu,
                    579: };
                    580: #endif
1.1.1.7 ! root      581: #endif
1.1       root      582: 
                    583: static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
                    584: {
1.1.1.6   root      585:     int addr_reg, data_reg, data_reg2, r0, r1, rbase, bswap;
1.1       root      586: #ifdef CONFIG_SOFTMMU
1.1.1.7 ! root      587:     int mem_index, s_bits, r2, ir;
1.1       root      588:     void *label1_ptr, *label2_ptr;
                    589: #if TARGET_LONG_BITS == 64
                    590:     int addr_reg2;
                    591: #endif
1.1.1.6   root      592: #endif
1.1       root      593: 
                    594:     data_reg = *args++;
                    595:     if (opc == 3)
                    596:         data_reg2 = *args++;
                    597:     else
                    598:         data_reg2 = 0;
                    599:     addr_reg = *args++;
1.1.1.6   root      600: 
                    601: #ifdef CONFIG_SOFTMMU
1.1       root      602: #if TARGET_LONG_BITS == 64
                    603:     addr_reg2 = *args++;
                    604: #endif
                    605:     mem_index = *args;
                    606:     s_bits = opc & 3;
                    607:     r0 = 3;
                    608:     r1 = 4;
                    609:     r2 = 0;
1.1.1.3   root      610:     rbase = 0;
1.1       root      611: 
                    612:     tcg_out32 (s, (RLWINM
                    613:                    | RA (r0)
                    614:                    | RS (addr_reg)
                    615:                    | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
                    616:                    | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
                    617:                    | ME (31 - CPU_TLB_ENTRY_BITS)
                    618:                    )
                    619:         );
                    620:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
                    621:     tcg_out32 (s, (LWZU
                    622:                    | RT (r1)
                    623:                    | RA (r0)
1.1.1.7 ! root      624:                    | offsetof (CPUArchState, tlb_table[mem_index][0].addr_read)
1.1       root      625:                    )
                    626:         );
                    627:     tcg_out32 (s, (RLWINM
                    628:                    | RA (r2)
                    629:                    | RS (addr_reg)
                    630:                    | SH (0)
                    631:                    | MB ((32 - s_bits) & 31)
                    632:                    | ME (31 - TARGET_PAGE_BITS)
                    633:                    )
                    634:         );
                    635: 
                    636:     tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
                    637: #if TARGET_LONG_BITS == 64
                    638:     tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
                    639:     tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
                    640:     tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
                    641: #endif
                    642: 
                    643:     label1_ptr = s->code_ptr;
                    644: #ifdef FAST_PATH
                    645:     tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
                    646: #endif
                    647: 
                    648:     /* slow path */
1.1.1.7 ! root      649:     ir = 3;
        !           650: #ifdef CONFIG_TCG_PASS_AREG0
        !           651:     tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);
        !           652: #endif
1.1       root      653: #if TARGET_LONG_BITS == 32
1.1.1.7 ! root      654:     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
1.1       root      655: #else
1.1.1.7 ! root      656: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
        !           657:     ir |= 1;
1.1       root      658: #endif
1.1.1.7 ! root      659:     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg2);
        !           660:     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
        !           661: #endif
        !           662:     tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
1.1       root      663: 
                    664:     tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
                    665:     switch (opc) {
                    666:     case 0|4:
                    667:         tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
                    668:         break;
                    669:     case 1|4:
                    670:         tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
                    671:         break;
                    672:     case 0:
                    673:     case 1:
                    674:     case 2:
                    675:         if (data_reg != 3)
1.1.1.4   root      676:             tcg_out_mov (s, TCG_TYPE_I32, data_reg, 3);
1.1       root      677:         break;
                    678:     case 3:
                    679:         if (data_reg == 3) {
                    680:             if (data_reg2 == 4) {
1.1.1.4   root      681:                 tcg_out_mov (s, TCG_TYPE_I32, 0, 4);
                    682:                 tcg_out_mov (s, TCG_TYPE_I32, 4, 3);
                    683:                 tcg_out_mov (s, TCG_TYPE_I32, 3, 0);
1.1       root      684:             }
                    685:             else {
1.1.1.4   root      686:                 tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 3);
                    687:                 tcg_out_mov (s, TCG_TYPE_I32, 3, 4);
1.1       root      688:             }
                    689:         }
                    690:         else {
1.1.1.4   root      691:             if (data_reg != 4) tcg_out_mov (s, TCG_TYPE_I32, data_reg, 4);
                    692:             if (data_reg2 != 3) tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 3);
1.1       root      693:         }
                    694:         break;
                    695:     }
                    696:     label2_ptr = s->code_ptr;
                    697:     tcg_out32 (s, B);
                    698: 
                    699:     /* label1: fast path */
                    700: #ifdef FAST_PATH
                    701:     reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
                    702: #endif
                    703: 
                    704:     /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
                    705:     tcg_out32 (s, (LWZ
                    706:                    | RT (r0)
                    707:                    | RA (r0)
1.1.1.4   root      708:                    | (offsetof (CPUTLBEntry, addend)
1.1       root      709:                       - offsetof (CPUTLBEntry, addr_read))
                    710:                    ));
                    711:     /* r0 = env->tlb_table[mem_index][index].addend */
                    712:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
                    713:     /* r0 = env->tlb_table[mem_index][index].addend + addr */
                    714: 
                    715: #else  /* !CONFIG_SOFTMMU */
                    716:     r0 = addr_reg;
                    717:     r1 = 3;
1.1.1.3   root      718:     rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1.1       root      719: #endif
                    720: 
                    721: #ifdef TARGET_WORDS_BIGENDIAN
                    722:     bswap = 0;
                    723: #else
                    724:     bswap = 1;
                    725: #endif
1.1.1.3   root      726: 
1.1       root      727:     switch (opc) {
                    728:     default:
                    729:     case 0:
1.1.1.3   root      730:         tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
1.1       root      731:         break;
                    732:     case 0|4:
1.1.1.3   root      733:         tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
1.1       root      734:         tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
                    735:         break;
                    736:     case 1:
1.1.1.3   root      737:         if (bswap)
                    738:             tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
                    739:         else
                    740:             tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
1.1       root      741:         break;
                    742:     case 1|4:
                    743:         if (bswap) {
1.1.1.3   root      744:             tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
1.1       root      745:             tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
                    746:         }
1.1.1.3   root      747:         else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
1.1       root      748:         break;
                    749:     case 2:
1.1.1.3   root      750:         if (bswap)
                    751:             tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
                    752:         else
                    753:             tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
1.1       root      754:         break;
                    755:     case 3:
                    756:         if (bswap) {
1.1.1.3   root      757:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
                    758:             tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
                    759:             tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));
1.1       root      760:         }
                    761:         else {
1.1.1.3   root      762: #ifdef CONFIG_USE_GUEST_BASE
                    763:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
                    764:             tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));
                    765:             tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));
                    766: #else
1.1       root      767:             if (r0 == data_reg2) {
                    768:                 tcg_out32 (s, LWZ | RT (0) | RA (r0));
                    769:                 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
1.1.1.4   root      770:                 tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 0);
1.1       root      771:             }
                    772:             else {
                    773:                 tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
                    774:                 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
                    775:             }
1.1.1.3   root      776: #endif
1.1       root      777:         }
                    778:         break;
                    779:     }
                    780: 
                    781: #ifdef CONFIG_SOFTMMU
                    782:     reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
                    783: #endif
                    784: }
                    785: 
                    786: static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
                    787: {
1.1.1.6   root      788:     int addr_reg, r0, r1, data_reg, data_reg2, bswap, rbase;
1.1       root      789: #ifdef CONFIG_SOFTMMU
1.1.1.6   root      790:     int mem_index, r2, ir;
1.1       root      791:     void *label1_ptr, *label2_ptr;
                    792: #if TARGET_LONG_BITS == 64
                    793:     int addr_reg2;
                    794: #endif
1.1.1.6   root      795: #endif
1.1       root      796: 
                    797:     data_reg = *args++;
                    798:     if (opc == 3)
                    799:         data_reg2 = *args++;
                    800:     else
                    801:         data_reg2 = 0;
                    802:     addr_reg = *args++;
1.1.1.6   root      803: 
                    804: #ifdef CONFIG_SOFTMMU
1.1       root      805: #if TARGET_LONG_BITS == 64
                    806:     addr_reg2 = *args++;
                    807: #endif
                    808:     mem_index = *args;
                    809:     r0 = 3;
                    810:     r1 = 4;
                    811:     r2 = 0;
1.1.1.3   root      812:     rbase = 0;
1.1       root      813: 
                    814:     tcg_out32 (s, (RLWINM
                    815:                    | RA (r0)
                    816:                    | RS (addr_reg)
                    817:                    | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
                    818:                    | MB (32 - (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS))
                    819:                    | ME (31 - CPU_TLB_ENTRY_BITS)
                    820:                    )
                    821:         );
                    822:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
                    823:     tcg_out32 (s, (LWZU
                    824:                    | RT (r1)
                    825:                    | RA (r0)
1.1.1.7 ! root      826:                    | offsetof (CPUArchState, tlb_table[mem_index][0].addr_write)
1.1       root      827:                    )
                    828:         );
                    829:     tcg_out32 (s, (RLWINM
                    830:                    | RA (r2)
                    831:                    | RS (addr_reg)
                    832:                    | SH (0)
                    833:                    | MB ((32 - opc) & 31)
                    834:                    | ME (31 - TARGET_PAGE_BITS)
                    835:                    )
                    836:         );
                    837: 
                    838:     tcg_out32 (s, CMP | (7 << 23) | RA (r2) | RB (r1));
                    839: #if TARGET_LONG_BITS == 64
                    840:     tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
                    841:     tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
                    842:     tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
                    843: #endif
                    844: 
                    845:     label1_ptr = s->code_ptr;
                    846: #ifdef FAST_PATH
                    847:     tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
                    848: #endif
                    849: 
                    850:     /* slow path */
1.1.1.7 ! root      851:     ir = 3;
        !           852: #ifdef CONFIG_TCG_PASS_AREG0
        !           853:     tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);
        !           854: #endif
1.1       root      855: #if TARGET_LONG_BITS == 32
1.1.1.7 ! root      856:     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
1.1       root      857: #else
                    858: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1.1.1.7 ! root      859:     ir |= 1;
1.1       root      860: #endif
1.1.1.7 ! root      861:     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg2);
        !           862:     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
1.1       root      863: #endif
                    864: 
                    865:     switch (opc) {
                    866:     case 0:
                    867:         tcg_out32 (s, (RLWINM
                    868:                        | RA (ir)
                    869:                        | RS (data_reg)
                    870:                        | SH (0)
                    871:                        | MB (24)
                    872:                        | ME (31)));
                    873:         break;
                    874:     case 1:
                    875:         tcg_out32 (s, (RLWINM
                    876:                        | RA (ir)
                    877:                        | RS (data_reg)
                    878:                        | SH (0)
                    879:                        | MB (16)
                    880:                        | ME (31)));
                    881:         break;
                    882:     case 2:
1.1.1.4   root      883:         tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
1.1       root      884:         break;
                    885:     case 3:
                    886: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1.1.1.7 ! root      887:         ir |= 1;
1.1       root      888: #endif
1.1.1.4   root      889:         tcg_out_mov (s, TCG_TYPE_I32, ir++, data_reg2);
                    890:         tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
1.1       root      891:         break;
                    892:     }
                    893:     ir++;
                    894: 
                    895:     tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
                    896:     tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
                    897:     label2_ptr = s->code_ptr;
                    898:     tcg_out32 (s, B);
                    899: 
                    900:     /* label1: fast path */
                    901: #ifdef FAST_PATH
                    902:     reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
                    903: #endif
                    904: 
                    905:     tcg_out32 (s, (LWZ
                    906:                    | RT (r0)
                    907:                    | RA (r0)
1.1.1.4   root      908:                    | (offsetof (CPUTLBEntry, addend)
1.1       root      909:                       - offsetof (CPUTLBEntry, addr_write))
                    910:                    ));
                    911:     /* r0 = env->tlb_table[mem_index][index].addend */
                    912:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
                    913:     /* r0 = env->tlb_table[mem_index][index].addend + addr */
                    914: 
                    915: #else  /* !CONFIG_SOFTMMU */
                    916:     r0 = addr_reg;
1.1.1.3   root      917:     r1 = 3;
                    918:     rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1.1       root      919: #endif
                    920: 
                    921: #ifdef TARGET_WORDS_BIGENDIAN
                    922:     bswap = 0;
                    923: #else
                    924:     bswap = 1;
                    925: #endif
                    926:     switch (opc) {
                    927:     case 0:
1.1.1.3   root      928:         tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
1.1       root      929:         break;
                    930:     case 1:
1.1.1.3   root      931:         if (bswap)
                    932:             tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
                    933:         else
                    934:             tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
1.1       root      935:         break;
                    936:     case 2:
1.1.1.3   root      937:         if (bswap)
                    938:             tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
                    939:         else
                    940:             tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
1.1       root      941:         break;
                    942:     case 3:
                    943:         if (bswap) {
                    944:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
1.1.1.3   root      945:             tcg_out32 (s, STWBRX | SAB (data_reg,  rbase, r0));
                    946:             tcg_out32 (s, STWBRX | SAB (data_reg2, rbase, r1));
1.1       root      947:         }
                    948:         else {
1.1.1.3   root      949: #ifdef CONFIG_USE_GUEST_BASE
                    950:             tcg_out32 (s, STWX | SAB (data_reg2, rbase, r0));
                    951:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
                    952:             tcg_out32 (s, STWX | SAB (data_reg,  rbase, r1));
                    953: #else
1.1       root      954:             tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
                    955:             tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
1.1.1.3   root      956: #endif
1.1       root      957:         }
                    958:         break;
                    959:     }
                    960: 
                    961: #ifdef CONFIG_SOFTMMU
                    962:     reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
                    963: #endif
                    964: }
                    965: 
1.1.1.4   root      966: static void tcg_target_qemu_prologue (TCGContext *s)
1.1       root      967: {
                    968:     int i, frame_size;
                    969: 
                    970:     frame_size = 0
                    971:         + LINKAGE_AREA_SIZE
                    972:         + TCG_STATIC_CALL_ARGS_SIZE
                    973:         + ARRAY_SIZE (tcg_target_callee_save_regs) * 4
1.1.1.5   root      974:         + CPU_TEMP_BUF_NLONGS * sizeof(long)
1.1       root      975:         ;
                    976:     frame_size = (frame_size + 15) & ~15;
                    977: 
1.1.1.5   root      978:     tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size
                    979:                   - CPU_TEMP_BUF_NLONGS * sizeof(long),
                    980:                   CPU_TEMP_BUF_NLONGS * sizeof(long));
                    981: 
1.1.1.4   root      982: #ifdef _CALL_AIX
1.1       root      983:     {
                    984:         uint32_t addr;
                    985: 
                    986:         /* First emit adhoc function descriptor */
                    987:         addr = (uint32_t) s->code_ptr + 12;
                    988:         tcg_out32 (s, addr);        /* entry point */
                    989:         s->code_ptr += 8;           /* skip TOC and environment pointer */
                    990:     }
                    991: #endif
                    992:     tcg_out32 (s, MFSPR | RT (0) | LR);
                    993:     tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff));
                    994:     for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
                    995:         tcg_out32 (s, (STW
                    996:                        | RS (tcg_target_callee_save_regs[i])
                    997:                        | RA (1)
                    998:                        | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
                    999:                        )
                   1000:             );
                   1001:     tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
                   1002: 
1.1.1.3   root     1003: #ifdef CONFIG_USE_GUEST_BASE
1.1.1.4   root     1004:     if (GUEST_BASE) {
                   1005:         tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
                   1006:         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
                   1007:     }
1.1.1.3   root     1008: #endif
                   1009: 
1.1.1.5   root     1010:     tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
                   1011:     tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
1.1       root     1012:     tcg_out32 (s, BCCTR | BO_ALWAYS);
                   1013:     tb_ret_addr = s->code_ptr;
                   1014: 
                   1015:     for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
                   1016:         tcg_out32 (s, (LWZ
                   1017:                        | RT (tcg_target_callee_save_regs[i])
                   1018:                        | RA (1)
                   1019:                        | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
                   1020:                        )
                   1021:             );
                   1022:     tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + LR_OFFSET));
                   1023:     tcg_out32 (s, MTSPR | RS (0) | LR);
                   1024:     tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
                   1025:     tcg_out32 (s, BCLR | BO_ALWAYS);
                   1026: }
                   1027: 
1.1.1.6   root     1028: static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
1.1       root     1029:                         tcg_target_long arg2)
                   1030: {
                   1031:     tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
                   1032: }
                   1033: 
1.1.1.6   root     1034: static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
1.1       root     1035:                         tcg_target_long arg2)
                   1036: {
                   1037:     tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
                   1038: }
                   1039: 
                   1040: static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
                   1041: {
                   1042:     if (!si && rt == ra)
                   1043:         return;
                   1044: 
                   1045:     if (si == (int16_t) si)
                   1046:         tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
                   1047:     else {
                   1048:         uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
                   1049:         tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
                   1050:         tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
                   1051:     }
                   1052: }
                   1053: 
                   1054: static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
                   1055:                          int const_arg2, int cr)
                   1056: {
                   1057:     int imm;
                   1058:     uint32_t op;
                   1059: 
                   1060:     switch (cond) {
                   1061:     case TCG_COND_EQ:
                   1062:     case TCG_COND_NE:
                   1063:         if (const_arg2) {
                   1064:             if ((int16_t) arg2 == arg2) {
                   1065:                 op = CMPI;
                   1066:                 imm = 1;
                   1067:                 break;
                   1068:             }
                   1069:             else if ((uint16_t) arg2 == arg2) {
                   1070:                 op = CMPLI;
                   1071:                 imm = 1;
                   1072:                 break;
                   1073:             }
                   1074:         }
                   1075:         op = CMPL;
                   1076:         imm = 0;
                   1077:         break;
                   1078: 
                   1079:     case TCG_COND_LT:
                   1080:     case TCG_COND_GE:
                   1081:     case TCG_COND_LE:
                   1082:     case TCG_COND_GT:
                   1083:         if (const_arg2) {
                   1084:             if ((int16_t) arg2 == arg2) {
                   1085:                 op = CMPI;
                   1086:                 imm = 1;
                   1087:                 break;
                   1088:             }
                   1089:         }
                   1090:         op = CMP;
                   1091:         imm = 0;
                   1092:         break;
                   1093: 
                   1094:     case TCG_COND_LTU:
                   1095:     case TCG_COND_GEU:
                   1096:     case TCG_COND_LEU:
                   1097:     case TCG_COND_GTU:
                   1098:         if (const_arg2) {
                   1099:             if ((uint16_t) arg2 == arg2) {
                   1100:                 op = CMPLI;
                   1101:                 imm = 1;
                   1102:                 break;
                   1103:             }
                   1104:         }
                   1105:         op = CMPL;
                   1106:         imm = 0;
                   1107:         break;
                   1108: 
                   1109:     default:
                   1110:         tcg_abort ();
                   1111:     }
                   1112:     op |= BF (cr);
                   1113: 
                   1114:     if (imm)
                   1115:         tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
                   1116:     else {
                   1117:         if (const_arg2) {
                   1118:             tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
                   1119:             tcg_out32 (s, op | RA (arg1) | RB (0));
                   1120:         }
                   1121:         else
                   1122:             tcg_out32 (s, op | RA (arg1) | RB (arg2));
                   1123:     }
                   1124: 
                   1125: }
                   1126: 
                   1127: static void tcg_out_bc (TCGContext *s, int bc, int label_index)
                   1128: {
                   1129:     TCGLabel *l = &s->labels[label_index];
                   1130: 
                   1131:     if (l->has_value)
                   1132:         tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
                   1133:     else {
                   1134:         uint16_t val = *(uint16_t *) &s->code_ptr[2];
                   1135: 
                   1136:         /* Thanks to Andrzej Zaborowski */
                   1137:         tcg_out32 (s, bc | (val & 0xfffc));
                   1138:         tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
                   1139:     }
                   1140: }
                   1141: 
1.1.1.4   root     1142: static void tcg_out_cr7eq_from_cond (TCGContext *s, const TCGArg *args,
                   1143:                                      const int *const_args)
1.1       root     1144: {
1.1.1.4   root     1145:     TCGCond cond = args[4];
                   1146:     int op;
1.1       root     1147:     struct { int bit1; int bit2; int cond2; } bits[] = {
                   1148:         [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT  },
                   1149:         [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT  },
                   1150:         [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT  },
                   1151:         [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT  },
                   1152:         [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU },
                   1153:         [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU },
                   1154:         [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU },
                   1155:         [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU },
                   1156:     }, *b = &bits[cond];
                   1157: 
                   1158:     switch (cond) {
                   1159:     case TCG_COND_EQ:
                   1160:     case TCG_COND_NE:
                   1161:         op = (cond == TCG_COND_EQ) ? CRAND : CRNAND;
                   1162:         tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 6);
                   1163:         tcg_out_cmp (s, cond, args[1], args[3], const_args[3], 7);
                   1164:         tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
                   1165:         break;
                   1166:     case TCG_COND_LT:
                   1167:     case TCG_COND_LE:
                   1168:     case TCG_COND_GT:
                   1169:     case TCG_COND_GE:
                   1170:     case TCG_COND_LTU:
                   1171:     case TCG_COND_LEU:
                   1172:     case TCG_COND_GTU:
                   1173:     case TCG_COND_GEU:
                   1174:         op = (b->bit1 != b->bit2) ? CRANDC : CRAND;
                   1175:         tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5);
1.1.1.4   root     1176:         tcg_out_cmp (s, tcg_unsigned_cond (cond), args[0], args[2],
                   1177:                      const_args[2], 7);
                   1178:         tcg_out32 (s, op | BT (7, CR_EQ) | BA (5, CR_EQ) | BB (7, b->bit2));
1.1       root     1179:         tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ));
                   1180:         break;
                   1181:     default:
                   1182:         tcg_abort();
                   1183:     }
1.1.1.4   root     1184: }
                   1185: 
                   1186: static void tcg_out_setcond (TCGContext *s, TCGCond cond, TCGArg arg0,
                   1187:                              TCGArg arg1, TCGArg arg2, int const_arg2)
                   1188: {
                   1189:     int crop, sh, arg;
                   1190: 
                   1191:     switch (cond) {
                   1192:     case TCG_COND_EQ:
                   1193:         if (const_arg2) {
                   1194:             if (!arg2) {
                   1195:                 arg = arg1;
                   1196:             }
                   1197:             else {
                   1198:                 arg = 0;
                   1199:                 if ((uint16_t) arg2 == arg2) {
                   1200:                     tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
                   1201:                 }
                   1202:                 else {
                   1203:                     tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
                   1204:                     tcg_out32 (s, XOR | SAB (arg1, 0, 0));
                   1205:                 }
                   1206:             }
                   1207:         }
                   1208:         else {
                   1209:             arg = 0;
                   1210:             tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
                   1211:         }
                   1212:         tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
                   1213:         tcg_out32 (s, (RLWINM
                   1214:                        | RA (arg0)
                   1215:                        | RS (0)
                   1216:                        | SH (27)
                   1217:                        | MB (5)
                   1218:                        | ME (31)
                   1219:                        )
                   1220:             );
                   1221:         break;
                   1222: 
                   1223:     case TCG_COND_NE:
                   1224:         if (const_arg2) {
                   1225:             if (!arg2) {
                   1226:                 arg = arg1;
                   1227:             }
                   1228:             else {
                   1229:                 arg = 0;
                   1230:                 if ((uint16_t) arg2 == arg2) {
                   1231:                     tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
                   1232:                 }
                   1233:                 else {
                   1234:                     tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
                   1235:                     tcg_out32 (s, XOR | SAB (arg1, 0, 0));
                   1236:                 }
                   1237:             }
                   1238:         }
                   1239:         else {
                   1240:             arg = 0;
                   1241:             tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
                   1242:         }
                   1243: 
                   1244:         if (arg == arg1 && arg1 == arg0) {
                   1245:             tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
                   1246:             tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
                   1247:         }
                   1248:         else {
                   1249:             tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
                   1250:             tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
                   1251:         }
                   1252:         break;
                   1253: 
                   1254:     case TCG_COND_GT:
                   1255:     case TCG_COND_GTU:
                   1256:         sh = 30;
                   1257:         crop = 0;
                   1258:         goto crtest;
                   1259: 
                   1260:     case TCG_COND_LT:
                   1261:     case TCG_COND_LTU:
                   1262:         sh = 29;
                   1263:         crop = 0;
                   1264:         goto crtest;
                   1265: 
                   1266:     case TCG_COND_GE:
                   1267:     case TCG_COND_GEU:
                   1268:         sh = 31;
                   1269:         crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
                   1270:         goto crtest;
                   1271: 
                   1272:     case TCG_COND_LE:
                   1273:     case TCG_COND_LEU:
                   1274:         sh = 31;
                   1275:         crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
                   1276:     crtest:
                   1277:         tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
                   1278:         if (crop) tcg_out32 (s, crop);
                   1279:         tcg_out32 (s, MFCR | RT (0));
                   1280:         tcg_out32 (s, (RLWINM
                   1281:                        | RA (arg0)
                   1282:                        | RS (0)
                   1283:                        | SH (sh)
                   1284:                        | MB (31)
                   1285:                        | ME (31)
                   1286:                        )
                   1287:             );
                   1288:         break;
                   1289: 
                   1290:     default:
                   1291:         tcg_abort ();
                   1292:     }
                   1293: }
                   1294: 
                   1295: static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
                   1296:                               const int *const_args)
                   1297: {
                   1298:     tcg_out_cr7eq_from_cond (s, args + 1, const_args + 1);
                   1299:     tcg_out32 (s, MFCR | RT (0));
                   1300:     tcg_out32 (s, (RLWINM
                   1301:                    | RA (args[0])
                   1302:                    | RS (0)
                   1303:                    | SH (31)
                   1304:                    | MB (31)
                   1305:                    | ME (31)
                   1306:                    )
                   1307:         );
                   1308: }
                   1309: 
                   1310: static void tcg_out_brcond (TCGContext *s, TCGCond cond,
                   1311:                             TCGArg arg1, TCGArg arg2, int const_arg2,
                   1312:                             int label_index)
                   1313: {
                   1314:     tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
                   1315:     tcg_out_bc (s, tcg_to_bc[cond], label_index);
                   1316: }
1.1       root     1317: 
1.1.1.4   root     1318: /* XXX: we implement it at the target level to avoid having to
                   1319:    handle cross basic blocks temporaries */
                   1320: static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
                   1321:                              const int *const_args)
                   1322: {
                   1323:     tcg_out_cr7eq_from_cond (s, args, const_args);
                   1324:     tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), args[5]);
1.1       root     1325: }
                   1326: 
                   1327: void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
                   1328: {
                   1329:     uint32_t *ptr;
                   1330:     long disp = addr - jmp_addr;
                   1331:     unsigned long patch_size;
                   1332: 
                   1333:     ptr = (uint32_t *)jmp_addr;
                   1334: 
                   1335:     if ((disp << 6) >> 6 != disp) {
                   1336:         ptr[0] = 0x3c000000 | (addr >> 16);    /* lis 0,addr@ha */
                   1337:         ptr[1] = 0x60000000 | (addr & 0xffff); /* la  0,addr@l(0) */
                   1338:         ptr[2] = 0x7c0903a6;                   /* mtctr 0 */
                   1339:         ptr[3] = 0x4e800420;                   /* brctr */
                   1340:         patch_size = 16;
                   1341:     } else {
                   1342:         /* patch the branch destination */
                   1343:         if (disp != 16) {
                   1344:             *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */
                   1345:             patch_size = 4;
                   1346:         } else {
                   1347:             ptr[0] = 0x60000000; /* nop */
                   1348:             ptr[1] = 0x60000000;
                   1349:             ptr[2] = 0x60000000;
                   1350:             ptr[3] = 0x60000000;
                   1351:             patch_size = 16;
                   1352:         }
                   1353:     }
                   1354:     /* flush icache */
                   1355:     flush_icache_range(jmp_addr, jmp_addr + patch_size);
                   1356: }
                   1357: 
1.1.1.4   root     1358: static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1.1       root     1359:                        const int *const_args)
                   1360: {
                   1361:     switch (opc) {
                   1362:     case INDEX_op_exit_tb:
                   1363:         tcg_out_movi (s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
                   1364:         tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
                   1365:         break;
                   1366:     case INDEX_op_goto_tb:
                   1367:         if (s->tb_jmp_offset) {
                   1368:             /* direct jump method */
                   1369: 
                   1370:             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
                   1371:             s->code_ptr += 16;
                   1372:         }
                   1373:         else {
                   1374:             tcg_abort ();
                   1375:         }
                   1376:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                   1377:         break;
                   1378:     case INDEX_op_br:
                   1379:         {
                   1380:             TCGLabel *l = &s->labels[args[0]];
                   1381: 
                   1382:             if (l->has_value) {
                   1383:                 tcg_out_b (s, 0, l->u.value);
                   1384:             }
                   1385:             else {
                   1386:                 uint32_t val = *(uint32_t *) s->code_ptr;
                   1387: 
                   1388:                 /* Thanks to Andrzej Zaborowski */
                   1389:                 tcg_out32 (s, B | (val & 0x3fffffc));
                   1390:                 tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
                   1391:             }
                   1392:         }
                   1393:         break;
                   1394:     case INDEX_op_call:
                   1395:         tcg_out_call (s, args[0], const_args[0]);
                   1396:         break;
                   1397:     case INDEX_op_jmp:
                   1398:         if (const_args[0]) {
                   1399:             tcg_out_b (s, 0, args[0]);
                   1400:         }
                   1401:         else {
                   1402:             tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
                   1403:             tcg_out32 (s, BCCTR | BO_ALWAYS);
                   1404:         }
                   1405:         break;
                   1406:     case INDEX_op_movi_i32:
                   1407:         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
                   1408:         break;
                   1409:     case INDEX_op_ld8u_i32:
                   1410:         tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
                   1411:         break;
                   1412:     case INDEX_op_ld8s_i32:
                   1413:         tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
                   1414:         tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
                   1415:         break;
                   1416:     case INDEX_op_ld16u_i32:
                   1417:         tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
                   1418:         break;
                   1419:     case INDEX_op_ld16s_i32:
                   1420:         tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
                   1421:         break;
                   1422:     case INDEX_op_ld_i32:
                   1423:         tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
                   1424:         break;
                   1425:     case INDEX_op_st8_i32:
                   1426:         tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
                   1427:         break;
                   1428:     case INDEX_op_st16_i32:
                   1429:         tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
                   1430:         break;
                   1431:     case INDEX_op_st_i32:
                   1432:         tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
                   1433:         break;
                   1434: 
                   1435:     case INDEX_op_add_i32:
                   1436:         if (const_args[2])
                   1437:             ppc_addi (s, args[0], args[1], args[2]);
                   1438:         else
                   1439:             tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
                   1440:         break;
                   1441:     case INDEX_op_sub_i32:
                   1442:         if (const_args[2])
                   1443:             ppc_addi (s, args[0], args[1], -args[2]);
                   1444:         else
                   1445:             tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
                   1446:         break;
                   1447: 
                   1448:     case INDEX_op_and_i32:
                   1449:         if (const_args[2]) {
1.1.1.3   root     1450:             uint32_t c;
                   1451: 
                   1452:             c = args[2];
                   1453: 
                   1454:             if (!c) {
                   1455:                 tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
                   1456:                 break;
                   1457:             }
                   1458: #ifdef __PPU__
                   1459:             uint32_t t, n;
                   1460:             int mb, me;
                   1461: 
                   1462:             n = c ^ -(c & 1);
                   1463:             t = n + (n & -n);
                   1464: 
                   1465:             if ((t & (t - 1)) == 0) {
                   1466:                 int lzc, tzc;
                   1467: 
                   1468:                 if ((c & 0x80000001) == 0x80000001) {
                   1469:                     lzc = clz32 (n);
                   1470:                     tzc = ctz32 (n);
                   1471: 
                   1472:                     mb = 32 - tzc;
                   1473:                     me = lzc - 1;
                   1474:                 }
                   1475:                 else {
                   1476:                     lzc = clz32 (c);
                   1477:                     tzc = ctz32 (c);
                   1478: 
                   1479:                     mb = lzc;
                   1480:                     me = 31 - tzc;
                   1481:                 }
                   1482: 
                   1483:                 tcg_out32 (s, (RLWINM
                   1484:                                | RA (args[0])
                   1485:                                | RS (args[1])
                   1486:                                | SH (0)
                   1487:                                | MB (mb)
                   1488:                                | ME (me)
                   1489:                                )
                   1490:                     );
                   1491:             }
                   1492:             else
                   1493: #endif /* !__PPU__ */
                   1494:             {
                   1495:                 if ((c & 0xffff) == c)
                   1496:                     tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | c);
                   1497:                 else if ((c & 0xffff0000) == c)
                   1498:                     tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
                   1499:                                | ((c >> 16) & 0xffff));
                   1500:                 else {
                   1501:                     tcg_out_movi (s, TCG_TYPE_I32, 0, c);
                   1502:                     tcg_out32 (s, AND | SAB (args[1], args[0], 0));
                   1503:                 }
1.1       root     1504:             }
                   1505:         }
                   1506:         else
                   1507:             tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
                   1508:         break;
                   1509:     case INDEX_op_or_i32:
                   1510:         if (const_args[2]) {
                   1511:             if (args[2] & 0xffff) {
                   1512:                 tcg_out32 (s, ORI | RS (args[1])  | RA (args[0])
                   1513:                            | (args[2] & 0xffff));
                   1514:                 if (args[2] >> 16)
                   1515:                     tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
                   1516:                                | ((args[2] >> 16) & 0xffff));
                   1517:             }
                   1518:             else {
                   1519:                 tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
                   1520:                            | ((args[2] >> 16) & 0xffff));
                   1521:             }
                   1522:         }
                   1523:         else
                   1524:             tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
                   1525:         break;
                   1526:     case INDEX_op_xor_i32:
                   1527:         if (const_args[2]) {
                   1528:             if ((args[2] & 0xffff) == args[2])
                   1529:                 tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
                   1530:                            | (args[2] & 0xffff));
                   1531:             else if ((args[2] & 0xffff0000) == args[2])
                   1532:                 tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
                   1533:                            | ((args[2] >> 16) & 0xffff));
                   1534:             else {
                   1535:                 tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
                   1536:                 tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
                   1537:             }
                   1538:         }
                   1539:         else
                   1540:             tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
                   1541:         break;
1.1.1.4   root     1542:     case INDEX_op_andc_i32:
                   1543:         tcg_out32 (s, ANDC | SAB (args[1], args[0], args[2]));
                   1544:         break;
                   1545:     case INDEX_op_orc_i32:
                   1546:         tcg_out32 (s, ORC | SAB (args[1], args[0], args[2]));
                   1547:         break;
                   1548:     case INDEX_op_eqv_i32:
                   1549:         tcg_out32 (s, EQV | SAB (args[1], args[0], args[2]));
                   1550:         break;
                   1551:     case INDEX_op_nand_i32:
                   1552:         tcg_out32 (s, NAND | SAB (args[1], args[0], args[2]));
                   1553:         break;
                   1554:     case INDEX_op_nor_i32:
                   1555:         tcg_out32 (s, NOR | SAB (args[1], args[0], args[2]));
                   1556:         break;
1.1       root     1557: 
                   1558:     case INDEX_op_mul_i32:
                   1559:         if (const_args[2]) {
                   1560:             if (args[2] == (int16_t) args[2])
                   1561:                 tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
                   1562:                            | (args[2] & 0xffff));
                   1563:             else {
                   1564:                 tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
                   1565:                 tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
                   1566:             }
                   1567:         }
                   1568:         else
                   1569:             tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
                   1570:         break;
                   1571: 
                   1572:     case INDEX_op_div_i32:
                   1573:         tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
                   1574:         break;
                   1575: 
                   1576:     case INDEX_op_divu_i32:
                   1577:         tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
                   1578:         break;
                   1579: 
                   1580:     case INDEX_op_rem_i32:
                   1581:         tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
                   1582:         tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
                   1583:         tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
                   1584:         break;
                   1585: 
                   1586:     case INDEX_op_remu_i32:
                   1587:         tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
                   1588:         tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
                   1589:         tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
                   1590:         break;
                   1591: 
                   1592:     case INDEX_op_mulu2_i32:
                   1593:         if (args[0] == args[2] || args[0] == args[3]) {
                   1594:             tcg_out32 (s, MULLW | TAB (0, args[2], args[3]));
                   1595:             tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
1.1.1.4   root     1596:             tcg_out_mov (s, TCG_TYPE_I32, args[0], 0);
1.1       root     1597:         }
                   1598:         else {
                   1599:             tcg_out32 (s, MULLW | TAB (args[0], args[2], args[3]));
                   1600:             tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
                   1601:         }
                   1602:         break;
                   1603: 
                   1604:     case INDEX_op_shl_i32:
                   1605:         if (const_args[2]) {
                   1606:             tcg_out32 (s, (RLWINM
                   1607:                            | RA (args[0])
                   1608:                            | RS (args[1])
                   1609:                            | SH (args[2])
                   1610:                            | MB (0)
                   1611:                            | ME (31 - args[2])
                   1612:                            )
                   1613:                 );
                   1614:         }
                   1615:         else
                   1616:             tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
                   1617:         break;
                   1618:     case INDEX_op_shr_i32:
                   1619:         if (const_args[2]) {
                   1620:             tcg_out32 (s, (RLWINM
                   1621:                            | RA (args[0])
                   1622:                            | RS (args[1])
                   1623:                            | SH (32 - args[2])
                   1624:                            | MB (args[2])
                   1625:                            | ME (31)
                   1626:                            )
                   1627:                 );
                   1628:         }
                   1629:         else
                   1630:             tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
                   1631:         break;
                   1632:     case INDEX_op_sar_i32:
                   1633:         if (const_args[2])
                   1634:             tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
                   1635:         else
                   1636:             tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
                   1637:         break;
1.1.1.4   root     1638:     case INDEX_op_rotl_i32:
                   1639:         {
                   1640:             int op = 0
                   1641:                 | RA (args[0])
                   1642:                 | RS (args[1])
                   1643:                 | MB (0)
                   1644:                 | ME (31)
                   1645:                 | (const_args[2] ? RLWINM | SH (args[2])
                   1646:                                  : RLWNM | RB (args[2]))
                   1647:                 ;
                   1648:             tcg_out32 (s, op);
                   1649:         }
                   1650:         break;
                   1651:     case INDEX_op_rotr_i32:
                   1652:         if (const_args[2]) {
                   1653:             if (!args[2]) {
                   1654:                 tcg_out_mov (s, TCG_TYPE_I32, args[0], args[1]);
                   1655:             }
                   1656:             else {
                   1657:                 tcg_out32 (s, RLWINM
                   1658:                            | RA (args[0])
                   1659:                            | RS (args[1])
                   1660:                            | SH (32 - args[2])
                   1661:                            | MB (0)
                   1662:                            | ME (31)
                   1663:                     );
                   1664:             }
                   1665:         }
                   1666:         else {
                   1667:             tcg_out32 (s, SUBFIC | RT (0) | RA (args[2]) | 32);
                   1668:             tcg_out32 (s, RLWNM
                   1669:                        | RA (args[0])
                   1670:                        | RS (args[1])
                   1671:                        | RB (0)
                   1672:                        | MB (0)
                   1673:                        | ME (31)
                   1674:                 );
                   1675:         }
                   1676:         break;
1.1       root     1677: 
                   1678:     case INDEX_op_add2_i32:
                   1679:         if (args[0] == args[3] || args[0] == args[5]) {
                   1680:             tcg_out32 (s, ADDC | TAB (0, args[2], args[4]));
                   1681:             tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
1.1.1.4   root     1682:             tcg_out_mov (s, TCG_TYPE_I32, args[0], 0);
1.1       root     1683:         }
                   1684:         else {
                   1685:             tcg_out32 (s, ADDC | TAB (args[0], args[2], args[4]));
                   1686:             tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
                   1687:         }
                   1688:         break;
                   1689:     case INDEX_op_sub2_i32:
                   1690:         if (args[0] == args[3] || args[0] == args[5]) {
                   1691:             tcg_out32 (s, SUBFC | TAB (0, args[4], args[2]));
                   1692:             tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
1.1.1.4   root     1693:             tcg_out_mov (s, TCG_TYPE_I32, args[0], 0);
1.1       root     1694:         }
                   1695:         else {
                   1696:             tcg_out32 (s, SUBFC | TAB (args[0], args[4], args[2]));
                   1697:             tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
                   1698:         }
                   1699:         break;
                   1700: 
                   1701:     case INDEX_op_brcond_i32:
                   1702:         /*
                   1703:           args[0] = r0
                   1704:           args[1] = r1
                   1705:           args[2] = cond
                   1706:           args[3] = r1 is const
                   1707:           args[4] = label_index
                   1708:         */
                   1709:         tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3]);
                   1710:         break;
                   1711:     case INDEX_op_brcond2_i32:
                   1712:         tcg_out_brcond2(s, args, const_args);
                   1713:         break;
                   1714: 
                   1715:     case INDEX_op_neg_i32:
                   1716:         tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
                   1717:         break;
                   1718: 
1.1.1.4   root     1719:     case INDEX_op_not_i32:
                   1720:         tcg_out32 (s, NOR | SAB (args[1], args[0], args[1]));
                   1721:         break;
                   1722: 
1.1       root     1723:     case INDEX_op_qemu_ld8u:
                   1724:         tcg_out_qemu_ld(s, args, 0);
                   1725:         break;
                   1726:     case INDEX_op_qemu_ld8s:
                   1727:         tcg_out_qemu_ld(s, args, 0 | 4);
                   1728:         break;
                   1729:     case INDEX_op_qemu_ld16u:
                   1730:         tcg_out_qemu_ld(s, args, 1);
                   1731:         break;
                   1732:     case INDEX_op_qemu_ld16s:
                   1733:         tcg_out_qemu_ld(s, args, 1 | 4);
                   1734:         break;
1.1.1.4   root     1735:     case INDEX_op_qemu_ld32:
1.1       root     1736:         tcg_out_qemu_ld(s, args, 2);
                   1737:         break;
                   1738:     case INDEX_op_qemu_ld64:
                   1739:         tcg_out_qemu_ld(s, args, 3);
                   1740:         break;
                   1741:     case INDEX_op_qemu_st8:
                   1742:         tcg_out_qemu_st(s, args, 0);
                   1743:         break;
                   1744:     case INDEX_op_qemu_st16:
                   1745:         tcg_out_qemu_st(s, args, 1);
                   1746:         break;
                   1747:     case INDEX_op_qemu_st32:
                   1748:         tcg_out_qemu_st(s, args, 2);
                   1749:         break;
                   1750:     case INDEX_op_qemu_st64:
                   1751:         tcg_out_qemu_st(s, args, 3);
                   1752:         break;
                   1753: 
                   1754:     case INDEX_op_ext8s_i32:
                   1755:         tcg_out32 (s, EXTSB | RS (args[1]) | RA (args[0]));
                   1756:         break;
1.1.1.4   root     1757:     case INDEX_op_ext8u_i32:
                   1758:         tcg_out32 (s, RLWINM
                   1759:                    | RA (args[0])
                   1760:                    | RS (args[1])
                   1761:                    | SH (0)
                   1762:                    | MB (24)
                   1763:                    | ME (31)
                   1764:             );
                   1765:         break;
1.1       root     1766:     case INDEX_op_ext16s_i32:
                   1767:         tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
                   1768:         break;
1.1.1.4   root     1769:     case INDEX_op_ext16u_i32:
                   1770:         tcg_out32 (s, RLWINM
                   1771:                    | RA (args[0])
                   1772:                    | RS (args[1])
                   1773:                    | SH (0)
                   1774:                    | MB (16)
                   1775:                    | ME (31)
                   1776:             );
                   1777:         break;
                   1778: 
                   1779:     case INDEX_op_setcond_i32:
                   1780:         tcg_out_setcond (s, args[3], args[0], args[1], args[2], const_args[2]);
                   1781:         break;
                   1782:     case INDEX_op_setcond2_i32:
                   1783:         tcg_out_setcond2 (s, args, const_args);
                   1784:         break;
                   1785: 
                   1786:     case INDEX_op_bswap16_i32:
                   1787:         /* Stolen from gcc's builtin_bswap16 */
                   1788: 
                   1789:         /* a1 = abcd */
                   1790: 
                   1791:         /* r0 = (a1 << 8) & 0xff00 # 00d0 */
                   1792:         tcg_out32 (s, RLWINM
                   1793:                    | RA (0)
                   1794:                    | RS (args[1])
                   1795:                    | SH (8)
                   1796:                    | MB (16)
                   1797:                    | ME (23)
                   1798:             );
                   1799: 
                   1800:         /* a0 = rotate_left (a1, 24) & 0xff # 000c */
                   1801:         tcg_out32 (s, RLWINM
                   1802:                    | RA (args[0])
                   1803:                    | RS (args[1])
                   1804:                    | SH (24)
                   1805:                    | MB (24)
                   1806:                    | ME (31)
                   1807:             );
                   1808: 
                   1809:         /* a0 = a0 | r0 # 00dc */
                   1810:         tcg_out32 (s, OR | SAB (0, args[0], args[0]));
                   1811:         break;
                   1812: 
                   1813:     case INDEX_op_bswap32_i32:
                   1814:         /* Stolen from gcc's builtin_bswap32 */
                   1815:         {
                   1816:             int a0 = args[0];
                   1817: 
                   1818:             /* a1 = args[1] # abcd */
                   1819: 
                   1820:             if (a0 == args[1]) {
                   1821:                 a0 = 0;
                   1822:             }
                   1823: 
                   1824:             /* a0 = rotate_left (a1, 8) # bcda */
                   1825:             tcg_out32 (s, RLWINM
                   1826:                        | RA (a0)
                   1827:                        | RS (args[1])
                   1828:                        | SH (8)
                   1829:                        | MB (0)
                   1830:                        | ME (31)
                   1831:                 );
                   1832: 
                   1833:             /* a0 = (a0 & ~0xff000000) | ((a1 << 24) & 0xff000000) # dcda */
                   1834:             tcg_out32 (s, RLWIMI
                   1835:                        | RA (a0)
                   1836:                        | RS (args[1])
                   1837:                        | SH (24)
                   1838:                        | MB (0)
                   1839:                        | ME (7)
                   1840:                 );
                   1841: 
                   1842:             /* a0 = (a0 & ~0x0000ff00) | ((a1 << 24) & 0x0000ff00) # dcba */
                   1843:             tcg_out32 (s, RLWIMI
                   1844:                        | RA (a0)
                   1845:                        | RS (args[1])
                   1846:                        | SH (24)
                   1847:                        | MB (16)
                   1848:                        | ME (23)
                   1849:                 );
                   1850: 
                   1851:             if (!a0) {
                   1852:                 tcg_out_mov (s, TCG_TYPE_I32, args[0], a0);
                   1853:             }
                   1854:         }
                   1855:         break;
1.1       root     1856: 
1.1.1.6   root     1857:     case INDEX_op_deposit_i32:
                   1858:         tcg_out32 (s, RLWIMI
                   1859:                    | RA (args[0])
                   1860:                    | RS (args[2])
                   1861:                    | SH (args[3])
                   1862:                    | MB (32 - args[3] - args[4])
                   1863:                    | ME (31 - args[3])
                   1864:             );
                   1865:         break;
                   1866: 
1.1       root     1867:     default:
                   1868:         tcg_dump_ops (s, stderr);
                   1869:         tcg_abort ();
                   1870:     }
                   1871: }
                   1872: 
                   1873: static const TCGTargetOpDef ppc_op_defs[] = {
                   1874:     { INDEX_op_exit_tb, { } },
                   1875:     { INDEX_op_goto_tb, { } },
                   1876:     { INDEX_op_call, { "ri" } },
                   1877:     { INDEX_op_jmp, { "ri" } },
                   1878:     { INDEX_op_br, { } },
                   1879: 
                   1880:     { INDEX_op_mov_i32, { "r", "r" } },
                   1881:     { INDEX_op_movi_i32, { "r" } },
                   1882:     { INDEX_op_ld8u_i32, { "r", "r" } },
                   1883:     { INDEX_op_ld8s_i32, { "r", "r" } },
                   1884:     { INDEX_op_ld16u_i32, { "r", "r" } },
                   1885:     { INDEX_op_ld16s_i32, { "r", "r" } },
                   1886:     { INDEX_op_ld_i32, { "r", "r" } },
                   1887:     { INDEX_op_st8_i32, { "r", "r" } },
                   1888:     { INDEX_op_st16_i32, { "r", "r" } },
                   1889:     { INDEX_op_st_i32, { "r", "r" } },
                   1890: 
                   1891:     { INDEX_op_add_i32, { "r", "r", "ri" } },
                   1892:     { INDEX_op_mul_i32, { "r", "r", "ri" } },
                   1893:     { INDEX_op_div_i32, { "r", "r", "r" } },
                   1894:     { INDEX_op_divu_i32, { "r", "r", "r" } },
                   1895:     { INDEX_op_rem_i32, { "r", "r", "r" } },
                   1896:     { INDEX_op_remu_i32, { "r", "r", "r" } },
                   1897:     { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
                   1898:     { INDEX_op_sub_i32, { "r", "r", "ri" } },
                   1899:     { INDEX_op_and_i32, { "r", "r", "ri" } },
                   1900:     { INDEX_op_or_i32, { "r", "r", "ri" } },
                   1901:     { INDEX_op_xor_i32, { "r", "r", "ri" } },
                   1902: 
                   1903:     { INDEX_op_shl_i32, { "r", "r", "ri" } },
                   1904:     { INDEX_op_shr_i32, { "r", "r", "ri" } },
                   1905:     { INDEX_op_sar_i32, { "r", "r", "ri" } },
                   1906: 
1.1.1.4   root     1907:     { INDEX_op_rotl_i32, { "r", "r", "ri" } },
                   1908:     { INDEX_op_rotr_i32, { "r", "r", "ri" } },
                   1909: 
1.1       root     1910:     { INDEX_op_brcond_i32, { "r", "ri" } },
                   1911: 
                   1912:     { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
                   1913:     { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
                   1914:     { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
                   1915: 
                   1916:     { INDEX_op_neg_i32, { "r", "r" } },
1.1.1.4   root     1917:     { INDEX_op_not_i32, { "r", "r" } },
                   1918: 
                   1919:     { INDEX_op_andc_i32, { "r", "r", "r" } },
                   1920:     { INDEX_op_orc_i32, { "r", "r", "r" } },
                   1921:     { INDEX_op_eqv_i32, { "r", "r", "r" } },
                   1922:     { INDEX_op_nand_i32, { "r", "r", "r" } },
                   1923:     { INDEX_op_nor_i32, { "r", "r", "r" } },
                   1924: 
                   1925:     { INDEX_op_setcond_i32, { "r", "r", "ri" } },
                   1926:     { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
                   1927: 
                   1928:     { INDEX_op_bswap16_i32, { "r", "r" } },
                   1929:     { INDEX_op_bswap32_i32, { "r", "r" } },
1.1       root     1930: 
                   1931: #if TARGET_LONG_BITS == 32
                   1932:     { INDEX_op_qemu_ld8u, { "r", "L" } },
                   1933:     { INDEX_op_qemu_ld8s, { "r", "L" } },
                   1934:     { INDEX_op_qemu_ld16u, { "r", "L" } },
                   1935:     { INDEX_op_qemu_ld16s, { "r", "L" } },
1.1.1.4   root     1936:     { INDEX_op_qemu_ld32, { "r", "L" } },
1.1       root     1937:     { INDEX_op_qemu_ld64, { "r", "r", "L" } },
                   1938: 
                   1939:     { INDEX_op_qemu_st8, { "K", "K" } },
                   1940:     { INDEX_op_qemu_st16, { "K", "K" } },
                   1941:     { INDEX_op_qemu_st32, { "K", "K" } },
                   1942:     { INDEX_op_qemu_st64, { "M", "M", "M" } },
                   1943: #else
                   1944:     { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
                   1945:     { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
                   1946:     { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
                   1947:     { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1.1.1.4   root     1948:     { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1.1       root     1949:     { INDEX_op_qemu_ld64, { "r", "L", "L", "L" } },
                   1950: 
                   1951:     { INDEX_op_qemu_st8, { "K", "K", "K" } },
                   1952:     { INDEX_op_qemu_st16, { "K", "K", "K" } },
                   1953:     { INDEX_op_qemu_st32, { "K", "K", "K" } },
                   1954:     { INDEX_op_qemu_st64, { "M", "M", "M", "M" } },
                   1955: #endif
                   1956: 
                   1957:     { INDEX_op_ext8s_i32, { "r", "r" } },
1.1.1.4   root     1958:     { INDEX_op_ext8u_i32, { "r", "r" } },
1.1       root     1959:     { INDEX_op_ext16s_i32, { "r", "r" } },
1.1.1.4   root     1960:     { INDEX_op_ext16u_i32, { "r", "r" } },
1.1       root     1961: 
1.1.1.6   root     1962:     { INDEX_op_deposit_i32, { "r", "0", "r" } },
                   1963: 
1.1       root     1964:     { -1 },
                   1965: };
                   1966: 
1.1.1.4   root     1967: static void tcg_target_init(TCGContext *s)
1.1       root     1968: {
                   1969:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
                   1970:     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
                   1971:                      (1 << TCG_REG_R0) |
1.1.1.7 ! root     1972: #ifdef TCG_TARGET_CALL_DARWIN
1.1       root     1973:                      (1 << TCG_REG_R2) |
                   1974: #endif
                   1975:                      (1 << TCG_REG_R3) |
                   1976:                      (1 << TCG_REG_R4) |
                   1977:                      (1 << TCG_REG_R5) |
                   1978:                      (1 << TCG_REG_R6) |
                   1979:                      (1 << TCG_REG_R7) |
                   1980:                      (1 << TCG_REG_R8) |
                   1981:                      (1 << TCG_REG_R9) |
                   1982:                      (1 << TCG_REG_R10) |
                   1983:                      (1 << TCG_REG_R11) |
                   1984:                      (1 << TCG_REG_R12)
                   1985:         );
                   1986: 
                   1987:     tcg_regset_clear(s->reserved_regs);
                   1988:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
                   1989:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
1.1.1.7 ! root     1990: #ifndef TCG_TARGET_CALL_DARWIN
1.1       root     1991:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
                   1992: #endif
1.1.1.4   root     1993: #ifdef _CALL_SYSV
1.1       root     1994:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
                   1995: #endif
                   1996: 
                   1997:     tcg_add_target_add_op_defs(ppc_op_defs);
                   1998: }

unix.superglobalmegacorp.com

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