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

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,
1.1.1.5 ! root      163:     TCG_REG_R27, /* currently used for the global env */
1.1       root      164:     TCG_REG_R28,
                    165:     TCG_REG_R29,
                    166:     TCG_REG_R30,
                    167:     TCG_REG_R31
                    168: };
                    169: 
                    170: static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
                    171: {
                    172:     tcg_target_long disp;
                    173: 
                    174:     disp = target - (tcg_target_long) pc;
                    175:     if ((disp << 6) >> 6 != disp)
                    176:         tcg_abort ();
                    177: 
                    178:     return disp & 0x3fffffc;
                    179: }
                    180: 
                    181: static void reloc_pc24 (void *pc, tcg_target_long target)
                    182: {
                    183:     *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
                    184:         | reloc_pc24_val (pc, target);
                    185: }
                    186: 
                    187: static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
                    188: {
                    189:     tcg_target_long disp;
                    190: 
                    191:     disp = target - (tcg_target_long) pc;
                    192:     if (disp != (int16_t) disp)
                    193:         tcg_abort ();
                    194: 
                    195:     return disp & 0xfffc;
                    196: }
                    197: 
                    198: static void reloc_pc14 (void *pc, tcg_target_long target)
                    199: {
                    200:     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
                    201:         | reloc_pc14_val (pc, target);
                    202: }
                    203: 
                    204: static void patch_reloc(uint8_t *code_ptr, int type,
                    205:                         tcg_target_long value, tcg_target_long addend)
                    206: {
                    207:     value += addend;
                    208:     switch (type) {
                    209:     case R_PPC_REL14:
                    210:         reloc_pc14 (code_ptr, value);
                    211:         break;
                    212:     case R_PPC_REL24:
                    213:         reloc_pc24 (code_ptr, value);
                    214:         break;
                    215:     default:
                    216:         tcg_abort();
                    217:     }
                    218: }
                    219: 
                    220: /* maximum number of register used for input function arguments */
                    221: static int tcg_target_get_call_iarg_regs_count(int flags)
                    222: {
                    223:     return ARRAY_SIZE (tcg_target_call_iarg_regs);
                    224: }
                    225: 
                    226: /* parse target specific constraints */
                    227: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    228: {
                    229:     const char *ct_str;
                    230: 
                    231:     ct_str = *pct_str;
                    232:     switch (ct_str[0]) {
                    233:     case 'A': case 'B': case 'C': case 'D':
                    234:         ct->ct |= TCG_CT_REG;
                    235:         tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
                    236:         break;
                    237:     case 'r':
                    238:         ct->ct |= TCG_CT_REG;
                    239:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    240:         break;
                    241: #ifdef CONFIG_SOFTMMU
                    242:     case 'L':                   /* qemu_ld constraint */
                    243:         ct->ct |= TCG_CT_REG;
                    244:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    245:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    246:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
                    247:         break;
                    248:     case 'K':                   /* qemu_st[8..32] constraint */
                    249:         ct->ct |= TCG_CT_REG;
                    250:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    251:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    252:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
                    253:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
                    254: #if TARGET_LONG_BITS == 64
                    255:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
                    256: #endif
                    257:         break;
                    258:     case 'M':                   /* qemu_st64 constraint */
                    259:         ct->ct |= TCG_CT_REG;
                    260:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    261:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    262:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
                    263:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
                    264:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
                    265:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
                    266:         break;
                    267: #else
                    268:     case 'L':
                    269:     case 'K':
                    270:         ct->ct |= TCG_CT_REG;
                    271:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    272:         break;
                    273:     case 'M':
                    274:         ct->ct |= TCG_CT_REG;
                    275:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    276:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
                    277:         break;
                    278: #endif
                    279:     default:
                    280:         return -1;
                    281:     }
                    282:     ct_str++;
                    283:     *pct_str = ct_str;
                    284:     return 0;
                    285: }
                    286: 
                    287: /* test if a constant matches the constraint */
                    288: static int tcg_target_const_match(tcg_target_long val,
                    289:                                   const TCGArgConstraint *arg_ct)
                    290: {
                    291:     int ct;
                    292: 
                    293:     ct = arg_ct->ct;
                    294:     if (ct & TCG_CT_CONST)
                    295:         return 1;
                    296:     return 0;
                    297: }
                    298: 
                    299: #define OPCD(opc) ((opc)<<26)
                    300: #define XO31(opc) (OPCD(31)|((opc)<<1))
                    301: #define XO19(opc) (OPCD(19)|((opc)<<1))
                    302: 
                    303: #define B      OPCD(18)
                    304: #define BC     OPCD(16)
                    305: #define LBZ    OPCD(34)
                    306: #define LHZ    OPCD(40)
                    307: #define LHA    OPCD(42)
                    308: #define LWZ    OPCD(32)
                    309: #define STB    OPCD(38)
                    310: #define STH    OPCD(44)
                    311: #define STW    OPCD(36)
                    312: 
