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