Annotation of qemu/tcg/ppc64/tcg-target.c, revision 1.1.1.8

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

unix.superglobalmegacorp.com