1.1.1.4   root      313: #define ADDIC  OPCD(12)
1.1       root      314: #define ADDI   OPCD(14)
                    315: #define ADDIS  OPCD(15)
                    316: #define ORI    OPCD(24)
                    317: #define ORIS   OPCD(25)
                    318: #define XORI   OPCD(26)
                    319: #define XORIS  OPCD(27)
                    320: #define ANDI   OPCD(28)
                    321: #define ANDIS  OPCD(29)
                    322: #define MULLI  OPCD( 7)
                    323: #define CMPLI  OPCD(10)
                    324: #define CMPI   OPCD(11)
1.1.1.4   root      325: #define SUBFIC OPCD( 8)
1.1       root      326: 
                    327: #define LWZU   OPCD(33)
                    328: #define STWU   OPCD(37)
                    329: 
1.1.1.4   root      330: #define RLWIMI OPCD(20)
1.1       root      331: #define RLWINM OPCD(21)
1.1.1.4   root      332: #define RLWNM  OPCD(23)
1.1       root      333: 
                    334: #define BCLR   XO19( 16)
                    335: #define BCCTR  XO19(528)
                    336: #define CRAND  XO19(257)
                    337: #define CRANDC XO19(129)
                    338: #define CRNAND XO19(225)
                    339: #define CROR   XO19(449)
1.1.1.4   root      340: #define CRNOR  XO19( 33)
1.1       root      341: 
                    342: #define EXTSB  XO31(954)
                    343: #define EXTSH  XO31(922)
                    344: #define ADD    XO31(266)
                    345: #define ADDE   XO31(138)
                    346: #define ADDC   XO31( 10)
                    347: #define AND    XO31( 28)
                    348: #define SUBF   XO31( 40)
                    349: #define SUBFC  XO31(  8)
                    350: #define SUBFE  XO31(136)
                    351: #define OR     XO31(444)
                    352: #define XOR    XO31(316)
                    353: #define MULLW  XO31(235)
                    354: #define MULHWU XO31( 11)
                    355: #define DIVW   XO31(491)
                    356: #define DIVWU  XO31(459)
                    357: #define CMP    XO31(  0)
                    358: #define CMPL   XO31( 32)
                    359: #define LHBRX  XO31(790)
                    360: #define LWBRX  XO31(534)
                    361: #define STHBRX XO31(918)
                    362: #define STWBRX XO31(662)
                    363: #define MFSPR  XO31(339)
                    364: #define MTSPR  XO31(467)
                    365: #define SRAWI  XO31(824)
                    366: #define NEG    XO31(104)
1.1.1.4   root      367: #define MFCR   XO31( 19)
                    368: #define CNTLZW XO31( 26)
                    369: #define NOR    XO31(124)
                    370: #define ANDC   XO31( 60)
                    371: #define ORC    XO31(412)
                    372: #define EQV    XO31(284)
                    373: #define NAND   XO31(476)
1.1       root      374: 
                    375: #define LBZX   XO31( 87)
