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