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

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

unix.superglobalmegacorp.com

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