1.1.1.3   root      376: #define LHZX   XO31(279)
1.1       root      377: #define LHAX   XO31(343)
                    378: #define LWZX   XO31( 23)
                    379: #define STBX   XO31(215)
                    380: #define STHX   XO31(407)
                    381: #define STWX   XO31(151)
                    382: 
                    383: #define SPR(a,b) ((((a)<<5)|(b))<<11)
                    384: #define LR     SPR(8, 0)
                    385: #define CTR    SPR(9, 0)
                    386: 
                    387: #define SLW    XO31( 24)
                    388: #define SRW    XO31(536)
                    389: #define SRAW   XO31(792)
                    390: 
                    391: #define TW     XO31(4)
                    392: #define TRAP   (TW | TO (31))
                    393: 
                    394: #define RT(r) ((r)<<21)
                    395: #define RS(r) ((r)<<21)
                    396: #define RA(r) ((r)<<16)
                    397: #define RB(r) ((r)<<11)
                    398: #define TO(t) ((t)<<21)
                    399: #define SH(s) ((s)<<11)
                    400: #define MB(b) ((b)<<6)
                    401: #define ME(e) ((e)<<1)
                    402: #define BO(o) ((o)<<21)
                    403: 
                    404: #define LK    1
                    405: 
                    406: #define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
                    407: #define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
                    408: 
                    409: #define BF(n)    ((n)<<23)
                    410: #define BI(n, c) (((c)+((n)*4))<<16)
                    411: #define BT(n, c) (((c)+((n)*4))<<21)
                    412: #define BA(n, c) (((c)+((n)*4))<<16)
                    413: #define BB(n, c) (((c)+((n)*4))<<11)
                    414: 
                    415: #define BO_COND_TRUE  BO (12)
                    416: #define BO_COND_FALSE BO (4)
                    417: #define BO_ALWAYS     BO (20)
                    418: 
                    419: enum {
                    420:     CR_LT,
                    421:     CR_GT,
                    422:     CR_EQ,
                    423:     CR_SO
                    424: };
                    425: 
                    426: static const uint32_t tcg_to_bc[10] = {
                    427:     [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
                    428:     [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
                    429:     [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
                    430:     [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
                    431:     [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
                    432:     [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
                    433:     [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
                    434:     [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
                    435:     [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
                    436:     [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
                    437: };
                    438: 
1.1.1.4   root      439: static void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
1.1       root      440: {
                    441:     tcg_out32 (s, OR | SAB (arg, ret, arg));
                    442: }
                    443: 
                    444: static void tcg_out_movi(TCGContext *s, TCGType type,
                    445:                          int ret, tcg_target_long arg)
                    446: {
                    447:     if (arg == (int16_t) arg)
                    448:         tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
                    449:     else {
                    450:         tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
                    451:         if (arg & 0xffff)
                    452:             tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
                    453:     }
                    454: }
                    455: 
                    456: static void tcg_out_ldst (TCGContext *s, int ret, int addr,
                    457:                           int offset, int op1, int op2)
                    458: {
                    459:     if (offset == (int16_t) offset)
                    460:         tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
                    461:     else {
                    462:         tcg_out_movi (s, TCG_TYPE_I32, 0, offset);
                    463:         tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
                    464:     }
                    465: }
                    466: 
                    467: static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
                    468: {
                    469:     tcg_target_long disp;
                    470: 
                    471:     disp = target - (tcg_target_long) s->code_ptr;
                    472:     if ((disp << 6) >> 6 == disp)
                    473:         tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
                    474:     else {
                    475:         tcg_out_movi (s, TCG_TYPE_I32, 0, (tcg_target_long) target);
                    476:         tcg_out32 (s, MTSPR | RS (0) | CTR);
                    477:         tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
                    478:     }
                    479: }
                    480: 
                    481: static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
                    482: {
1.1.1.4   root      483: #ifdef _CALL_AIX
1.1       root      484:     int reg;
                    485: 
                    486:     if (const_arg) {
                    487:         reg = 2;
                    488:         tcg_out_movi (s, TCG_TYPE_I32, reg, arg);
                    489:     }
                    490:     else reg = arg;
                    491: 
                    492:     tcg_out32 (s, LWZ | RT (0) | RA (reg));
                    493:     tcg_out32 (s, MTSPR | RA (0) | CTR);
                    494:     tcg_out32 (s, LWZ | RT (2) | RA (reg) | 4);
                    495:     tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
1.1.1.3   root      496: #else
                    497:     if (const_arg) {
                    498:         tcg_out_b (s, LK, arg);
                    499:     }
                    500:     else {
                    501:         tcg_out32 (s, MTSPR | RS (arg) | LR);
                    502:         tcg_out32 (s, BCLR | BO_ALWAYS | LK);
                    503:     }
1.1       root      504: #endif
1.1.1.3   root      505: }
1.1       root      506: 
                    507: #if defined(CONFIG_SOFTMMU)
                    508: 
                    509: #include "../../softmmu_defs.h"
                    510: 
                    511: static void *qemu_ld_helpers[4] = {
                    512:     __ldb_mmu,
                    513:     __ldw_mmu,
                    514:     __ldl_mmu,
                    515:     __ldq_mmu,
                    516: };
                    517: 
                    518: static void *qemu_st_helpers[4] = {
                    519:     __stb_mmu,
                    520:     __stw_mmu,
                    521:     __stl_mmu,
                    522:     __stq_mmu,
                    523: };
                    524: #endif
                    525: 
                    526: static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
                    527: {
1.1.1.3   root      528:     int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
1.1       root      529: #ifdef CONFIG_SOFTMMU
                    530:     int r2;
                    531:     void *label1_ptr, *label2_ptr;
                    532: #endif
                    533: #if TARGET_LONG_BITS == 64
                    534:     int addr_reg2;
                    535: #endif
                    536: 
                    537:     data_reg = *args++;
                    538:     if (opc == 3)
                    539:         data_reg2 = *args++;
                    540:     else
                    541:         data_reg2 = 0;
                    542:     addr_reg = *args++;
                    543: #if TARGET_LONG_BITS == 64
                    544:     addr_reg2 = *args++;
                    545: #endif
                    546:     mem_index = *args;
                    547:     s_bits = opc & 3;
                    548: 
                    549: #ifdef CONFIG_SOFTMMU
                    550:     r0 = 3;
                    551:     r1 = 4;
                    552:     r2 = 0;
1.1.1.3   root      553:     rbase = 0;
1.1       root      554: 
                    555:     tcg_out32 (s, (RLWINM
                    556:                    | RA (r0)
                    557:                    | RS (addr_reg)
                    558:                    | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
                    559:                    | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
                    560:                    | ME (31 - CPU_TLB_ENTRY_BITS)
                    561:                    )
                    562:         );
                    563:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
                    564:     tcg_out32 (s, (LWZU
                    565:                    | RT (r1)
                    566:                    | RA (r0)
                    567:                    | offsetof (CPUState, tlb_table[mem_index][0].addr_read)
                    568:                    )
                    569:         );
                    570:     tcg_out32 (s, (RLWINM
                    571:                    | RA (r2)
                    572:                    | RS (addr_reg)
                    573:                    | SH (0)
                    574:                    | MB ((32 - s_bits) & 31)
                    575:                    | ME (31 - TARGET_PAGE_BITS)
                    576:                    )
                    577:         );
                    578: 
                    579:     tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
                    580: #if TARGET_LONG_BITS == 64
                    581:     tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
                    582:     tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
                    583:     tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
                    584: #endif
                    585: 
                    586:     label1_ptr = s->code_ptr;
                    587: #ifdef FAST_PATH
                    588:     tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
                    589: #endif
                    590: 
                    591:     /* slow path */
                    592: #if TARGET_LONG_BITS == 32
1.1.1.4   root      593:     tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg);
1.1       root      594:     tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);
                    595: #else
1.1.1.4   root      596:     tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
                    597:     tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
1.1       root      598:     tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
                    599: #endif
                    600: 
                    601:     tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
                    602:     switch (opc) {
                    603:     case 0|4:
                    604:         tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
                    605:         break;
                    606:     case 1|4:
                    607:         tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
                    608:         break;
                    609:     case 0:
                    610:     case 1:
                    611:     case 2:
                    612:         if (data_reg != 3)
1.1.1.4   root      613:             tcg_out_mov (s, TCG_TYPE_I32, data_reg, 3);
1.1       root      614:         break;
                    615:     case 3:
                    616:         if (data_reg == 3) {
                    617:             if (data_reg2 == 4) {
1.1.1.4   root      618:                 tcg_out_mov (s, TCG_TYPE_I32, 0, 4);
                    619:                 tcg_out_mov (s, TCG_TYPE_I32, 4, 3);
                    620:                 tcg_out_mov (s, TCG_TYPE_I32, 3, 0);
1.1       root      621:             }
                    622:             else {
1.1.1.4   root      623:                 tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 3);
                    624:                 tcg_out_mov (s, TCG_TYPE_I32, 3, 4);
1.1       root      625:             }
                    626:         }
                    627:         else {
1.1.1.4   root      628:             if (data_reg != 4) tcg_out_mov (s, TCG_TYPE_I32, data_reg, 4);
                    629:             if (data_reg2 != 3) tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 3);
1.1       root      630:         }
                    631:         break;
                    632:     }
                    633:     label2_ptr = s->code_ptr;
                    634:     tcg_out32 (s, B);
                    635: 
                    636:     /* label1: fast path */
                    637: #ifdef FAST_PATH
                    638:     reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
                    639: #endif
                    640: 
                    641:     /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
                    642:     tcg_out32 (s, (LWZ
                    643:                    | RT (r0)
                    644:                    | RA (r0)
1.1.1.4   root      645:                    | (offsetof (CPUTLBEntry, addend)
1.1       root      646:                       - offsetof (CPUTLBEntry, addr_read))
                    647:                    ));
                    648:     /* r0 = env->tlb_table[mem_index][index].addend */
                    649:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
                    650:     /* r0 = env->tlb_table[mem_index][index].addend + addr */
                    651: 
                    652: #else  /* !CONFIG_SOFTMMU */
                    653:     r0 = addr_reg;
                    654:     r1 = 3;
1.1.1.3   root      655:     rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1.1       root      656: #endif
                    657: 
                    658: #ifdef TARGET_WORDS_BIGENDIAN
                    659:     bswap = 0;
                    660: #else
                    661:     bswap = 1;
                    662: #endif
1.1.1.3   root      663: 
1.1       root      664:     switch (opc) {
                    665:     default:
                    666:     case 0:
1.1.1.3   root      667:         tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
1.1       root      668:         break;
                    669:     case 0|4:
1.1.1.3   root      670:         tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
1.1       root      671:         tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
                    672:         break;
                    673:     case 1:
1.1.1.3   root      674:         if (bswap)
                    675:             tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
                    676:         else
                    677:             tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
1.1       root      678:         break;
                    679:     case 1|4:
                    680:         if (bswap) {
1.1.1.3   root      681:             tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
1.1       root      682:             tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
                    683:         }
1.1.1.3   root      684:         else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
1.1       root      685:         break;
                    686:     case 2:
1.1.1.3   root      687:         if (bswap)
                    688:             tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
                    689:         else
                    690:             tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
1.1       root      691:         break;
                    692:     case 3:
                    693:         if (bswap) {
1.1.1.3   root      694:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
                    695:             tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
                    696:             tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));
1.1       root      697:         }
                    698:         else {
1.1.1.3   root      699: #ifdef CONFIG_USE_GUEST_BASE
                    700:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
                    701:             tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));
                    702:             tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));
                    703: #else
1.1       root      704:             if (r0 == data_reg2) {
                    705:                 tcg_out32 (s, LWZ | RT (0) | RA (r0));
                    706:                 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
1.1.1.4   root      707:                 tcg_out_mov (s, TCG_TYPE_I32, data_reg2, 0);
1.1       root      708:             }
                    709:             else {
                    710:                 tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
                    711:                 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
                    712:             }
1.1.1.3   root      713: #endif
1.1       root      714:         }
                    715:         break;
                    716:     }
                    717: 
                    718: #ifdef CONFIG_SOFTMMU
                    719:     reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
                    720: #endif
                    721: }
                    722: 
                    723: static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
                    724: {
1.1.1.3   root      725:     int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
1.1       root      726: #ifdef CONFIG_SOFTMMU
                    727:     int r2, ir;
                    728:     void *label1_ptr, *label2_ptr;
                    729: #endif
                    730: #if TARGET_LONG_BITS == 64
                    731:     int addr_reg2;
                    732: #endif
                    733: 
                    734:     data_reg = *args++;
                    735:     if (opc == 3)
                    736:         data_reg2 = *args++;
                    737:     else
                    738:         data_reg2 = 0;
                    739:     addr_reg = *args++;
                    740: #if TARGET_LONG_BITS == 64
                    741:     addr_reg2 = *args++;
                    742: #endif
                    743:     mem_index = *args;
                    744: 
                    745: #ifdef CONFIG_SOFTMMU
                    746:     r0 = 3;
                    747:     r1 = 4;
                    748:     r2 = 0;
1.1.1.3   root      749:     rbase = 0;
1.1       root      750: 
                    751:     tcg_out32 (s, (RLWINM
                    752:                    | RA (r0)
                    753:                    | RS (addr_reg)
                    754:                    | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
                    755:                    | MB (32 - (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS))
                    756:                    | ME (31 - CPU_TLB_ENTRY_BITS)
                    757:                    )
                    758:         );
                    759:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
                    760:     tcg_out32 (s, (LWZU
                    761:                    | RT (r1)
                    762:                    | RA (r0)
                    763:                    | offsetof (CPUState, tlb_table[mem_index][0].addr_write)
                    764:                    )
                    765:         );
                    766:     tcg_out32 (s, (RLWINM
                    767:                    | RA (r2)
                    768:                    | RS (addr_reg)
                    769:                    | SH (0)
                    770:                    | MB ((32 - opc) & 31)
                    771:                    | ME (31 - TARGET_PAGE_BITS)
                    772:                    )
                    773:         );
                    774: 
                    775:     tcg_out32 (s, CMP | (7 << 23) | RA (r2) | RB (r1));
                    776: #if TARGET_LONG_BITS == 64
                    777:     tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
                    778:     tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
                    779:     tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
                    780: #endif
                    781: 
                    782:     label1_ptr = s->code_ptr;
                    783: #ifdef FAST_PATH
                    784:     tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
                    785: #endif
                    786: 
                    787:     /* slow path */
                    788: #if TARGET_LONG_BITS == 32
1.1.1.4   root      789:     tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg);
1.1       root      790:     ir = 4;
                    791: #else
