qemu/tcg/ppc/tcg-target.inc.c
<<
>>
Prefs
   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#include "tcg-be-ldst.h"
  26
  27#if defined _CALL_DARWIN || defined __APPLE__
  28#define TCG_TARGET_CALL_DARWIN
  29#endif
  30#ifdef _CALL_SYSV
  31# define TCG_TARGET_CALL_ALIGN_ARGS   1
  32#endif
  33
  34/* For some memory operations, we need a scratch that isn't R0.  For the AIX
  35   calling convention, we can re-use the TOC register since we'll be reloading
  36   it at every call.  Otherwise R12 will do nicely as neither a call-saved
  37   register nor a parameter register.  */
  38#ifdef _CALL_AIX
  39# define TCG_REG_TMP1   TCG_REG_R2
  40#else
  41# define TCG_REG_TMP1   TCG_REG_R12
  42#endif
  43
  44/* For the 64-bit target, we don't like the 5 insn sequence needed to build
  45   full 64-bit addresses.  Better to have a base register to which we can
  46   apply a 32-bit displacement.
  47
  48   There are generally three items of interest:
  49   (1) helper functions in the main executable,
  50   (2) TranslationBlock data structures,
  51   (3) the return address in the epilogue.
  52
  53   For user-only, we USE_STATIC_CODE_GEN_BUFFER, so the code_gen_buffer
  54   will be inside the main executable, and thus near enough to make a
  55   pointer to the epilogue be within 2GB of all helper functions.
  56
  57   For softmmu, we'll let the kernel choose the address of code_gen_buffer,
  58   and odds are it'll be somewhere close to the main malloc arena, and so
  59   a pointer to the epilogue will be within 2GB of the TranslationBlocks.
  60
  61   For --enable-pie, everything will be kinda near everything else,
  62   somewhere in high memory.
  63
  64   Thus we choose to keep the return address in a call-saved register.  */
  65#define TCG_REG_RA     TCG_REG_R31
  66#define USE_REG_RA     (TCG_TARGET_REG_BITS == 64)
  67
  68/* Shorthand for size of a pointer.  Avoid promotion to unsigned.  */
  69#define SZP  ((int)sizeof(void *))
  70
  71/* Shorthand for size of a register.  */
  72#define SZR  (TCG_TARGET_REG_BITS / 8)
  73
  74#define TCG_CT_CONST_S16  0x100
  75#define TCG_CT_CONST_U16  0x200
  76#define TCG_CT_CONST_S32  0x400
  77#define TCG_CT_CONST_U32  0x800
  78#define TCG_CT_CONST_ZERO 0x1000
  79#define TCG_CT_CONST_MONE 0x2000
  80
  81static tcg_insn_unit *tb_ret_addr;
  82
  83#include "elf.h"
  84static bool have_isa_2_06;
  85#define HAVE_ISA_2_06  have_isa_2_06
  86#define HAVE_ISEL      have_isa_2_06
  87
  88#ifndef CONFIG_SOFTMMU
  89#define TCG_GUEST_BASE_REG 30
  90#endif
  91
  92#ifdef CONFIG_DEBUG_TCG
  93static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
  94    "r0",
  95    "r1",
  96    "r2",
  97    "r3",
  98    "r4",
  99    "r5",
 100    "r6",
 101    "r7",
 102    "r8",
 103    "r9",
 104    "r10",
 105    "r11",
 106    "r12",
 107    "r13",
 108    "r14",
 109    "r15",
 110    "r16",
 111    "r17",
 112    "r18",
 113    "r19",
 114    "r20",
 115    "r21",
 116    "r22",
 117    "r23",
 118    "r24",
 119    "r25",
 120    "r26",
 121    "r27",
 122    "r28",
 123    "r29",
 124    "r30",
 125    "r31"
 126};
 127#endif
 128
 129static const int tcg_target_reg_alloc_order[] = {
 130    TCG_REG_R14,  /* call saved registers */
 131    TCG_REG_R15,
 132    TCG_REG_R16,
 133    TCG_REG_R17,
 134    TCG_REG_R18,
 135    TCG_REG_R19,
 136    TCG_REG_R20,
 137    TCG_REG_R21,
 138    TCG_REG_R22,
 139    TCG_REG_R23,
 140    TCG_REG_R24,
 141    TCG_REG_R25,
 142    TCG_REG_R26,
 143    TCG_REG_R27,
 144    TCG_REG_R28,
 145    TCG_REG_R29,
 146    TCG_REG_R30,
 147    TCG_REG_R31,
 148    TCG_REG_R12,  /* call clobbered, non-arguments */
 149    TCG_REG_R11,
 150    TCG_REG_R2,
 151    TCG_REG_R13,
 152    TCG_REG_R10,  /* call clobbered, arguments */
 153    TCG_REG_R9,
 154    TCG_REG_R8,
 155    TCG_REG_R7,
 156    TCG_REG_R6,
 157    TCG_REG_R5,
 158    TCG_REG_R4,
 159    TCG_REG_R3,
 160};
 161
 162static const int tcg_target_call_iarg_regs[] = {
 163    TCG_REG_R3,
 164    TCG_REG_R4,
 165    TCG_REG_R5,
 166    TCG_REG_R6,
 167    TCG_REG_R7,
 168    TCG_REG_R8,
 169    TCG_REG_R9,
 170    TCG_REG_R10
 171};
 172
 173static const int tcg_target_call_oarg_regs[] = {
 174    TCG_REG_R3,
 175    TCG_REG_R4
 176};
 177
 178static const int tcg_target_callee_save_regs[] = {
 179#ifdef TCG_TARGET_CALL_DARWIN
 180    TCG_REG_R11,
 181#endif
 182    TCG_REG_R14,
 183    TCG_REG_R15,
 184    TCG_REG_R16,
 185    TCG_REG_R17,
 186    TCG_REG_R18,
 187    TCG_REG_R19,
 188    TCG_REG_R20,
 189    TCG_REG_R21,
 190    TCG_REG_R22,
 191    TCG_REG_R23,
 192    TCG_REG_R24,
 193    TCG_REG_R25,
 194    TCG_REG_R26,
 195    TCG_REG_R27, /* currently used for the global env */
 196    TCG_REG_R28,
 197    TCG_REG_R29,
 198    TCG_REG_R30,
 199    TCG_REG_R31
 200};
 201
 202static inline bool in_range_b(tcg_target_long target)
 203{
 204    return target == sextract64(target, 0, 26);
 205}
 206
 207static uint32_t reloc_pc24_val(tcg_insn_unit *pc, tcg_insn_unit *target)
 208{
 209    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
 210    tcg_debug_assert(in_range_b(disp));
 211    return disp & 0x3fffffc;
 212}
 213
 214static void reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
 215{
 216    *pc = (*pc & ~0x3fffffc) | reloc_pc24_val(pc, target);
 217}
 218
 219static uint16_t reloc_pc14_val(tcg_insn_unit *pc, tcg_insn_unit *target)
 220{
 221    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
 222    tcg_debug_assert(disp == (int16_t) disp);
 223    return disp & 0xfffc;
 224}
 225
 226static void reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
 227{
 228    *pc = (*pc & ~0xfffc) | reloc_pc14_val(pc, target);
 229}
 230
 231static inline void tcg_out_b_noaddr(TCGContext *s, int insn)
 232{
 233    unsigned retrans = *s->code_ptr & 0x3fffffc;
 234    tcg_out32(s, insn | retrans);
 235}
 236
 237static inline void tcg_out_bc_noaddr(TCGContext *s, int insn)
 238{
 239    unsigned retrans = *s->code_ptr & 0xfffc;
 240    tcg_out32(s, insn | retrans);
 241}
 242
 243static void patch_reloc(tcg_insn_unit *code_ptr, int type,
 244                        intptr_t value, intptr_t addend)
 245{
 246    tcg_insn_unit *target = (tcg_insn_unit *)value;
 247
 248    tcg_debug_assert(addend == 0);
 249    switch (type) {
 250    case R_PPC_REL14:
 251        reloc_pc14(code_ptr, target);
 252        break;
 253    case R_PPC_REL24:
 254        reloc_pc24(code_ptr, target);
 255        break;
 256    default:
 257        tcg_abort();
 258    }
 259}
 260
 261/* parse target specific constraints */
 262static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 263{
 264    const char *ct_str;
 265
 266    ct_str = *pct_str;
 267    switch (ct_str[0]) {
 268    case 'A': case 'B': case 'C': case 'D':
 269        ct->ct |= TCG_CT_REG;
 270        tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
 271        break;
 272    case 'r':
 273        ct->ct |= TCG_CT_REG;
 274        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
 275        break;
 276    case 'L':                   /* qemu_ld constraint */
 277        ct->ct |= TCG_CT_REG;
 278        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
 279        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
 280#ifdef CONFIG_SOFTMMU
 281        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
 282        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
 283#endif
 284        break;
 285    case 'S':                   /* qemu_st constraint */
 286        ct->ct |= TCG_CT_REG;
 287        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
 288        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
 289#ifdef CONFIG_SOFTMMU
 290        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
 291        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
 292        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
 293#endif
 294        break;
 295    case 'I':
 296        ct->ct |= TCG_CT_CONST_S16;
 297        break;
 298    case 'J':
 299        ct->ct |= TCG_CT_CONST_U16;
 300        break;
 301    case 'M':
 302        ct->ct |= TCG_CT_CONST_MONE;
 303        break;
 304    case 'T':
 305        ct->ct |= TCG_CT_CONST_S32;
 306        break;
 307    case 'U':
 308        ct->ct |= TCG_CT_CONST_U32;
 309        break;
 310    case 'Z':
 311        ct->ct |= TCG_CT_CONST_ZERO;
 312        break;
 313    default:
 314        return -1;
 315    }
 316    ct_str++;
 317    *pct_str = ct_str;
 318    return 0;
 319}
 320
 321/* test if a constant matches the constraint */
 322static int tcg_target_const_match(tcg_target_long val, TCGType type,
 323                                  const TCGArgConstraint *arg_ct)
 324{
 325    int ct = arg_ct->ct;
 326    if (ct & TCG_CT_CONST) {
 327        return 1;
 328    }
 329
 330    /* The only 32-bit constraint we use aside from
 331       TCG_CT_CONST is TCG_CT_CONST_S16.  */
 332    if (type == TCG_TYPE_I32) {
 333        val = (int32_t)val;
 334    }
 335
 336    if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
 337        return 1;
 338    } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
 339        return 1;
 340    } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
 341        return 1;
 342    } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
 343        return 1;
 344    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
 345        return 1;
 346    } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
 347        return 1;
 348    }
 349    return 0;
 350}
 351
 352#define OPCD(opc) ((opc)<<26)
 353#define XO19(opc) (OPCD(19)|((opc)<<1))
 354#define MD30(opc) (OPCD(30)|((opc)<<2))
 355#define MDS30(opc) (OPCD(30)|((opc)<<1))
 356#define XO31(opc) (OPCD(31)|((opc)<<1))
 357#define XO58(opc) (OPCD(58)|(opc))
 358#define XO62(opc) (OPCD(62)|(opc))
 359
 360#define B      OPCD( 18)
 361#define BC     OPCD( 16)
 362#define LBZ    OPCD( 34)
 363#define LHZ    OPCD( 40)
 364#define LHA    OPCD( 42)
 365#define LWZ    OPCD( 32)
 366#define STB    OPCD( 38)
 367#define STH    OPCD( 44)
 368#define STW    OPCD( 36)
 369
 370#define STD    XO62(  0)
 371#define STDU   XO62(  1)
 372#define STDX   XO31(149)
 373
 374#define LD     XO58(  0)
 375#define LDX    XO31( 21)
 376#define LDU    XO58(  1)
 377#define LWA    XO58(  2)
 378#define LWAX   XO31(341)
 379
 380#define ADDIC  OPCD( 12)
 381#define ADDI   OPCD( 14)
 382#define ADDIS  OPCD( 15)
 383#define ORI    OPCD( 24)
 384#define ORIS   OPCD( 25)
 385#define XORI   OPCD( 26)
 386#define XORIS  OPCD( 27)
 387#define ANDI   OPCD( 28)
 388#define ANDIS  OPCD( 29)
 389#define MULLI  OPCD(  7)
 390#define CMPLI  OPCD( 10)
 391#define CMPI   OPCD( 11)
 392#define SUBFIC OPCD( 8)
 393
 394#define LWZU   OPCD( 33)
 395#define STWU   OPCD( 37)
 396
 397#define RLWIMI OPCD( 20)
 398#define RLWINM OPCD( 21)
 399#define RLWNM  OPCD( 23)
 400
 401#define RLDICL MD30(  0)
 402#define RLDICR MD30(  1)
 403#define RLDIMI MD30(  3)
 404#define RLDCL  MDS30( 8)
 405
 406#define BCLR   XO19( 16)
 407#define BCCTR  XO19(528)
 408#define CRAND  XO19(257)
 409#define CRANDC XO19(129)
 410#define CRNAND XO19(225)
 411#define CROR   XO19(449)
 412#define CRNOR  XO19( 33)
 413
 414#define EXTSB  XO31(954)
 415#define EXTSH  XO31(922)
 416#define EXTSW  XO31(986)
 417#define ADD    XO31(266)
 418#define ADDE   XO31(138)
 419#define ADDME  XO31(234)
 420#define ADDZE  XO31(202)
 421#define ADDC   XO31( 10)
 422#define AND    XO31( 28)
 423#define SUBF   XO31( 40)
 424#define SUBFC  XO31(  8)
 425#define SUBFE  XO31(136)
 426#define SUBFME XO31(232)
 427#define SUBFZE XO31(200)
 428#define OR     XO31(444)
 429#define XOR    XO31(316)
 430#define MULLW  XO31(235)
 431#define MULHW  XO31( 75)
 432#define MULHWU XO31( 11)
 433#define DIVW   XO31(491)
 434#define DIVWU  XO31(459)
 435#define CMP    XO31(  0)
 436#define CMPL   XO31( 32)
 437#define LHBRX  XO31(790)
 438#define LWBRX  XO31(534)
 439#define LDBRX  XO31(532)
 440#define STHBRX XO31(918)
 441#define STWBRX XO31(662)
 442#define STDBRX XO31(660)
 443#define MFSPR  XO31(339)
 444#define MTSPR  XO31(467)
 445#define SRAWI  XO31(824)
 446#define NEG    XO31(104)
 447#define MFCR   XO31( 19)
 448#define MFOCRF (MFCR | (1u << 20))
 449#define NOR    XO31(124)
 450#define CNTLZW XO31( 26)
 451#define CNTLZD XO31( 58)
 452#define ANDC   XO31( 60)
 453#define ORC    XO31(412)
 454#define EQV    XO31(284)
 455#define NAND   XO31(476)
 456#define ISEL   XO31( 15)
 457
 458#define MULLD  XO31(233)
 459#define MULHD  XO31( 73)
 460#define MULHDU XO31(  9)
 461#define DIVD   XO31(489)
 462#define DIVDU  XO31(457)
 463
 464#define LBZX   XO31( 87)
 465#define LHZX   XO31(279)
 466#define LHAX   XO31(343)
 467#define LWZX   XO31( 23)
 468#define STBX   XO31(215)
 469#define STHX   XO31(407)
 470#define STWX   XO31(151)
 471
 472#define SPR(a, b) ((((a)<<5)|(b))<<11)
 473#define LR     SPR(8, 0)
 474#define CTR    SPR(9, 0)
 475
 476#define SLW    XO31( 24)
 477#define SRW    XO31(536)
 478#define SRAW   XO31(792)
 479
 480#define SLD    XO31( 27)
 481#define SRD    XO31(539)
 482#define SRAD   XO31(794)
 483#define SRADI  XO31(413<<1)
 484
 485#define TW     XO31( 4)
 486#define TRAP   (TW | TO(31))
 487
 488#define NOP    ORI  /* ori 0,0,0 */
 489
 490#define RT(r) ((r)<<21)
 491#define RS(r) ((r)<<21)
 492#define RA(r) ((r)<<16)
 493#define RB(r) ((r)<<11)
 494#define TO(t) ((t)<<21)
 495#define SH(s) ((s)<<11)
 496#define MB(b) ((b)<<6)
 497#define ME(e) ((e)<<1)
 498#define BO(o) ((o)<<21)
 499#define MB64(b) ((b)<<5)
 500#define FXM(b) (1 << (19 - (b)))
 501
 502#define LK    1
 503
 504#define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
 505#define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
 506#define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
 507#define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
 508
 509#define BF(n)    ((n)<<23)
 510#define BI(n, c) (((c)+((n)*4))<<16)
 511#define BT(n, c) (((c)+((n)*4))<<21)
 512#define BA(n, c) (((c)+((n)*4))<<16)
 513#define BB(n, c) (((c)+((n)*4))<<11)
 514#define BC_(n, c) (((c)+((n)*4))<<6)
 515
 516#define BO_COND_TRUE  BO(12)
 517#define BO_COND_FALSE BO( 4)
 518#define BO_ALWAYS     BO(20)
 519
 520enum {
 521    CR_LT,
 522    CR_GT,
 523    CR_EQ,
 524    CR_SO
 525};
 526
 527static const uint32_t tcg_to_bc[] = {
 528    [TCG_COND_EQ]  = BC | BI(7, CR_EQ) | BO_COND_TRUE,
 529    [TCG_COND_NE]  = BC | BI(7, CR_EQ) | BO_COND_FALSE,
 530    [TCG_COND_LT]  = BC | BI(7, CR_LT) | BO_COND_TRUE,
 531    [TCG_COND_GE]  = BC | BI(7, CR_LT) | BO_COND_FALSE,
 532    [TCG_COND_LE]  = BC | BI(7, CR_GT) | BO_COND_FALSE,
 533    [TCG_COND_GT]  = BC | BI(7, CR_GT) | BO_COND_TRUE,
 534    [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
 535    [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
 536    [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
 537    [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
 538};
 539
 540/* The low bit here is set if the RA and RB fields must be inverted.  */
 541static const uint32_t tcg_to_isel[] = {
 542    [TCG_COND_EQ]  = ISEL | BC_(7, CR_EQ),
 543    [TCG_COND_NE]  = ISEL | BC_(7, CR_EQ) | 1,
 544    [TCG_COND_LT]  = ISEL | BC_(7, CR_LT),
 545    [TCG_COND_GE]  = ISEL | BC_(7, CR_LT) | 1,
 546    [TCG_COND_LE]  = ISEL | BC_(7, CR_GT) | 1,
 547    [TCG_COND_GT]  = ISEL | BC_(7, CR_GT),
 548    [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
 549    [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
 550    [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
 551    [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
 552};
 553
 554static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
 555                             TCGReg base, tcg_target_long offset);
 556
 557static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 558{
 559    tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 560    if (ret != arg) {
 561        tcg_out32(s, OR | SAB(arg, ret, arg));
 562    }
 563}
 564
 565static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
 566                               int sh, int mb)
 567{
 568    tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
 569    sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
 570    mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
 571    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
 572}
 573
 574static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
 575                               int sh, int mb, int me)
 576{
 577    tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
 578}
 579
 580static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
 581{
 582    tcg_out_rld(s, RLDICL, dst, src, 0, 32);
 583}
 584
 585static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
 586{
 587    tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
 588}
 589
 590static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
 591{
 592    tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
 593}
 594
 595static inline void tcg_out_shri32(TCGContext *s, TCGReg dst, TCGReg src, int c)
 596{
 597    tcg_out_rlw(s, RLWINM, dst, src, 32 - c, c, 31);
 598}
 599
 600static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
 601{
 602    tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
 603}
 604
 605static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg)
 606{
 607    if (arg == (int16_t) arg) {
 608        tcg_out32(s, ADDI | TAI(ret, 0, arg));
 609    } else {
 610        tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
 611        if (arg & 0xffff) {
 612            tcg_out32(s, ORI | SAI(ret, ret, arg));
 613        }
 614    }
 615}
 616
 617static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
 618                         tcg_target_long arg)
 619{
 620    tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 621    if (type == TCG_TYPE_I32 || arg == (int32_t)arg) {
 622        tcg_out_movi32(s, ret, arg);
 623    } else if (arg == (uint32_t)arg && !(arg & 0x8000)) {
 624        tcg_out32(s, ADDI | TAI(ret, 0, arg));
 625        tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
 626    } else {
 627        int32_t high;
 628
 629        if (USE_REG_RA) {
 630            intptr_t diff = arg - (intptr_t)tb_ret_addr;
 631            if (diff == (int32_t)diff) {
 632                tcg_out_mem_long(s, ADDI, ADD, ret, TCG_REG_RA, diff);
 633                return;
 634            }
 635        }
 636
 637        high = arg >> 31 >> 1;
 638        tcg_out_movi32(s, ret, high);
 639        if (high) {
 640            tcg_out_shli64(s, ret, ret, 32);
 641        }
 642        if (arg & 0xffff0000) {
 643            tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
 644        }
 645        if (arg & 0xffff) {
 646            tcg_out32(s, ORI | SAI(ret, ret, arg));
 647        }
 648    }
 649}
 650
 651static bool mask_operand(uint32_t c, int *mb, int *me)
 652{
 653    uint32_t lsb, test;
 654
 655    /* Accept a bit pattern like:
 656           0....01....1
 657           1....10....0
 658           0..01..10..0
 659       Keep track of the transitions.  */
 660    if (c == 0 || c == -1) {
 661        return false;
 662    }
 663    test = c;
 664    lsb = test & -test;
 665    test += lsb;
 666    if (test & (test - 1)) {
 667        return false;
 668    }
 669
 670    *me = clz32(lsb);
 671    *mb = test ? clz32(test & -test) + 1 : 0;
 672    return true;
 673}
 674
 675static bool mask64_operand(uint64_t c, int *mb, int *me)
 676{
 677    uint64_t lsb;
 678
 679    if (c == 0) {
 680        return false;
 681    }
 682
 683    lsb = c & -c;
 684    /* Accept 1..10..0.  */
 685    if (c == -lsb) {
 686        *mb = 0;
 687        *me = clz64(lsb);
 688        return true;
 689    }
 690    /* Accept 0..01..1.  */
 691    if (lsb == 1 && (c & (c + 1)) == 0) {
 692        *mb = clz64(c + 1) + 1;
 693        *me = 63;
 694        return true;
 695    }
 696    return false;
 697}
 698
 699static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
 700{
 701    int mb, me;
 702
 703    if (mask_operand(c, &mb, &me)) {
 704        tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
 705    } else if ((c & 0xffff) == c) {
 706        tcg_out32(s, ANDI | SAI(src, dst, c));
 707        return;
 708    } else if ((c & 0xffff0000) == c) {
 709        tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
 710        return;
 711    } else {
 712        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
 713        tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
 714    }
 715}
 716
 717static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
 718{
 719    int mb, me;
 720
 721    tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
 722    if (mask64_operand(c, &mb, &me)) {
 723        if (mb == 0) {
 724            tcg_out_rld(s, RLDICR, dst, src, 0, me);
 725        } else {
 726            tcg_out_rld(s, RLDICL, dst, src, 0, mb);
 727        }
 728    } else if ((c & 0xffff) == c) {
 729        tcg_out32(s, ANDI | SAI(src, dst, c));
 730        return;
 731    } else if ((c & 0xffff0000) == c) {
 732        tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
 733        return;
 734    } else {
 735        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
 736        tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
 737    }
 738}
 739
 740static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
 741                           int op_lo, int op_hi)
 742{
 743    if (c >> 16) {
 744        tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
 745        src = dst;
 746    }
 747    if (c & 0xffff) {
 748        tcg_out32(s, op_lo | SAI(src, dst, c));
 749        src = dst;
 750    }
 751}
 752
 753static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
 754{
 755    tcg_out_zori32(s, dst, src, c, ORI, ORIS);
 756}
 757
 758static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
 759{
 760    tcg_out_zori32(s, dst, src, c, XORI, XORIS);
 761}
 762
 763static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
 764{
 765    ptrdiff_t disp = tcg_pcrel_diff(s, target);
 766    if (in_range_b(disp)) {
 767        tcg_out32(s, B | (disp & 0x3fffffc) | mask);
 768    } else {
 769        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target);
 770        tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
 771        tcg_out32(s, BCCTR | BO_ALWAYS | mask);
 772    }
 773}
 774
 775static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
 776                             TCGReg base, tcg_target_long offset)
 777{
 778    tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
 779    bool is_store = false;
 780    TCGReg rs = TCG_REG_TMP1;
 781
 782    switch (opi) {
 783    case LD: case LWA:
 784        align = 3;
 785        /* FALLTHRU */
 786    default:
 787        if (rt != TCG_REG_R0) {
 788            rs = rt;
 789            break;
 790        }
 791        break;
 792    case STD:
 793        align = 3;
 794        /* FALLTHRU */
 795    case STB: case STH: case STW:
 796        is_store = true;
 797        break;
 798    }
 799
 800    /* For unaligned, or very large offsets, use the indexed form.  */
 801    if (offset & align || offset != (int32_t)offset) {
 802        if (rs == base) {
 803            rs = TCG_REG_R0;
 804        }
 805        tcg_debug_assert(!is_store || rs != rt);
 806        tcg_out_movi(s, TCG_TYPE_PTR, rs, orig);
 807        tcg_out32(s, opx | TAB(rt, base, rs));
 808        return;
 809    }
 810
 811    l0 = (int16_t)offset;
 812    offset = (offset - l0) >> 16;
 813    l1 = (int16_t)offset;
 814
 815    if (l1 < 0 && orig >= 0) {
 816        extra = 0x4000;
 817        l1 = (int16_t)(offset - 0x4000);
 818    }
 819    if (l1) {
 820        tcg_out32(s, ADDIS | TAI(rs, base, l1));
 821        base = rs;
 822    }
 823    if (extra) {
 824        tcg_out32(s, ADDIS | TAI(rs, base, extra));
 825        base = rs;
 826    }
 827    if (opi != ADDI || base != rt || l0 != 0) {
 828        tcg_out32(s, opi | TAI(rt, base, l0));
 829    }
 830}
 831
 832static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
 833                              TCGReg arg1, intptr_t arg2)
 834{
 835    int opi, opx;
 836
 837    tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 838    if (type == TCG_TYPE_I32) {
 839        opi = LWZ, opx = LWZX;
 840    } else {
 841        opi = LD, opx = LDX;
 842    }
 843    tcg_out_mem_long(s, opi, opx, ret, arg1, arg2);
 844}
 845
 846static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 847                              TCGReg arg1, intptr_t arg2)
 848{
 849    int opi, opx;
 850
 851    tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 852    if (type == TCG_TYPE_I32) {
 853        opi = STW, opx = STWX;
 854    } else {
 855        opi = STD, opx = STDX;
 856    }
 857    tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
 858}
 859
 860static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
 861                               TCGReg base, intptr_t ofs)
 862{
 863    return false;
 864}
 865
 866static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
 867                        int const_arg2, int cr, TCGType type)
 868{
 869    int imm;
 870    uint32_t op;
 871
 872    tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 873
 874    /* Simplify the comparisons below wrt CMPI.  */
 875    if (type == TCG_TYPE_I32) {
 876        arg2 = (int32_t)arg2;
 877    }
 878
 879    switch (cond) {
 880    case TCG_COND_EQ:
 881    case TCG_COND_NE:
 882        if (const_arg2) {
 883            if ((int16_t) arg2 == arg2) {
 884                op = CMPI;
 885                imm = 1;
 886                break;
 887            } else if ((uint16_t) arg2 == arg2) {
 888                op = CMPLI;
 889                imm = 1;
 890                break;
 891            }
 892        }
 893        op = CMPL;
 894        imm = 0;
 895        break;
 896
 897    case TCG_COND_LT:
 898    case TCG_COND_GE:
 899    case TCG_COND_LE:
 900    case TCG_COND_GT:
 901        if (const_arg2) {
 902            if ((int16_t) arg2 == arg2) {
 903                op = CMPI;
 904                imm = 1;
 905                break;
 906            }
 907        }
 908        op = CMP;
 909        imm = 0;
 910        break;
 911
 912    case TCG_COND_LTU:
 913    case TCG_COND_GEU:
 914    case TCG_COND_LEU:
 915    case TCG_COND_GTU:
 916        if (const_arg2) {
 917            if ((uint16_t) arg2 == arg2) {
 918                op = CMPLI;
 919                imm = 1;
 920                break;
 921            }
 922        }
 923        op = CMPL;
 924        imm = 0;
 925        break;
 926
 927    default:
 928        tcg_abort();
 929    }
 930    op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
 931
 932    if (imm) {
 933        tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
 934    } else {
 935        if (const_arg2) {
 936            tcg_out_movi(s, type, TCG_REG_R0, arg2);
 937            arg2 = TCG_REG_R0;
 938        }
 939        tcg_out32(s, op | RA(arg1) | RB(arg2));
 940    }
 941}
 942
 943static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
 944                                TCGReg dst, TCGReg src)
 945{
 946    if (type == TCG_TYPE_I32) {
 947        tcg_out32(s, CNTLZW | RS(src) | RA(dst));
 948        tcg_out_shri32(s, dst, dst, 5);
 949    } else {
 950        tcg_out32(s, CNTLZD | RS(src) | RA(dst));
 951        tcg_out_shri64(s, dst, dst, 6);
 952    }
 953}
 954
 955static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
 956{
 957    /* X != 0 implies X + -1 generates a carry.  Extra addition
 958       trickery means: R = X-1 + ~X + C = X-1 + (-X+1) + C = C.  */
 959    if (dst != src) {
 960        tcg_out32(s, ADDIC | TAI(dst, src, -1));
 961        tcg_out32(s, SUBFE | TAB(dst, dst, src));
 962    } else {
 963        tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
 964        tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
 965    }
 966}
 967
 968static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
 969                                  bool const_arg2)
 970{
 971    if (const_arg2) {
 972        if ((uint32_t)arg2 == arg2) {
 973            tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
 974        } else {
 975            tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
 976            tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
 977        }
 978    } else {
 979        tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
 980    }
 981    return TCG_REG_R0;
 982}
 983
 984static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
 985                            TCGArg arg0, TCGArg arg1, TCGArg arg2,
 986                            int const_arg2)
 987{
 988    int crop, sh;
 989
 990    tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 991
 992    /* Ignore high bits of a potential constant arg2.  */
 993    if (type == TCG_TYPE_I32) {
 994        arg2 = (uint32_t)arg2;
 995    }
 996
 997    /* Handle common and trivial cases before handling anything else.  */
 998    if (arg2 == 0) {
 999        switch (cond) {
1000        case TCG_COND_EQ:
1001            tcg_out_setcond_eq0(s, type, arg0, arg1);
1002            return;
1003        case TCG_COND_NE:
1004            if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1005                tcg_out_ext32u(s, TCG_REG_R0, arg1);
1006                arg1 = TCG_REG_R0;
1007            }
1008            tcg_out_setcond_ne0(s, arg0, arg1);
1009            return;
1010        case TCG_COND_GE:
1011            tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1012            arg1 = arg0;
1013            /* FALLTHRU */
1014        case TCG_COND_LT:
1015            /* Extract the sign bit.  */
1016            if (type == TCG_TYPE_I32) {
1017                tcg_out_shri32(s, arg0, arg1, 31);
1018            } else {
1019                tcg_out_shri64(s, arg0, arg1, 63);
1020            }
1021            return;
1022        default:
1023            break;
1024        }
1025    }
1026
1027    /* If we have ISEL, we can implement everything with 3 or 4 insns.
1028       All other cases below are also at least 3 insns, so speed up the
1029       code generator by not considering them and always using ISEL.  */
1030    if (HAVE_ISEL) {
1031        int isel, tab;
1032
1033        tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1034
1035        isel = tcg_to_isel[cond];
1036
1037        tcg_out_movi(s, type, arg0, 1);
1038        if (isel & 1) {
1039            /* arg0 = (bc ? 0 : 1) */
1040            tab = TAB(arg0, 0, arg0);
1041            isel &= ~1;
1042        } else {
1043            /* arg0 = (bc ? 1 : 0) */
1044            tcg_out_movi(s, type, TCG_REG_R0, 0);
1045            tab = TAB(arg0, arg0, TCG_REG_R0);
1046        }
1047        tcg_out32(s, isel | tab);
1048        return;
1049    }
1050
1051    switch (cond) {
1052    case TCG_COND_EQ:
1053        arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1054        tcg_out_setcond_eq0(s, type, arg0, arg1);
1055        return;
1056
1057    case TCG_COND_NE:
1058        arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1059        /* Discard the high bits only once, rather than both inputs.  */
1060        if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1061            tcg_out_ext32u(s, TCG_REG_R0, arg1);
1062            arg1 = TCG_REG_R0;
1063        }
1064        tcg_out_setcond_ne0(s, arg0, arg1);
1065        return;
1066
1067    case TCG_COND_GT:
1068    case TCG_COND_GTU:
1069        sh = 30;
1070        crop = 0;
1071        goto crtest;
1072
1073    case TCG_COND_LT:
1074    case TCG_COND_LTU:
1075        sh = 29;
1076        crop = 0;
1077        goto crtest;
1078
1079    case TCG_COND_GE:
1080    case TCG_COND_GEU:
1081        sh = 31;
1082        crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1083        goto crtest;
1084
1085    case TCG_COND_LE:
1086    case TCG_COND_LEU:
1087        sh = 31;
1088        crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1089    crtest:
1090        tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1091        if (crop) {
1092            tcg_out32(s, crop);
1093        }
1094        tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1095        tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1096        break;
1097
1098    default:
1099        tcg_abort();
1100    }
1101}
1102
1103static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
1104{
1105    if (l->has_value) {
1106        tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));
1107    } else {
1108        tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
1109        tcg_out_bc_noaddr(s, bc);
1110    }
1111}
1112
1113static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1114                           TCGArg arg1, TCGArg arg2, int const_arg2,
1115                           TCGLabel *l, TCGType type)
1116{
1117    tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1118    tcg_out_bc(s, tcg_to_bc[cond], l);
1119}
1120
1121static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1122                            TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1123                            TCGArg v2, bool const_c2)
1124{
1125    /* If for some reason both inputs are zero, don't produce bad code.  */
1126    if (v1 == 0 && v2 == 0) {
1127        tcg_out_movi(s, type, dest, 0);
1128        return;
1129    }
1130
1131    tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1132
1133    if (HAVE_ISEL) {
1134        int isel = tcg_to_isel[cond];
1135
1136        /* Swap the V operands if the operation indicates inversion.  */
1137        if (isel & 1) {
1138            int t = v1;
1139            v1 = v2;
1140            v2 = t;
1141            isel &= ~1;
1142        }
1143        /* V1 == 0 is handled by isel; V2 == 0 must be handled by hand.  */
1144        if (v2 == 0) {
1145            tcg_out_movi(s, type, TCG_REG_R0, 0);
1146        }
1147        tcg_out32(s, isel | TAB(dest, v1, v2));
1148    } else {
1149        if (dest == v2) {
1150            cond = tcg_invert_cond(cond);
1151            v2 = v1;
1152        } else if (dest != v1) {
1153            if (v1 == 0) {
1154                tcg_out_movi(s, type, dest, 0);
1155            } else {
1156                tcg_out_mov(s, type, dest, v1);
1157            }
1158        }
1159        /* Branch forward over one insn */
1160        tcg_out32(s, tcg_to_bc[cond] | 8);
1161        if (v2 == 0) {
1162            tcg_out_movi(s, type, dest, 0);
1163        } else {
1164            tcg_out_mov(s, type, dest, v2);
1165        }
1166    }
1167}
1168
1169static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
1170                         const int *const_args)
1171{
1172    static const struct { uint8_t bit1, bit2; } bits[] = {
1173        [TCG_COND_LT ] = { CR_LT, CR_LT },
1174        [TCG_COND_LE ] = { CR_LT, CR_GT },
1175        [TCG_COND_GT ] = { CR_GT, CR_GT },
1176        [TCG_COND_GE ] = { CR_GT, CR_LT },
1177        [TCG_COND_LTU] = { CR_LT, CR_LT },
1178        [TCG_COND_LEU] = { CR_LT, CR_GT },
1179        [TCG_COND_GTU] = { CR_GT, CR_GT },
1180        [TCG_COND_GEU] = { CR_GT, CR_LT },
1181    };
1182
1183    TCGCond cond = args[4], cond2;
1184    TCGArg al, ah, bl, bh;
1185    int blconst, bhconst;
1186    int op, bit1, bit2;
1187
1188    al = args[0];
1189    ah = args[1];
1190    bl = args[2];
1191    bh = args[3];
1192    blconst = const_args[2];
1193    bhconst = const_args[3];
1194
1195    switch (cond) {
1196    case TCG_COND_EQ:
1197        op = CRAND;
1198        goto do_equality;
1199    case TCG_COND_NE:
1200        op = CRNAND;
1201    do_equality:
1202        tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
1203        tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
1204        tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1205        break;
1206
1207    case TCG_COND_LT:
1208    case TCG_COND_LE:
1209    case TCG_COND_GT:
1210    case TCG_COND_GE:
1211    case TCG_COND_LTU:
1212    case TCG_COND_LEU:
1213    case TCG_COND_GTU:
1214    case TCG_COND_GEU:
1215        bit1 = bits[cond].bit1;
1216        bit2 = bits[cond].bit2;
1217        op = (bit1 != bit2 ? CRANDC : CRAND);
1218        cond2 = tcg_unsigned_cond(cond);
1219
1220        tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
1221        tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
1222        tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
1223        tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
1224        break;
1225
1226    default:
1227        tcg_abort();
1228    }
1229}
1230
1231static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
1232                             const int *const_args)
1233{
1234    tcg_out_cmp2(s, args + 1, const_args + 1);
1235    tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1236    tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
1237}
1238
1239static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1240                             const int *const_args)
1241{
1242    tcg_out_cmp2(s, args, const_args);
1243    tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
1244}
1245
1246#ifdef __powerpc64__
1247void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
1248{
1249    tcg_insn_unit i1, i2;
1250    uint64_t pair;
1251    intptr_t diff = addr - jmp_addr;
1252
1253    if (in_range_b(diff)) {
1254        i1 = B | (diff & 0x3fffffc);
1255        i2 = NOP;
1256    } else if (USE_REG_RA) {
1257        intptr_t lo, hi;
1258        diff = addr - (uintptr_t)tb_ret_addr;
1259        lo = (int16_t)diff;
1260        hi = (int32_t)(diff - lo);
1261        tcg_debug_assert(diff == hi + lo);
1262        i1 = ADDIS | TAI(TCG_REG_TMP1, TCG_REG_RA, hi >> 16);
1263        i2 = ADDI | TAI(TCG_REG_TMP1, TCG_REG_TMP1, lo);
1264    } else {
1265        tcg_debug_assert(TCG_TARGET_REG_BITS == 32 || addr == (int32_t)addr);
1266        i1 = ADDIS | TAI(TCG_REG_TMP1, 0, addr >> 16);
1267        i2 = ORI | SAI(TCG_REG_TMP1, TCG_REG_TMP1, addr);
1268    }
1269#ifdef HOST_WORDS_BIGENDIAN
1270    pair = (uint64_t)i1 << 32 | i2;
1271#else
1272    pair = (uint64_t)i2 << 32 | i1;
1273#endif
1274
1275    atomic_set((uint64_t *)jmp_addr, pair);
1276    flush_icache_range(jmp_addr, jmp_addr + 8);
1277}
1278#else
1279void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
1280{
1281    intptr_t diff = addr - jmp_addr;
1282    tcg_debug_assert(in_range_b(diff));
1283    atomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
1284    flush_icache_range(jmp_addr, jmp_addr + 4);
1285}
1286#endif
1287
1288static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
1289{
1290#ifdef _CALL_AIX
1291    /* Look through the descriptor.  If the branch is in range, and we
1292       don't have to spend too much effort on building the toc.  */
1293    void *tgt = ((void **)target)[0];
1294    uintptr_t toc = ((uintptr_t *)target)[1];
1295    intptr_t diff = tcg_pcrel_diff(s, tgt);
1296
1297    if (in_range_b(diff) && toc == (uint32_t)toc) {
1298        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc);
1299        tcg_out_b(s, LK, tgt);
1300    } else {
1301        /* Fold the low bits of the constant into the addresses below.  */
1302        intptr_t arg = (intptr_t)target;
1303        int ofs = (int16_t)arg;
1304
1305        if (ofs + 8 < 0x8000) {
1306            arg -= ofs;
1307        } else {
1308            ofs = 0;
1309        }
1310        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, arg);
1311        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs);
1312        tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
1313        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP);
1314        tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1315    }
1316#elif defined(_CALL_ELF) && _CALL_ELF == 2
1317    intptr_t diff;
1318
1319    /* In the ELFv2 ABI, we have to set up r12 to contain the destination
1320       address, which the callee uses to compute its TOC address.  */
1321    /* FIXME: when the branch is in range, we could avoid r12 load if we
1322       knew that the destination uses the same TOC, and what its local
1323       entry point offset is.  */
1324    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, (intptr_t)target);
1325
1326    diff = tcg_pcrel_diff(s, target);
1327    if (in_range_b(diff)) {
1328        tcg_out_b(s, LK, target);
1329    } else {
1330        tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR);
1331        tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1332    }
1333#else
1334    tcg_out_b(s, LK, target);
1335#endif
1336}
1337
1338static const uint32_t qemu_ldx_opc[16] = {
1339    [MO_UB] = LBZX,
1340    [MO_UW] = LHZX,
1341    [MO_UL] = LWZX,
1342    [MO_Q]  = LDX,
1343    [MO_SW] = LHAX,
1344    [MO_SL] = LWAX,
1345    [MO_BSWAP | MO_UB] = LBZX,
1346    [MO_BSWAP | MO_UW] = LHBRX,
1347    [MO_BSWAP | MO_UL] = LWBRX,
1348    [MO_BSWAP | MO_Q]  = LDBRX,
1349};
1350
1351static const uint32_t qemu_stx_opc[16] = {
1352    [MO_UB] = STBX,
1353    [MO_UW] = STHX,
1354    [MO_UL] = STWX,
1355    [MO_Q]  = STDX,
1356    [MO_BSWAP | MO_UB] = STBX,
1357    [MO_BSWAP | MO_UW] = STHBRX,
1358    [MO_BSWAP | MO_UL] = STWBRX,
1359    [MO_BSWAP | MO_Q]  = STDBRX,
1360};
1361
1362static const uint32_t qemu_exts_opc[4] = {
1363    EXTSB, EXTSH, EXTSW, 0
1364};
1365
1366#if defined (CONFIG_SOFTMMU)
1367/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1368 *                                 int mmu_idx, uintptr_t ra)
1369 */
1370static void * const qemu_ld_helpers[16] = {
1371    [MO_UB]   = helper_ret_ldub_mmu,
1372    [MO_LEUW] = helper_le_lduw_mmu,
1373    [MO_LEUL] = helper_le_ldul_mmu,
1374    [MO_LEQ]  = helper_le_ldq_mmu,
1375    [MO_BEUW] = helper_be_lduw_mmu,
1376    [MO_BEUL] = helper_be_ldul_mmu,
1377    [MO_BEQ]  = helper_be_ldq_mmu,
1378};
1379
1380/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1381 *                                 uintxx_t val, int mmu_idx, uintptr_t ra)
1382 */
1383static void * const qemu_st_helpers[16] = {
1384    [MO_UB]   = helper_ret_stb_mmu,
1385    [MO_LEUW] = helper_le_stw_mmu,
1386    [MO_LEUL] = helper_le_stl_mmu,
1387    [MO_LEQ]  = helper_le_stq_mmu,
1388    [MO_BEUW] = helper_be_stw_mmu,
1389    [MO_BEUL] = helper_be_stl_mmu,
1390    [MO_BEQ]  = helper_be_stq_mmu,
1391};
1392
1393/* Perform the TLB load and compare.  Places the result of the comparison
1394   in CR7, loads the addend of the TLB into R3, and returns the register
1395   containing the guest address (zero-extended into R4).  Clobbers R0 and R2. */
1396
1397static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp opc,
1398                               TCGReg addrlo, TCGReg addrhi,
1399                               int mem_index, bool is_read)
1400{
1401    int cmp_off
1402        = (is_read
1403           ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1404           : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1405    int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1406    TCGReg base = TCG_AREG0;
1407    TCGMemOp s_bits = opc & MO_SIZE;
1408    int a_bits = get_alignment_bits(opc);
1409
1410    /* Extract the page index, shifted into place for tlb index.  */
1411    if (TCG_TARGET_REG_BITS == 64) {
1412        if (TARGET_LONG_BITS == 32) {
1413            /* Zero-extend the address into a place helpful for further use. */
1414            tcg_out_ext32u(s, TCG_REG_R4, addrlo);
1415            addrlo = TCG_REG_R4;
1416        } else {
1417            tcg_out_rld(s, RLDICL, TCG_REG_R3, addrlo,
1418                        64 - TARGET_PAGE_BITS, 64 - CPU_TLB_BITS);
1419        }
1420    }
1421
1422    /* Compensate for very large offsets.  */
1423    if (add_off >= 0x8000) {
1424        /* Most target env are smaller than 32k; none are larger than 64k.
1425           Simplify the logic here merely to offset by 0x7ff0, giving us a
1426           range just shy of 64k.  Check this assumption.  */
1427        QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
1428                                   tlb_table[NB_MMU_MODES - 1][1])
1429                          > 0x7ff0 + 0x7fff);
1430        tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, base, 0x7ff0));
1431        base = TCG_REG_TMP1;
1432        cmp_off -= 0x7ff0;
1433        add_off -= 0x7ff0;
1434    }
1435
1436    /* Extraction and shifting, part 2.  */
1437    if (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32) {
1438        tcg_out_rlw(s, RLWINM, TCG_REG_R3, addrlo,
1439                    32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
1440                    32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS),
1441                    31 - CPU_TLB_ENTRY_BITS);
1442    } else {
1443        tcg_out_shli64(s, TCG_REG_R3, TCG_REG_R3, CPU_TLB_ENTRY_BITS);
1444    }
1445
1446    tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, base));
1447
1448    /* Load the tlb comparator.  */
1449    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1450        tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off);
1451        tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4);
1452    } else {
1453        tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off);
1454    }
1455
1456    /* Load the TLB addend for use on the fast path.  Do this asap
1457       to minimize any load use delay.  */
1458    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, add_off);
1459
1460    /* Clear the non-page, non-alignment bits from the address */
1461    if (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32) {
1462        /* We don't support unaligned accesses on 32-bits, preserve
1463         * the bottom bits and thus trigger a comparison failure on
1464         * unaligned accesses
1465         */
1466        if (a_bits < 0) {
1467            a_bits = s_bits;
1468        }
1469        tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
1470                    (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1471    } else if (a_bits) {
1472        /* More than byte access, we need to handle alignment */
1473        if (a_bits > 0) {
1474            /* Alignment required by the front-end, same as 32-bits */
1475            tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
1476                        64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - a_bits);
1477            tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
1478       } else {
1479           /* We support unaligned accesses, we need to make sure we fail
1480            * if we cross a page boundary. The trick is to add the
1481            * access_size-1 to the address before masking the low bits.
1482            * That will make the address overflow to the next page if we
1483            * cross a page boundary which will then force a mismatch of
1484            * the TLB compare since the next page cannot possibly be in
1485            * the same TLB index.
1486            */
1487            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, (1 << s_bits) - 1));
1488            tcg_out_rld(s, RLDICR, TCG_REG_R0, TCG_REG_R0,
1489                        0, 63 - TARGET_PAGE_BITS);
1490        }
1491    } else {
1492        /* Byte access, just chop off the bits below the page index */
1493        tcg_out_rld(s, RLDICR, TCG_REG_R0, addrlo, 0, 63 - TARGET_PAGE_BITS);
1494    }
1495
1496    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1497        tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1498                    0, 7, TCG_TYPE_I32);
1499        tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32);
1500        tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1501    } else {
1502        tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1503                    0, 7, TCG_TYPE_TL);
1504    }
1505
1506    return addrlo;
1507}
1508
1509/* Record the context of a call to the out of line helper code for the slow
1510   path for a load or store, so that we can later generate the correct
1511   helper code.  */
1512static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1513                                TCGReg datalo_reg, TCGReg datahi_reg,
1514                                TCGReg addrlo_reg, TCGReg addrhi_reg,
1515                                tcg_insn_unit *raddr, tcg_insn_unit *lptr)
1516{
1517    TCGLabelQemuLdst *label = new_ldst_label(s);
1518
1519    label->is_ld = is_ld;
1520    label->oi = oi;
1521    label->datalo_reg = datalo_reg;
1522    label->datahi_reg = datahi_reg;
1523    label->addrlo_reg = addrlo_reg;
1524    label->addrhi_reg = addrhi_reg;
1525    label->raddr = raddr;
1526    label->label_ptr[0] = lptr;
1527}
1528
1529static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1530{
1531    TCGMemOpIdx oi = lb->oi;
1532    TCGMemOp opc = get_memop(oi);
1533    TCGReg hi, lo, arg = TCG_REG_R3;
1534
1535    reloc_pc14(lb->label_ptr[0], s->code_ptr);
1536
1537    tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1538
1539    lo = lb->addrlo_reg;
1540    hi = lb->addrhi_reg;
1541    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1542#ifdef TCG_TARGET_CALL_ALIGN_ARGS
1543        arg |= 1;
1544#endif
1545        tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1546        tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1547    } else {
1548        /* If the address needed to be zero-extended, we'll have already
1549           placed it in R4.  The only remaining case is 64-bit guest.  */
1550        tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1551    }
1552
1553    tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1554    tcg_out32(s, MFSPR | RT(arg) | LR);
1555
1556    tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1557
1558    lo = lb->datalo_reg;
1559    hi = lb->datahi_reg;
1560    if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
1561        tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4);
1562        tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3);
1563    } else if (opc & MO_SIGN) {
1564        uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
1565        tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3));
1566    } else {
1567        tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3);
1568    }
1569
1570    tcg_out_b(s, 0, lb->raddr);
1571}
1572
1573static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1574{
1575    TCGMemOpIdx oi = lb->oi;
1576    TCGMemOp opc = get_memop(oi);
1577    TCGMemOp s_bits = opc & MO_SIZE;
1578    TCGReg hi, lo, arg = TCG_REG_R3;
1579
1580    reloc_pc14(lb->label_ptr[0], s->code_ptr);
1581
1582    tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1583
1584    lo = lb->addrlo_reg;
1585    hi = lb->addrhi_reg;
1586    if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1587#ifdef TCG_TARGET_CALL_ALIGN_ARGS
1588        arg |= 1;
1589#endif
1590        tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1591        tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1592    } else {
1593        /* If the address needed to be zero-extended, we'll have already
1594           placed it in R4.  The only remaining case is 64-bit guest.  */
1595        tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1596    }
1597
1598    lo = lb->datalo_reg;
1599    hi = lb->datahi_reg;
1600    if (TCG_TARGET_REG_BITS == 32) {
1601        switch (s_bits) {
1602        case MO_64:
1603#ifdef TCG_TARGET_CALL_ALIGN_ARGS
1604            arg |= 1;
1605#endif
1606            tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1607            /* FALLTHRU */
1608        case MO_32:
1609            tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1610            break;
1611        default:
1612            tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31);
1613            break;
1614        }
1615    } else {
1616        if (s_bits == MO_64) {
1617            tcg_out_mov(s, TCG_TYPE_I64, arg++, lo);
1618        } else {
1619            tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits));
1620        }
1621    }
1622
1623    tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1624    tcg_out32(s, MFSPR | RT(arg) | LR);
1625
1626    tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1627
1628    tcg_out_b(s, 0, lb->raddr);
1629}
1630#endif /* SOFTMMU */
1631
1632static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1633{
1634    TCGReg datalo, datahi, addrlo, rbase;
1635    TCGReg addrhi __attribute__((unused));
1636    TCGMemOpIdx oi;
1637    TCGMemOp opc, s_bits;
1638#ifdef CONFIG_SOFTMMU
1639    int mem_index;
1640    tcg_insn_unit *label_ptr;
1641#endif
1642
1643    datalo = *args++;
1644    datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1645    addrlo = *args++;
1646    addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1647    oi = *args++;
1648    opc = get_memop(oi);
1649    s_bits = opc & MO_SIZE;
1650
1651#ifdef CONFIG_SOFTMMU
1652    mem_index = get_mmuidx(oi);
1653    addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, true);
1654
1655    /* Load a pointer into the current opcode w/conditional branch-link. */
1656    label_ptr = s->code_ptr;
1657    tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1658
1659    rbase = TCG_REG_R3;
1660#else  /* !CONFIG_SOFTMMU */
1661    rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
1662    if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1663        tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1664        addrlo = TCG_REG_TMP1;
1665    }
1666#endif
1667
1668    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1669        if (opc & MO_BSWAP) {
1670            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1671            tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1672            tcg_out32(s, LWBRX | TAB(datahi, rbase, TCG_REG_R0));
1673        } else if (rbase != 0) {
1674            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1675            tcg_out32(s, LWZX | TAB(datahi, rbase, addrlo));
1676            tcg_out32(s, LWZX | TAB(datalo, rbase, TCG_REG_R0));
1677        } else if (addrlo == datahi) {
1678            tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1679            tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1680        } else {
1681            tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1682            tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1683        }
1684    } else {
1685        uint32_t insn = qemu_ldx_opc[opc & (MO_BSWAP | MO_SSIZE)];
1686        if (!HAVE_ISA_2_06 && insn == LDBRX) {
1687            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1688            tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1689            tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
1690            tcg_out_rld(s, RLDIMI, datalo, TCG_REG_R0, 32, 0);
1691        } else if (insn) {
1692            tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1693        } else {
1694            insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
1695            tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1696            insn = qemu_exts_opc[s_bits];
1697            tcg_out32(s, insn | RA(datalo) | RS(datalo));
1698        }
1699    }
1700
1701#ifdef CONFIG_SOFTMMU
1702    add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
1703                        s->code_ptr, label_ptr);
1704#endif
1705}
1706
1707static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1708{
1709    TCGReg datalo, datahi, addrlo, rbase;
1710    TCGReg addrhi __attribute__((unused));
1711    TCGMemOpIdx oi;
1712    TCGMemOp opc, s_bits;
1713#ifdef CONFIG_SOFTMMU
1714    int mem_index;
1715    tcg_insn_unit *label_ptr;
1716#endif
1717
1718    datalo = *args++;
1719    datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1720    addrlo = *args++;
1721    addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1722    oi = *args++;
1723    opc = get_memop(oi);
1724    s_bits = opc & MO_SIZE;
1725
1726#ifdef CONFIG_SOFTMMU
1727    mem_index = get_mmuidx(oi);
1728    addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, false);
1729
1730    /* Load a pointer into the current opcode w/conditional branch-link. */
1731    label_ptr = s->code_ptr;
1732    tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1733
1734    rbase = TCG_REG_R3;
1735#else  /* !CONFIG_SOFTMMU */
1736    rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
1737    if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1738        tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1739        addrlo = TCG_REG_TMP1;
1740    }
1741#endif
1742
1743    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1744        if (opc & MO_BSWAP) {
1745            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1746            tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1747            tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0));
1748        } else if (rbase != 0) {
1749            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1750            tcg_out32(s, STWX | SAB(datahi, rbase, addrlo));
1751            tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0));
1752        } else {
1753            tcg_out32(s, STW | TAI(datahi, addrlo, 0));
1754            tcg_out32(s, STW | TAI(datalo, addrlo, 4));
1755        }
1756    } else {
1757        uint32_t insn = qemu_stx_opc[opc & (MO_BSWAP | MO_SIZE)];
1758        if (!HAVE_ISA_2_06 && insn == STDBRX) {
1759            tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1760            tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4));
1761            tcg_out_shri64(s, TCG_REG_R0, datalo, 32);
1762            tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1));
1763        } else {
1764            tcg_out32(s, insn | SAB(datalo, rbase, addrlo));
1765        }
1766    }
1767
1768#ifdef CONFIG_SOFTMMU
1769    add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,
1770                        s->code_ptr, label_ptr);
1771#endif
1772}
1773
1774/* Parameters for function call generation, used in tcg.c.  */
1775#define TCG_TARGET_STACK_ALIGN       16
1776#define TCG_TARGET_EXTEND_ARGS       1
1777
1778#ifdef _CALL_AIX
1779# define LINK_AREA_SIZE                (6 * SZR)
1780# define LR_OFFSET                     (1 * SZR)
1781# define TCG_TARGET_CALL_STACK_OFFSET  (LINK_AREA_SIZE + 8 * SZR)
1782#elif defined(TCG_TARGET_CALL_DARWIN)
1783# define LINK_AREA_SIZE                (6 * SZR)
1784# define LR_OFFSET                     (2 * SZR)
1785#elif TCG_TARGET_REG_BITS == 64
1786# if defined(_CALL_ELF) && _CALL_ELF == 2
1787#  define LINK_AREA_SIZE               (4 * SZR)
1788#  define LR_OFFSET                    (1 * SZR)
1789# endif
1790#else /* TCG_TARGET_REG_BITS == 32 */
1791# if defined(_CALL_SYSV)
1792#  define LINK_AREA_SIZE               (2 * SZR)
1793#  define LR_OFFSET                    (1 * SZR)
1794# endif
1795#endif
1796#ifndef LR_OFFSET
1797# error "Unhandled abi"
1798#endif
1799#ifndef TCG_TARGET_CALL_STACK_OFFSET
1800# define TCG_TARGET_CALL_STACK_OFFSET  LINK_AREA_SIZE
1801#endif
1802
1803#define CPU_TEMP_BUF_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
1804#define REG_SAVE_SIZE      ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * SZR)
1805
1806#define FRAME_SIZE ((TCG_TARGET_CALL_STACK_OFFSET   \
1807                     + TCG_STATIC_CALL_ARGS_SIZE    \
1808                     + CPU_TEMP_BUF_SIZE            \
1809                     + REG_SAVE_SIZE                \
1810                     + TCG_TARGET_STACK_ALIGN - 1)  \
1811                    & -TCG_TARGET_STACK_ALIGN)
1812
1813#define REG_SAVE_BOT (FRAME_SIZE - REG_SAVE_SIZE)
1814
1815static void tcg_target_qemu_prologue(TCGContext *s)
1816{
1817    int i;
1818
1819#ifdef _CALL_AIX
1820    void **desc = (void **)s->code_ptr;
1821    desc[0] = desc + 2;                   /* entry point */
1822    desc[1] = 0;                          /* environment pointer */
1823    s->code_ptr = (void *)(desc + 2);     /* skip over descriptor */
1824#endif
1825
1826    tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE,
1827                  CPU_TEMP_BUF_SIZE);
1828
1829    /* Prologue */
1830    tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
1831    tcg_out32(s, (SZR == 8 ? STDU : STWU)
1832              | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
1833
1834    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1835        tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1836                   TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1837    }
1838    tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1839
1840#ifndef CONFIG_SOFTMMU
1841    if (guest_base) {
1842        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
1843        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1844    }
1845#endif
1846
1847    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1848    tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
1849
1850    if (USE_REG_RA) {
1851#ifdef _CALL_AIX
1852        /* Make the caller load the value as the TOC into R2.  */
1853        tb_ret_addr = s->code_ptr + 2;
1854        desc[1] = tb_ret_addr;
1855        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_RA, TCG_REG_R2);
1856        tcg_out32(s, BCCTR | BO_ALWAYS);
1857#elif defined(_CALL_ELF) && _CALL_ELF == 2
1858        /* Compute from the incoming R12 value.  */
1859        tb_ret_addr = s->code_ptr + 2;
1860        tcg_out32(s, ADDI | TAI(TCG_REG_RA, TCG_REG_R12,
1861                                tcg_ptr_byte_diff(tb_ret_addr, s->code_buf)));
1862        tcg_out32(s, BCCTR | BO_ALWAYS);
1863#else
1864        /* Reserve max 5 insns for the constant load.  */
1865        tb_ret_addr = s->code_ptr + 6;
1866        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)tb_ret_addr);
1867        tcg_out32(s, BCCTR | BO_ALWAYS);
1868        while (s->code_ptr < tb_ret_addr) {
1869            tcg_out32(s, NOP);
1870        }
1871#endif
1872    } else {
1873        tcg_out32(s, BCCTR | BO_ALWAYS);
1874        tb_ret_addr = s->code_ptr;
1875    }
1876
1877    /* Epilogue */
1878    tcg_debug_assert(tb_ret_addr == s->code_ptr);
1879
1880    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1881    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1882        tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1883                   TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1884    }
1885    tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
1886    tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
1887    tcg_out32(s, BCLR | BO_ALWAYS);
1888}
1889
1890static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1891                       const int *const_args)
1892{
1893    TCGArg a0, a1, a2;
1894    int c;
1895
1896    switch (opc) {
1897    case INDEX_op_exit_tb:
1898        if (USE_REG_RA) {
1899            ptrdiff_t disp = tcg_pcrel_diff(s, tb_ret_addr);
1900
1901            /* Use a direct branch if we can, otherwise use the value in RA.
1902               Note that the direct branch is always backward, thus we need
1903               to account for the possibility of 5 insns from the movi.  */
1904            if (!in_range_b(disp - 20)) {
1905                tcg_out32(s, MTSPR | RS(TCG_REG_RA) | CTR);
1906                tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
1907                tcg_out32(s, BCCTR | BO_ALWAYS);
1908                break;
1909            }
1910        }
1911        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
1912        tcg_out_b(s, 0, tb_ret_addr);
1913        break;
1914    case INDEX_op_goto_tb:
1915        tcg_debug_assert(s->tb_jmp_insn_offset);
1916        /* Direct jump. */
1917#ifdef __powerpc64__
1918        /* Ensure the next insns are 8-byte aligned. */
1919        if ((uintptr_t)s->code_ptr & 7) {
1920            tcg_out32(s, NOP);
1921        }
1922        s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
1923        /* To be replaced by either a branch+nop or a load into TMP1.  */
1924        s->code_ptr += 2;
1925        tcg_out32(s, MTSPR | RS(TCG_REG_TMP1) | CTR);
1926        tcg_out32(s, BCCTR | BO_ALWAYS);
1927#else
1928        /* To be replaced by a branch.  */
1929        s->code_ptr++;
1930#endif
1931        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
1932        break;
1933    case INDEX_op_br:
1934        {
1935            TCGLabel *l = arg_label(args[0]);
1936
1937            if (l->has_value) {
1938                tcg_out_b(s, 0, l->u.value_ptr);
1939            } else {
1940                tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0);
1941                tcg_out_b_noaddr(s, B);
1942            }
1943        }
1944        break;
1945    case INDEX_op_ld8u_i32:
1946    case INDEX_op_ld8u_i64:
1947        tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1948        break;
1949    case INDEX_op_ld8s_i32:
1950    case INDEX_op_ld8s_i64:
1951        tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1952        tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
1953        break;
1954    case INDEX_op_ld16u_i32:
1955    case INDEX_op_ld16u_i64:
1956        tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
1957        break;
1958    case INDEX_op_ld16s_i32:
1959    case INDEX_op_ld16s_i64:
1960        tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
1961        break;
1962    case INDEX_op_ld_i32:
1963    case INDEX_op_ld32u_i64:
1964        tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
1965        break;
1966    case INDEX_op_ld32s_i64:
1967        tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
1968        break;
1969    case INDEX_op_ld_i64:
1970        tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
1971        break;
1972    case INDEX_op_st8_i32:
1973    case INDEX_op_st8_i64:
1974        tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
1975        break;
1976    case INDEX_op_st16_i32:
1977    case INDEX_op_st16_i64:
1978        tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
1979        break;
1980    case INDEX_op_st_i32:
1981    case INDEX_op_st32_i64:
1982        tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
1983        break;
1984    case INDEX_op_st_i64:
1985        tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
1986        break;
1987
1988    case INDEX_op_add_i32:
1989        a0 = args[0], a1 = args[1], a2 = args[2];
1990        if (const_args[2]) {
1991        do_addi_32:
1992            tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
1993        } else {
1994            tcg_out32(s, ADD | TAB(a0, a1, a2));
1995        }
1996        break;
1997    case INDEX_op_sub_i32:
1998        a0 = args[0], a1 = args[1], a2 = args[2];
1999        if (const_args[1]) {
2000            if (const_args[2]) {
2001                tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
2002            } else {
2003                tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2004            }
2005        } else if (const_args[2]) {
2006            a2 = -a2;
2007            goto do_addi_32;
2008        } else {
2009            tcg_out32(s, SUBF | TAB(a0, a2, a1));
2010        }
2011        break;
2012
2013    case INDEX_op_and_i32:
2014        a0 = args[0], a1 = args[1], a2 = args[2];
2015        if (const_args[2]) {
2016            tcg_out_andi32(s, a0, a1, a2);
2017        } else {
2018            tcg_out32(s, AND | SAB(a1, a0, a2));
2019        }
2020        break;
2021    case INDEX_op_and_i64:
2022        a0 = args[0], a1 = args[1], a2 = args[2];
2023        if (const_args[2]) {
2024            tcg_out_andi64(s, a0, a1, a2);
2025        } else {
2026            tcg_out32(s, AND | SAB(a1, a0, a2));
2027        }
2028        break;
2029    case INDEX_op_or_i64:
2030    case INDEX_op_or_i32:
2031        a0 = args[0], a1 = args[1], a2 = args[2];
2032        if (const_args[2]) {
2033            tcg_out_ori32(s, a0, a1, a2);
2034        } else {
2035            tcg_out32(s, OR | SAB(a1, a0, a2));
2036        }
2037        break;
2038    case INDEX_op_xor_i64:
2039    case INDEX_op_xor_i32:
2040        a0 = args[0], a1 = args[1], a2 = args[2];
2041        if (const_args[2]) {
2042            tcg_out_xori32(s, a0, a1, a2);
2043        } else {
2044            tcg_out32(s, XOR | SAB(a1, a0, a2));
2045        }
2046        break;
2047    case INDEX_op_andc_i32:
2048        a0 = args[0], a1 = args[1], a2 = args[2];
2049        if (const_args[2]) {
2050            tcg_out_andi32(s, a0, a1, ~a2);
2051        } else {
2052            tcg_out32(s, ANDC | SAB(a1, a0, a2));
2053        }
2054        break;
2055    case INDEX_op_andc_i64:
2056        a0 = args[0], a1 = args[1], a2 = args[2];
2057        if (const_args[2]) {
2058            tcg_out_andi64(s, a0, a1, ~a2);
2059        } else {
2060            tcg_out32(s, ANDC | SAB(a1, a0, a2));
2061        }
2062        break;
2063    case INDEX_op_orc_i32:
2064        if (const_args[2]) {
2065            tcg_out_ori32(s, args[0], args[1], ~args[2]);
2066            break;
2067        }
2068        /* FALLTHRU */
2069    case INDEX_op_orc_i64:
2070        tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
2071        break;
2072    case INDEX_op_eqv_i32:
2073        if (const_args[2]) {
2074            tcg_out_xori32(s, args[0], args[1], ~args[2]);
2075            break;
2076        }
2077        /* FALLTHRU */
2078    case INDEX_op_eqv_i64:
2079        tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
2080        break;
2081    case INDEX_op_nand_i32:
2082    case INDEX_op_nand_i64:
2083        tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
2084        break;
2085    case INDEX_op_nor_i32:
2086    case INDEX_op_nor_i64:
2087        tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
2088        break;
2089
2090    case INDEX_op_mul_i32:
2091        a0 = args[0], a1 = args[1], a2 = args[2];
2092        if (const_args[2]) {
2093            tcg_out32(s, MULLI | TAI(a0, a1, a2));
2094        } else {
2095            tcg_out32(s, MULLW | TAB(a0, a1, a2));
2096        }
2097        break;
2098
2099    case INDEX_op_div_i32:
2100        tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
2101        break;
2102
2103    case INDEX_op_divu_i32:
2104        tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
2105        break;
2106
2107    case INDEX_op_shl_i32:
2108        if (const_args[2]) {
2109            tcg_out_shli32(s, args[0], args[1], args[2]);
2110        } else {
2111            tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
2112        }
2113        break;
2114    case INDEX_op_shr_i32:
2115        if (const_args[2]) {
2116            tcg_out_shri32(s, args[0], args[1], args[2]);
2117        } else {
2118            tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
2119        }
2120        break;
2121    case INDEX_op_sar_i32:
2122        if (const_args[2]) {
2123            tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2]));
2124        } else {
2125            tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
2126        }
2127        break;
2128    case INDEX_op_rotl_i32:
2129        if (const_args[2]) {
2130            tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
2131        } else {
2132            tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
2133                         | MB(0) | ME(31));
2134        }
2135        break;
2136    case INDEX_op_rotr_i32:
2137        if (const_args[2]) {
2138            tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
2139        } else {
2140            tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
2141            tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
2142                         | MB(0) | ME(31));
2143        }
2144        break;
2145
2146    case INDEX_op_brcond_i32:
2147        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2148                       arg_label(args[3]), TCG_TYPE_I32);
2149        break;
2150    case INDEX_op_brcond_i64:
2151        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2152                       arg_label(args[3]), TCG_TYPE_I64);
2153        break;
2154    case INDEX_op_brcond2_i32:
2155        tcg_out_brcond2(s, args, const_args);
2156        break;
2157
2158    case INDEX_op_neg_i32:
2159    case INDEX_op_neg_i64:
2160        tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
2161        break;
2162
2163    case INDEX_op_not_i32:
2164    case INDEX_op_not_i64:
2165        tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
2166        break;
2167
2168    case INDEX_op_add_i64:
2169        a0 = args[0], a1 = args[1], a2 = args[2];
2170        if (const_args[2]) {
2171        do_addi_64:
2172            tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
2173        } else {
2174            tcg_out32(s, ADD | TAB(a0, a1, a2));
2175        }
2176        break;
2177    case INDEX_op_sub_i64:
2178        a0 = args[0], a1 = args[1], a2 = args[2];
2179        if (const_args[1]) {
2180            if (const_args[2]) {
2181                tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
2182            } else {
2183                tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2184            }
2185        } else if (const_args[2]) {
2186            a2 = -a2;
2187            goto do_addi_64;
2188        } else {
2189            tcg_out32(s, SUBF | TAB(a0, a2, a1));
2190        }
2191        break;
2192
2193    case INDEX_op_shl_i64:
2194        if (const_args[2]) {
2195            tcg_out_shli64(s, args[0], args[1], args[2]);
2196        } else {
2197            tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
2198        }
2199        break;
2200    case INDEX_op_shr_i64:
2201        if (const_args[2]) {
2202            tcg_out_shri64(s, args[0], args[1], args[2]);
2203        } else {
2204            tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
2205        }
2206        break;
2207    case INDEX_op_sar_i64:
2208        if (const_args[2]) {
2209            int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
2210            tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
2211        } else {
2212            tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
2213        }
2214        break;
2215    case INDEX_op_rotl_i64:
2216        if (const_args[2]) {
2217            tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
2218        } else {
2219            tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
2220        }
2221        break;
2222    case INDEX_op_rotr_i64:
2223        if (const_args[2]) {
2224            tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
2225        } else {
2226            tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
2227            tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
2228        }
2229        break;
2230
2231    case INDEX_op_mul_i64:
2232        a0 = args[0], a1 = args[1], a2 = args[2];
2233        if (const_args[2]) {
2234            tcg_out32(s, MULLI | TAI(a0, a1, a2));
2235        } else {
2236            tcg_out32(s, MULLD | TAB(a0, a1, a2));
2237        }
2238        break;
2239    case INDEX_op_div_i64:
2240        tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
2241        break;
2242    case INDEX_op_divu_i64:
2243        tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
2244        break;
2245
2246    case INDEX_op_qemu_ld_i32:
2247        tcg_out_qemu_ld(s, args, false);
2248        break;
2249    case INDEX_op_qemu_ld_i64:
2250        tcg_out_qemu_ld(s, args, true);
2251        break;
2252    case INDEX_op_qemu_st_i32:
2253        tcg_out_qemu_st(s, args, false);
2254        break;
2255    case INDEX_op_qemu_st_i64:
2256        tcg_out_qemu_st(s, args, true);
2257        break;
2258
2259    case INDEX_op_ext8s_i32:
2260    case INDEX_op_ext8s_i64:
2261        c = EXTSB;
2262        goto gen_ext;
2263    case INDEX_op_ext16s_i32:
2264    case INDEX_op_ext16s_i64:
2265        c = EXTSH;
2266        goto gen_ext;
2267    case INDEX_op_ext_i32_i64:
2268    case INDEX_op_ext32s_i64:
2269        c = EXTSW;
2270        goto gen_ext;
2271    gen_ext:
2272        tcg_out32(s, c | RS(args[1]) | RA(args[0]));
2273        break;
2274    case INDEX_op_extu_i32_i64:
2275        tcg_out_ext32u(s, args[0], args[1]);
2276        break;
2277
2278    case INDEX_op_setcond_i32:
2279        tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
2280                        const_args[2]);
2281        break;
2282    case INDEX_op_setcond_i64:
2283        tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
2284                        const_args[2]);
2285        break;
2286    case INDEX_op_setcond2_i32:
2287        tcg_out_setcond2(s, args, const_args);
2288        break;
2289
2290    case INDEX_op_bswap16_i32:
2291    case INDEX_op_bswap16_i64:
2292        a0 = args[0], a1 = args[1];
2293        /* a1 = abcd */
2294        if (a0 != a1) {
2295            /* a0 = (a1 r<< 24) & 0xff # 000c */
2296            tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2297            /* a0 = (a0 & ~0xff00) | (a1 r<< 8) & 0xff00 # 00dc */
2298            tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
2299        } else {
2300            /* r0 = (a1 r<< 8) & 0xff00 # 00d0 */
2301            tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
2302            /* a0 = (a1 r<< 24) & 0xff # 000c */
2303            tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2304            /* a0 = a0 | r0 # 00dc */
2305            tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
2306        }
2307        break;
2308
2309    case INDEX_op_bswap32_i32:
2310    case INDEX_op_bswap32_i64:
2311        /* Stolen from gcc's builtin_bswap32 */
2312        a1 = args[1];
2313        a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
2314
2315        /* a1 = args[1] # abcd */
2316        /* a0 = rotate_left (a1, 8) # bcda */
2317        tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2318        /* a0 = (a0 & ~0xff000000) | ((a1 r<< 24) & 0xff000000) # dcda */
2319        tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2320        /* a0 = (a0 & ~0x0000ff00) | ((a1 r<< 24) & 0x0000ff00) # dcba */
2321        tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2322
2323        if (a0 == TCG_REG_R0) {
2324            tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2325        }
2326        break;
2327
2328    case INDEX_op_bswap64_i64:
2329        a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
2330        if (a0 == a1) {
2331            a0 = TCG_REG_R0;
2332            a2 = a1;
2333        }
2334
2335        /* a1 = # abcd efgh */
2336        /* a0 = rl32(a1, 8) # 0000 fghe */
2337        tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2338        /* a0 = dep(a0, rl32(a1, 24), 0xff000000) # 0000 hghe */
2339        tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2340        /* a0 = dep(a0, rl32(a1, 24), 0x0000ff00) # 0000 hgfe */
2341        tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2342
2343        /* a0 = rl64(a0, 32) # hgfe 0000 */
2344        /* a2 = rl64(a1, 32) # efgh abcd */
2345        tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
2346        tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
2347
2348        /* a0 = dep(a0, rl32(a2, 8), 0xffffffff)  # hgfe bcda */
2349        tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
2350        /* a0 = dep(a0, rl32(a2, 24), 0xff000000) # hgfe dcda */
2351        tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
2352        /* a0 = dep(a0, rl32(a2, 24), 0x0000ff00) # hgfe dcba */
2353        tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
2354
2355        if (a0 == 0) {
2356            tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2357        }
2358        break;
2359
2360    case INDEX_op_deposit_i32:
2361        if (const_args[2]) {
2362            uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
2363            tcg_out_andi32(s, args[0], args[0], ~mask);
2364        } else {
2365            tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
2366                        32 - args[3] - args[4], 31 - args[3]);
2367        }
2368        break;
2369    case INDEX_op_deposit_i64:
2370        if (const_args[2]) {
2371            uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
2372            tcg_out_andi64(s, args[0], args[0], ~mask);
2373        } else {
2374            tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
2375                        64 - args[3] - args[4]);
2376        }
2377        break;
2378
2379    case INDEX_op_movcond_i32:
2380        tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
2381                        args[3], args[4], const_args[2]);
2382        break;
2383    case INDEX_op_movcond_i64:
2384        tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
2385                        args[3], args[4], const_args[2]);
2386        break;
2387
2388#if TCG_TARGET_REG_BITS == 64
2389    case INDEX_op_add2_i64:
2390#else
2391    case INDEX_op_add2_i32:
2392#endif
2393        /* Note that the CA bit is defined based on the word size of the
2394           environment.  So in 64-bit mode it's always carry-out of bit 63.
2395           The fallback code using deposit works just as well for 32-bit.  */
2396        a0 = args[0], a1 = args[1];
2397        if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
2398            a0 = TCG_REG_R0;
2399        }
2400        if (const_args[4]) {
2401            tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
2402        } else {
2403            tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
2404        }
2405        if (const_args[5]) {
2406            tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
2407        } else {
2408            tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
2409        }
2410        if (a0 != args[0]) {
2411            tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2412        }
2413        break;
2414
2415#if TCG_TARGET_REG_BITS == 64
2416    case INDEX_op_sub2_i64:
2417#else
2418    case INDEX_op_sub2_i32:
2419#endif
2420        a0 = args[0], a1 = args[1];
2421        if (a0 == args[5] || (!const_args[3] && a0 == args[3])) {
2422            a0 = TCG_REG_R0;
2423        }
2424        if (const_args[2]) {
2425            tcg_out32(s, SUBFIC | TAI(a0, args[4], args[2]));
2426        } else {
2427            tcg_out32(s, SUBFC | TAB(a0, args[4], args[2]));
2428        }
2429        if (const_args[3]) {
2430            tcg_out32(s, (args[3] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
2431        } else {
2432            tcg_out32(s, SUBFE | TAB(a1, args[5], args[3]));
2433        }
2434        if (a0 != args[0]) {
2435            tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2436        }
2437        break;
2438
2439    case INDEX_op_muluh_i32:
2440        tcg_out32(s, MULHWU | TAB(args[0], args[1], args[2]));
2441        break;
2442    case INDEX_op_mulsh_i32:
2443        tcg_out32(s, MULHW | TAB(args[0], args[1], args[2]));
2444        break;
2445    case INDEX_op_muluh_i64:
2446        tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2447        break;
2448    case INDEX_op_mulsh_i64:
2449        tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2450        break;
2451
2452    case INDEX_op_mov_i32:   /* Always emitted via tcg_out_mov.  */
2453    case INDEX_op_mov_i64:
2454    case INDEX_op_movi_i32:  /* Always emitted via tcg_out_movi.  */
2455    case INDEX_op_movi_i64:
2456    case INDEX_op_call:      /* Always emitted via tcg_out_call.  */
2457    default:
2458        tcg_abort();
2459    }
2460}
2461
2462static const TCGTargetOpDef ppc_op_defs[] = {
2463    { INDEX_op_exit_tb, { } },
2464    { INDEX_op_goto_tb, { } },
2465    { INDEX_op_br, { } },
2466
2467    { INDEX_op_ld8u_i32, { "r", "r" } },
2468    { INDEX_op_ld8s_i32, { "r", "r" } },
2469    { INDEX_op_ld16u_i32, { "r", "r" } },
2470    { INDEX_op_ld16s_i32, { "r", "r" } },
2471    { INDEX_op_ld_i32, { "r", "r" } },
2472
2473    { INDEX_op_st8_i32, { "r", "r" } },
2474    { INDEX_op_st16_i32, { "r", "r" } },
2475    { INDEX_op_st_i32, { "r", "r" } },
2476
2477    { INDEX_op_add_i32, { "r", "r", "ri" } },
2478    { INDEX_op_mul_i32, { "r", "r", "rI" } },
2479    { INDEX_op_div_i32, { "r", "r", "r" } },
2480    { INDEX_op_divu_i32, { "r", "r", "r" } },
2481    { INDEX_op_sub_i32, { "r", "rI", "ri" } },
2482    { INDEX_op_and_i32, { "r", "r", "ri" } },
2483    { INDEX_op_or_i32, { "r", "r", "ri" } },
2484    { INDEX_op_xor_i32, { "r", "r", "ri" } },
2485    { INDEX_op_andc_i32, { "r", "r", "ri" } },
2486    { INDEX_op_orc_i32, { "r", "r", "ri" } },
2487    { INDEX_op_eqv_i32, { "r", "r", "ri" } },
2488    { INDEX_op_nand_i32, { "r", "r", "r" } },
2489    { INDEX_op_nor_i32, { "r", "r", "r" } },
2490
2491    { INDEX_op_shl_i32, { "r", "r", "ri" } },
2492    { INDEX_op_shr_i32, { "r", "r", "ri" } },
2493    { INDEX_op_sar_i32, { "r", "r", "ri" } },
2494    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2495    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2496
2497    { INDEX_op_neg_i32, { "r", "r" } },
2498    { INDEX_op_not_i32, { "r", "r" } },
2499    { INDEX_op_ext8s_i32, { "r", "r" } },
2500    { INDEX_op_ext16s_i32, { "r", "r" } },
2501    { INDEX_op_bswap16_i32, { "r", "r" } },
2502    { INDEX_op_bswap32_i32, { "r", "r" } },
2503
2504    { INDEX_op_brcond_i32, { "r", "ri" } },
2505    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
2506    { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } },
2507
2508    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2509
2510    { INDEX_op_muluh_i32, { "r", "r", "r" } },
2511    { INDEX_op_mulsh_i32, { "r", "r", "r" } },
2512
2513#if TCG_TARGET_REG_BITS == 64
2514    { INDEX_op_ld8u_i64, { "r", "r" } },
2515    { INDEX_op_ld8s_i64, { "r", "r" } },
2516    { INDEX_op_ld16u_i64, { "r", "r" } },
2517    { INDEX_op_ld16s_i64, { "r", "r" } },
2518    { INDEX_op_ld32u_i64, { "r", "r" } },
2519    { INDEX_op_ld32s_i64, { "r", "r" } },
2520    { INDEX_op_ld_i64, { "r", "r" } },
2521
2522    { INDEX_op_st8_i64, { "r", "r" } },
2523    { INDEX_op_st16_i64, { "r", "r" } },
2524    { INDEX_op_st32_i64, { "r", "r" } },
2525    { INDEX_op_st_i64, { "r", "r" } },
2526
2527    { INDEX_op_add_i64, { "r", "r", "rT" } },
2528    { INDEX_op_sub_i64, { "r", "rI", "rT" } },
2529    { INDEX_op_and_i64, { "r", "r", "ri" } },
2530    { INDEX_op_or_i64, { "r", "r", "rU" } },
2531    { INDEX_op_xor_i64, { "r", "r", "rU" } },
2532    { INDEX_op_andc_i64, { "r", "r", "ri" } },
2533    { INDEX_op_orc_i64, { "r", "r", "r" } },
2534    { INDEX_op_eqv_i64, { "r", "r", "r" } },
2535    { INDEX_op_nand_i64, { "r", "r", "r" } },
2536    { INDEX_op_nor_i64, { "r", "r", "r" } },
2537
2538    { INDEX_op_shl_i64, { "r", "r", "ri" } },
2539    { INDEX_op_shr_i64, { "r", "r", "ri" } },
2540    { INDEX_op_sar_i64, { "r", "r", "ri" } },
2541    { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2542    { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2543
2544    { INDEX_op_mul_i64, { "r", "r", "rI" } },
2545    { INDEX_op_div_i64, { "r", "r", "r" } },
2546    { INDEX_op_divu_i64, { "r", "r", "r" } },
2547
2548    { INDEX_op_neg_i64, { "r", "r" } },
2549    { INDEX_op_not_i64, { "r", "r" } },
2550    { INDEX_op_ext8s_i64, { "r", "r" } },
2551    { INDEX_op_ext16s_i64, { "r", "r" } },
2552    { INDEX_op_ext32s_i64, { "r", "r" } },
2553    { INDEX_op_ext_i32_i64, { "r", "r" } },
2554    { INDEX_op_extu_i32_i64, { "r", "r" } },
2555    { INDEX_op_bswap16_i64, { "r", "r" } },
2556    { INDEX_op_bswap32_i64, { "r", "r" } },
2557    { INDEX_op_bswap64_i64, { "r", "r" } },
2558
2559    { INDEX_op_brcond_i64, { "r", "ri" } },
2560    { INDEX_op_setcond_i64, { "r", "r", "ri" } },
2561    { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } },
2562
2563    { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
2564
2565    { INDEX_op_mulsh_i64, { "r", "r", "r" } },
2566    { INDEX_op_muluh_i64, { "r", "r", "r" } },
2567#endif
2568
2569#if TCG_TARGET_REG_BITS == 32
2570    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
2571    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
2572#endif
2573
2574#if TCG_TARGET_REG_BITS == 64
2575    { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
2576    { INDEX_op_sub2_i64, { "r", "r", "rI", "rZM", "r", "r" } },
2577#else
2578    { INDEX_op_add2_i32, { "r", "r", "r", "r", "rI", "rZM" } },
2579    { INDEX_op_sub2_i32, { "r", "r", "rI", "rZM", "r", "r" } },
2580#endif
2581
2582#if TCG_TARGET_REG_BITS == 64
2583    { INDEX_op_qemu_ld_i32, { "r", "L" } },
2584    { INDEX_op_qemu_st_i32, { "S", "S" } },
2585    { INDEX_op_qemu_ld_i64, { "r", "L" } },
2586    { INDEX_op_qemu_st_i64, { "S", "S" } },
2587#elif TARGET_LONG_BITS == 32
2588    { INDEX_op_qemu_ld_i32, { "r", "L" } },
2589    { INDEX_op_qemu_st_i32, { "S", "S" } },
2590    { INDEX_op_qemu_ld_i64, { "L", "L", "L" } },
2591    { INDEX_op_qemu_st_i64, { "S", "S", "S" } },
2592#else
2593    { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
2594    { INDEX_op_qemu_st_i32, { "S", "S", "S" } },
2595    { INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } },
2596    { INDEX_op_qemu_st_i64, { "S", "S", "S", "S" } },
2597#endif
2598
2599    { -1 },
2600};
2601
2602static void tcg_target_init(TCGContext *s)
2603{
2604    unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2605    if (hwcap & PPC_FEATURE_ARCH_2_06) {
2606        have_isa_2_06 = true;
2607    }
2608
2609    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
2610    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
2611    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2612                     (1 << TCG_REG_R0) |
2613                     (1 << TCG_REG_R2) |
2614                     (1 << TCG_REG_R3) |
2615                     (1 << TCG_REG_R4) |
2616                     (1 << TCG_REG_R5) |
2617                     (1 << TCG_REG_R6) |
2618                     (1 << TCG_REG_R7) |
2619                     (1 << TCG_REG_R8) |
2620                     (1 << TCG_REG_R9) |
2621                     (1 << TCG_REG_R10) |
2622                     (1 << TCG_REG_R11) |
2623                     (1 << TCG_REG_R12));
2624
2625    tcg_regset_clear(s->reserved_regs);
2626    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */
2627    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */
2628#if defined(_CALL_SYSV)
2629    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* toc pointer */
2630#endif
2631#if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64
2632    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
2633#endif
2634    tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */
2635    if (USE_REG_RA) {
2636        tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);  /* return addr */
2637    }
2638
2639    tcg_add_target_add_op_defs(ppc_op_defs);
2640}
2641
2642#ifdef __ELF__
2643typedef struct {
2644    DebugFrameCIE cie;
2645    DebugFrameFDEHeader fde;
2646    uint8_t fde_def_cfa[4];
2647    uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
2648} DebugFrame;
2649
2650/* We're expecting a 2 byte uleb128 encoded value.  */
2651QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2652
2653#if TCG_TARGET_REG_BITS == 64
2654# define ELF_HOST_MACHINE EM_PPC64
2655#else
2656# define ELF_HOST_MACHINE EM_PPC
2657#endif
2658
2659static DebugFrame debug_frame = {
2660    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2661    .cie.id = -1,
2662    .cie.version = 1,
2663    .cie.code_align = 1,
2664    .cie.data_align = (-SZR & 0x7f),         /* sleb128 -SZR */
2665    .cie.return_column = 65,
2666
2667    /* Total FDE size does not include the "len" member.  */
2668    .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2669
2670    .fde_def_cfa = {
2671        12, TCG_REG_R1,                 /* DW_CFA_def_cfa r1, ... */
2672        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2673        (FRAME_SIZE >> 7)
2674    },
2675    .fde_reg_ofs = {
2676        /* DW_CFA_offset_extended_sf, lr, LR_OFFSET */
2677        0x11, 65, (LR_OFFSET / -SZR) & 0x7f,
2678    }
2679};
2680
2681void tcg_register_jit(void *buf, size_t buf_size)
2682{
2683    uint8_t *p = &debug_frame.fde_reg_ofs[3];
2684    int i;
2685
2686    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
2687        p[0] = 0x80 + tcg_target_callee_save_regs[i];
2688        p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * SZR)) / SZR;
2689    }
2690
2691    debug_frame.fde.func_start = (uintptr_t)buf;
2692    debug_frame.fde.func_len = buf_size;
2693
2694    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2695}
2696#endif /* __ELF__ */
2697
2698static size_t dcache_bsize = 16;
2699static size_t icache_bsize = 16;
2700
2701void flush_icache_range(uintptr_t start, uintptr_t stop)
2702{
2703    uintptr_t p, start1, stop1;
2704    size_t dsize = dcache_bsize;
2705    size_t isize = icache_bsize;
2706
2707    start1 = start & ~(dsize - 1);
2708    stop1 = (stop + dsize - 1) & ~(dsize - 1);
2709    for (p = start1; p < stop1; p += dsize) {
2710        asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
2711    }
2712    asm volatile ("sync" : : : "memory");
2713
2714    start &= start & ~(isize - 1);
2715    stop1 = (stop + isize - 1) & ~(isize - 1);
2716    for (p = start1; p < stop1; p += isize) {
2717        asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
2718    }
2719    asm volatile ("sync" : : : "memory");
2720    asm volatile ("isync" : : : "memory");
2721}
2722
2723#if defined _AIX
2724#include <sys/systemcfg.h>
2725
2726static void __attribute__((constructor)) tcg_cache_init(void)
2727{
2728    icache_bsize = _system_configuration.icache_line;
2729    dcache_bsize = _system_configuration.dcache_line;
2730}
2731
2732#elif defined __linux__
2733static void __attribute__((constructor)) tcg_cache_init(void)
2734{
2735    unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
2736    unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
2737
2738    if (dsize == 0 || isize == 0) {
2739        if (dsize == 0) {
2740            fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
2741        }
2742        if (isize == 0) {
2743            fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
2744        }
2745        exit(1);
2746    }
2747    dcache_bsize = dsize;
2748    icache_bsize = isize;
2749}
2750
2751#elif defined __APPLE__
2752#include <sys/sysctl.h>
2753
2754static void __attribute__((constructor)) tcg_cache_init(void)
2755{
2756    size_t len;
2757    unsigned cacheline;
2758    int name[2] = { CTL_HW, HW_CACHELINE };
2759
2760    len = sizeof(cacheline);
2761    if (sysctl(name, 2, &cacheline, &len, NULL, 0)) {
2762        perror("sysctl CTL_HW HW_CACHELINE failed");
2763        exit(1);
2764    }
2765    dcache_bsize = cacheline;
2766    icache_bsize = cacheline;
2767}
2768
2769#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2770#include <sys/sysctl.h>
2771
2772static void __attribute__((constructor)) tcg_cache_init(void)
2773{
2774    size_t len = 4;
2775    unsigned cacheline;
2776
2777    if (sysctlbyname ("machdep.cacheline_size", &cacheline, &len, NULL, 0)) {
2778        fprintf(stderr, "sysctlbyname machdep.cacheline_size failed: %s\n",
2779                strerror(errno));
2780        exit(1);
2781    }
2782    dcache_bsize = cacheline;
2783    icache_bsize = cacheline;
2784}
2785#endif
2786