1.1.1.4   root      792:     tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
                    793:     tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
1.1       root      794: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
                    795:     ir = 5;
                    796: #else
                    797:     ir = 4;
                    798: #endif
                    799: #endif
                    800: 
                    801:     switch (opc) {
                    802:     case 0:
                    803:         tcg_out32 (s, (RLWINM
                    804:                        | RA (ir)
                    805:                        | RS (data_reg)
                    806:                        | SH (0)
                    807:                        | MB (24)
                    808:                        | ME (31)));
                    809:         break;
                    810:     case 1:
                    811:         tcg_out32 (s, (RLWINM
                    812:                        | RA (ir)
                    813:                        | RS (data_reg)
                    814:                        | SH (0)
                    815:                        | MB (16)
                    816:                        | ME (31)));
                    817:         break;
                    818:     case 2:
1.1.1.4   root      819:         tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
1.1       root      820:         break;
                    821:     case 3:
                    822: #ifdef TCG_TARGET_CALL_ALIGN_ARGS
                    823:         ir = 5;
                    824: #endif
1.1.1.4   root      825:         tcg_out_mov (s, TCG_TYPE_I32, ir++, data_reg2);
                    826:         tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
1.1       root      827:         break;
                    828:     }
                    829:     ir++;
                    830: 
                    831:     tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
                    832:     tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
                    833:     label2_ptr = s->code_ptr;
                    834:     tcg_out32 (s, B);
                    835: 
                    836:     /* label1: fast path */
                    837: #ifdef FAST_PATH
                    838:     reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
                    839: #endif
                    840: 
                    841:     tcg_out32 (s, (LWZ
                    842:                    | RT (r0)
                    843:                    | RA (r0)
1.1.1.4   root      844:                    | (offsetof (CPUTLBEntry, addend)
1.1       root      845:                       - offsetof (CPUTLBEntry, addr_write))
                    846:                    ));
                    847:     /* r0 = env->tlb_table[mem_index][index].addend */
                    848:     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
                    849:     /* r0 = env->tlb_table[mem_index][index].addend + addr */
                    850: 
                    851: #else  /* !CONFIG_SOFTMMU */
                    852:     r0 = addr_reg;
1.1.1.3   root      853:     r1 = 3;
                    854:     rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1.1       root      855: #endif
                    856: 
                    857: #ifdef TARGET_WORDS_BIGENDIAN
                    858:     bswap = 0;
                    859: #else
                    860:     bswap = 1;
                    861: #endif
                    862:     switch (opc) {
                    863:     case 0:
1.1.1.3   root      864:         tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
1.1       root      865:         break;
                    866:     case 1:
1.1.1.3   root      867:         if (bswap)
                    868:             tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
                    869:         else
                    870:             tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
1.1       root      871:         break;
                    872:     case 2:
1.1.1.3   root      873:         if (bswap)
                    874:             tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
                    875:         else
                    876:             tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
1.1       root      877:         break;
                    878:     case 3:
                    879:         if (bswap) {
                    880:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
1.1.1.3   root      881:             tcg_out32 (s, STWBRX | SAB (data_reg,  rbase, r0));
                    882:             tcg_out32 (s, STWBRX | SAB (data_reg2, rbase, r1));
1.1       root      883:         }
                    884:         else {
1.1.1.3   root      885: #ifdef CONFIG_USE_GUEST_BASE
                    886:             tcg_out32 (s, STWX | SAB (data_reg2, rbase, r0));
                    887:             tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
                    888:             tcg_out32 (s, STWX | SAB (data_reg,  rbase, r1));
                    889: #else
1.1       root      890:             tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
                    891:             tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
1.1.1.3   root      892: #endif
1.1       root      893:         }
                    894:         break;
                    895:     }
                    896: 
                    897: #ifdef CONFIG_SOFTMMU
                    898:     reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
                    899: #endif
                    900: }
                    901: 
1.1.1.4   root      902: static void tcg_target_qemu_prologue (TCGContext *s)
1.1       root      903: {
                    904:     int i, frame_size;
                    905: 
                    906:     frame_size = 0
                    907:         + LINKAGE_AREA_SIZE
                    908:         + TCG_STATIC_CALL_ARGS_SIZE
                    909:         + ARRAY_SIZE (tcg_target_callee_save_regs) * 4
1.1.1.5 ! root      910:         + CPU_TEMP_BUF_NLONGS * sizeof(long)
1.1       root      911:         ;
                    912:     frame_size = (frame_size + 15) & ~15;
                    913: 
1.1.1.5 ! root      914:     tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size
        !           915:                   - CPU_TEMP_BUF_NLONGS * sizeof(long),
        !           916:                   CPU_TEMP_BUF_NLONGS * sizeof(long));
        !           917: 
1.1.1.4   root      918: #ifdef _CALL_AIX
1.1       root      919:     {
                    920:         uint32_t addr;
                    921: 
                    922:         /* First emit adhoc function descriptor */
                    923:         addr = (uint32_t) s->code_ptr + 12;
                    924:         tcg_out32 (s, addr);        /* entry point */
                    925:         s->code_ptr += 8;           /* skip TOC and environment pointer */
                    926:     }
                    927: #endif
                    928:     tcg_out32 (s, MFSPR | RT (0) | LR);
                    929:     tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff));
                    930:     for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
                    931:         tcg_out32 (s, (STW
                    932:                        | RS (tcg_target_callee_save_regs[i])
                    933:                        | RA (1)
                    934:                        | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
                    935:                        )
                    936:             );
                    937:     tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
                    938: 
1.1.1.3   root      939: #ifdef CONFIG_USE_GUEST_BASE
1.1.1.4   root      940:     if (GUEST_BASE) {
                    941:         tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
                    942:         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
                    943:     }
1.1.1.3   root      944: #endif
                    945: 
1.1.1.5 ! root      946:     tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
        !           947:     tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
1.1       root      948:     tcg_out32 (s, BCCTR | BO_ALWAYS);
                    949:     tb_ret_addr = s->code_ptr;
                    950: 
                    951:     for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
                    952:         tcg_out32 (s, (LWZ
                    953:                        | RT (tcg_target_callee_save_regs[i])
                    954:                        | RA (1)
                    955:                        | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
                    956:                        )
                    957:             );
                    958:     tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + LR_OFFSET));
                    959:     tcg_out32 (s, MTSPR | RS (0) | LR);
                    960:     tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
                    961:     tcg_out32 (s, BCLR | BO_ALWAYS);
                    962: }
                    963: 
                    964: static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
                    965:                         tcg_target_long arg2)
                    966: {
                    967:     tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
                    968: }
                    969: 
                    970: static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
                    971:                         tcg_target_long arg2)
                    972: {
                    973:     tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
                    974: }
                    975: 
                    976: static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
                    977: {
                    978:     if (!si && rt == ra)
                    979:         return;
                    980: 
                    981:     if (si == (int16_t) si)
                    982:         tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
                    983:     else {
                    984:         uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
                    985:         tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
                    986:         tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
                    987:     }
                    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.