Home | History | Annotate | Download | only in priv
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                                   host_ppc_defs.c ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2004-2017 OpenWorks LLP
     11       info (at) open-works.net
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     26    02110-1301, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 
     30    Neither the names of the U.S. Department of Energy nor the
     31    University of California nor the names of its contributors may be
     32    used to endorse or promote products derived from this software
     33    without prior written permission.
     34 */
     35 
     36 #include "libvex_basictypes.h"
     37 #include "libvex.h"
     38 #include "libvex_trc_values.h"
     39 
     40 #include "main_util.h"
     41 #include "host_generic_regs.h"
     42 #include "host_ppc_defs.h"
     43 
     44 
     45 /* --------- Registers. --------- */
     46 
     47 const RRegUniverse* getRRegUniverse_PPC ( Bool mode64 )
     48 {
     49    /* The real-register universe is a big constant, so we just want to
     50       initialise it once.  rRegUniverse_PPC_initted values: 0=not initted,
     51       1=initted for 32-bit-mode, 2=initted for 64-bit-mode */
     52    static RRegUniverse rRegUniverse_PPC;
     53    static UInt         rRegUniverse_PPC_initted = 0;
     54 
     55    /* Handy shorthand, nothing more */
     56    RRegUniverse* ru = &rRegUniverse_PPC;
     57 
     58    /* This isn't thread-safe.  Sigh. */
     59    UInt howNeeded = mode64 ? 2 : 1;
     60    if (LIKELY(rRegUniverse_PPC_initted == howNeeded))
     61       return ru;
     62 
     63    RRegUniverse__init(ru);
     64 
     65    /* Add the registers.  The initial segment of this array must be
     66       those available for allocation by reg-alloc, and those that
     67       follow are not available for allocation. */
     68    // GPR0 = scratch reg where poss. - some ops interpret as value zero
     69    // GPR1 = stack pointer
     70    // GPR2 = TOC pointer
     71    ru->regs[ru->size++] = hregPPC_GPR3(mode64);
     72    ru->regs[ru->size++] = hregPPC_GPR4(mode64);
     73    ru->regs[ru->size++] = hregPPC_GPR5(mode64);
     74    ru->regs[ru->size++] = hregPPC_GPR6(mode64);
     75    ru->regs[ru->size++] = hregPPC_GPR7(mode64);
     76    ru->regs[ru->size++] = hregPPC_GPR8(mode64);
     77    ru->regs[ru->size++] = hregPPC_GPR9(mode64);
     78    ru->regs[ru->size++] = hregPPC_GPR10(mode64);
     79    if (!mode64) {
     80       /* in mode64:
     81          r11 used for calls by ptr / env ptr for some langs
     82          r12 used for exception handling and global linkage code */
     83       ru->regs[ru->size++] = hregPPC_GPR11(mode64);
     84       ru->regs[ru->size++] = hregPPC_GPR12(mode64);
     85    }
     86    // GPR13 = thread specific pointer
     87    // GPR14 and above are callee save.  Yay.
     88    ru->regs[ru->size++] = hregPPC_GPR14(mode64);
     89    ru->regs[ru->size++] = hregPPC_GPR15(mode64);
     90    ru->regs[ru->size++] = hregPPC_GPR16(mode64);
     91    ru->regs[ru->size++] = hregPPC_GPR17(mode64);
     92    ru->regs[ru->size++] = hregPPC_GPR18(mode64);
     93    ru->regs[ru->size++] = hregPPC_GPR19(mode64);
     94    ru->regs[ru->size++] = hregPPC_GPR20(mode64);
     95    ru->regs[ru->size++] = hregPPC_GPR21(mode64);
     96    ru->regs[ru->size++] = hregPPC_GPR22(mode64);
     97    ru->regs[ru->size++] = hregPPC_GPR23(mode64);
     98    ru->regs[ru->size++] = hregPPC_GPR24(mode64);
     99    ru->regs[ru->size++] = hregPPC_GPR25(mode64);
    100    ru->regs[ru->size++] = hregPPC_GPR26(mode64);
    101    ru->regs[ru->size++] = hregPPC_GPR27(mode64);
    102    ru->regs[ru->size++] = hregPPC_GPR28(mode64);
    103    // GPR29 is reserved for the dispatcher
    104    // GPR30 is reserved as AltiVec spill reg temporary
    105    // GPR31 is reserved for the GuestStatePtr
    106 
    107    /* Don't waste the reg-allocs's time trawling through zillions of
    108       FP registers - they mostly will never be used.  We'll tolerate
    109       the occasional extra spill instead. */
    110    /* For both ppc32-linux and ppc64-linux, f14-f31 are callee save.
    111       So use them. */
    112    ru->regs[ru->size++] = hregPPC_FPR14(mode64);
    113    ru->regs[ru->size++] = hregPPC_FPR15(mode64);
    114    ru->regs[ru->size++] = hregPPC_FPR16(mode64);
    115    ru->regs[ru->size++] = hregPPC_FPR17(mode64);
    116    ru->regs[ru->size++] = hregPPC_FPR18(mode64);
    117    ru->regs[ru->size++] = hregPPC_FPR19(mode64);
    118    ru->regs[ru->size++] = hregPPC_FPR20(mode64);
    119    ru->regs[ru->size++] = hregPPC_FPR21(mode64);
    120 
    121    /* Same deal re Altivec */
    122    /* For both ppc32-linux and ppc64-linux, v20-v31 are callee save.
    123       So use them. */
    124    /* NB, vr29 is used as a scratch temporary -- do not allocate */
    125    ru->regs[ru->size++] = hregPPC_VR20(mode64);
    126    ru->regs[ru->size++] = hregPPC_VR21(mode64);
    127    ru->regs[ru->size++] = hregPPC_VR22(mode64);
    128    ru->regs[ru->size++] = hregPPC_VR23(mode64);
    129    ru->regs[ru->size++] = hregPPC_VR24(mode64);
    130    ru->regs[ru->size++] = hregPPC_VR25(mode64);
    131    ru->regs[ru->size++] = hregPPC_VR26(mode64);
    132    ru->regs[ru->size++] = hregPPC_VR27(mode64);
    133    ru->allocable = ru->size;
    134 
    135    /* And other regs, not available to the allocator. */
    136    ru->regs[ru->size++] = hregPPC_GPR1(mode64);
    137    ru->regs[ru->size++] = hregPPC_GPR29(mode64);
    138    ru->regs[ru->size++] = hregPPC_GPR30(mode64);
    139    ru->regs[ru->size++] = hregPPC_GPR31(mode64);
    140    ru->regs[ru->size++] = hregPPC_VR29(mode64);
    141 
    142    rRegUniverse_PPC_initted = howNeeded;
    143 
    144    RRegUniverse__check_is_sane(ru);
    145    return ru;
    146 }
    147 
    148 
    149 void ppHRegPPC ( HReg reg )
    150 {
    151    Int r;
    152    static const HChar* ireg32_names[32]
    153       = { "%r0",  "%r1",  "%r2",  "%r3",
    154           "%r4",  "%r5",  "%r6",  "%r7",
    155           "%r8",  "%r9",  "%r10", "%r11",
    156           "%r12", "%r13", "%r14", "%r15",
    157           "%r16", "%r17", "%r18", "%r19",
    158           "%r20", "%r21", "%r22", "%r23",
    159           "%r24", "%r25", "%r26", "%r27",
    160           "%r28", "%r29", "%r30", "%r31" };
    161    /* Be generic for all virtual regs. */
    162    if (hregIsVirtual(reg)) {
    163       ppHReg(reg);
    164       return;
    165    }
    166    /* But specific for real regs. */
    167    switch (hregClass(reg)) {
    168    case HRcInt64:
    169       r = hregEncoding(reg);
    170       vassert(r >= 0 && r < 32);
    171       vex_printf("%s", ireg32_names[r]);
    172       return;
    173    case HRcInt32:
    174       r = hregEncoding(reg);
    175       vassert(r >= 0 && r < 32);
    176       vex_printf("%s", ireg32_names[r]);
    177       return;
    178    case HRcFlt64:
    179       r = hregEncoding(reg);
    180       vassert(r >= 0 && r < 32);
    181       vex_printf("%%fr%d", r);
    182       return;
    183    case HRcVec128:
    184       r = hregEncoding(reg);
    185       vassert(r >= 0 && r < 32);
    186       vex_printf("%%v%d", r);
    187       return;
    188    default:
    189       vpanic("ppHRegPPC");
    190    }
    191 }
    192 
    193 
    194 /* --------- Condition codes, Intel encoding. --------- */
    195 
    196 const HChar* showPPCCondCode ( PPCCondCode cond )
    197 {
    198    if (cond.test == Pct_ALWAYS) return "always";
    199 
    200    switch (cond.flag) {
    201    case Pcf_7SO:
    202       return (cond.test == Pct_TRUE) ? "cr7.so=1" : "cr7.so=0";
    203    case Pcf_7EQ:
    204       return (cond.test == Pct_TRUE) ? "cr7.eq=1" : "cr7.eq=0";
    205    case Pcf_7GT:
    206       return (cond.test == Pct_TRUE) ? "cr7.gt=1" : "cr7.gt=0";
    207    case Pcf_7LT:
    208       return (cond.test == Pct_TRUE) ? "cr7.lt=1" : "cr7.lt=0";
    209    case Pcf_NONE:
    210       return "no-flag";
    211    default: vpanic("ppPPCCondCode");
    212    }
    213 }
    214 
    215 /* construct condition code */
    216 PPCCondCode mk_PPCCondCode ( PPCCondTest test, PPCCondFlag flag )
    217 {
    218    PPCCondCode cc;
    219    cc.flag = flag;
    220    cc.test = test;
    221    if (test == Pct_ALWAYS) {
    222       vassert(flag == Pcf_NONE);
    223    } else {
    224       vassert(flag != Pcf_NONE);
    225    }
    226    return cc;
    227 }
    228 
    229 /* false->true, true->false */
    230 PPCCondTest invertCondTest ( PPCCondTest ct )
    231 {
    232    vassert(ct != Pct_ALWAYS);
    233    return (ct == Pct_TRUE) ? Pct_FALSE : Pct_TRUE;
    234 }
    235 
    236 
    237 /* --------- PPCAMode: memory address expressions. --------- */
    238 
    239 PPCAMode* PPCAMode_IR ( Int idx, HReg base ) {
    240    PPCAMode* am = LibVEX_Alloc_inline(sizeof(PPCAMode));
    241    vassert(idx >= -0x8000 && idx < 0x8000);
    242    am->tag = Pam_IR;
    243    am->Pam.IR.base = base;
    244    am->Pam.IR.index = idx;
    245    return am;
    246 }
    247 PPCAMode* PPCAMode_RR ( HReg idx, HReg base ) {
    248    PPCAMode* am = LibVEX_Alloc_inline(sizeof(PPCAMode));
    249    am->tag = Pam_RR;
    250    am->Pam.RR.base = base;
    251    am->Pam.RR.index = idx;
    252    return am;
    253 }
    254 
    255 PPCAMode* dopyPPCAMode ( PPCAMode* am ) {
    256    switch (am->tag) {
    257    case Pam_IR:
    258       return PPCAMode_IR( am->Pam.IR.index, am->Pam.IR.base );
    259    case Pam_RR:
    260       return PPCAMode_RR( am->Pam.RR.index, am->Pam.RR.base );
    261    default:
    262       vpanic("dopyPPCAMode");
    263    }
    264 }
    265 
    266 void ppPPCAMode ( PPCAMode* am ) {
    267    switch (am->tag) {
    268    case Pam_IR:
    269       if (am->Pam.IR.index == 0)
    270          vex_printf("0(");
    271       else
    272          vex_printf("%d(", (Int)am->Pam.IR.index);
    273       ppHRegPPC(am->Pam.IR.base);
    274       vex_printf(")");
    275       return;
    276    case Pam_RR:
    277       ppHRegPPC(am->Pam.RR.base);
    278       vex_printf(",");
    279       ppHRegPPC(am->Pam.RR.index);
    280       return;
    281    default:
    282       vpanic("ppPPCAMode");
    283    }
    284 }
    285 
    286 static void addRegUsage_PPCAMode ( HRegUsage* u, PPCAMode* am ) {
    287    switch (am->tag) {
    288    case Pam_IR:
    289       addHRegUse(u, HRmRead, am->Pam.IR.base);
    290       return;
    291    case Pam_RR:
    292       addHRegUse(u, HRmRead, am->Pam.RR.base);
    293       addHRegUse(u, HRmRead, am->Pam.RR.index);
    294       return;
    295    default:
    296       vpanic("addRegUsage_PPCAMode");
    297    }
    298 }
    299 
    300 static void mapRegs_PPCAMode ( HRegRemap* m, PPCAMode* am ) {
    301    switch (am->tag) {
    302    case Pam_IR:
    303       am->Pam.IR.base = lookupHRegRemap(m, am->Pam.IR.base);
    304       return;
    305    case Pam_RR:
    306       am->Pam.RR.base = lookupHRegRemap(m, am->Pam.RR.base);
    307       am->Pam.RR.index = lookupHRegRemap(m, am->Pam.RR.index);
    308       return;
    309    default:
    310       vpanic("mapRegs_PPCAMode");
    311    }
    312 }
    313 
    314 /* --------- Operand, which can be a reg or a u16/s16. --------- */
    315 
    316 PPCRH* PPCRH_Imm ( Bool syned, UShort imm16 ) {
    317    PPCRH* op         = LibVEX_Alloc_inline(sizeof(PPCRH));
    318    op->tag           = Prh_Imm;
    319    op->Prh.Imm.syned = syned;
    320    op->Prh.Imm.imm16 = imm16;
    321    /* If this is a signed value, ensure it's not -32768, so that we
    322       are guaranteed always to be able to negate if needed. */
    323    if (syned)
    324       vassert(imm16 != 0x8000);
    325    vassert(syned == True || syned == False);
    326    return op;
    327 }
    328 PPCRH* PPCRH_Reg ( HReg reg ) {
    329    PPCRH* op       = LibVEX_Alloc_inline(sizeof(PPCRH));
    330    op->tag         = Prh_Reg;
    331    op->Prh.Reg.reg = reg;
    332    return op;
    333 }
    334 
    335 void ppPPCRH ( PPCRH* op ) {
    336    switch (op->tag) {
    337    case Prh_Imm:
    338       if (op->Prh.Imm.syned)
    339          vex_printf("%d", (Int)(Short)op->Prh.Imm.imm16);
    340       else
    341          vex_printf("%u", (UInt)(UShort)op->Prh.Imm.imm16);
    342       return;
    343    case Prh_Reg:
    344       ppHRegPPC(op->Prh.Reg.reg);
    345       return;
    346    default:
    347       vpanic("ppPPCRH");
    348    }
    349 }
    350 
    351 /* An PPCRH can only be used in a "read" context (what would it mean
    352    to write or modify a literal?) and so we enumerate its registers
    353    accordingly. */
    354 static void addRegUsage_PPCRH ( HRegUsage* u, PPCRH* op ) {
    355    switch (op->tag) {
    356    case Prh_Imm:
    357       return;
    358    case Prh_Reg:
    359       addHRegUse(u, HRmRead, op->Prh.Reg.reg);
    360       return;
    361    default:
    362       vpanic("addRegUsage_PPCRH");
    363    }
    364 }
    365 
    366 static void mapRegs_PPCRH ( HRegRemap* m, PPCRH* op ) {
    367    switch (op->tag) {
    368    case Prh_Imm:
    369       return;
    370    case Prh_Reg:
    371       op->Prh.Reg.reg = lookupHRegRemap(m, op->Prh.Reg.reg);
    372       return;
    373    default:
    374       vpanic("mapRegs_PPCRH");
    375    }
    376 }
    377 
    378 
    379 /* --------- Operand, which can be a reg or a u32/64. --------- */
    380 
    381 PPCRI* PPCRI_Imm ( ULong imm64 ) {
    382    PPCRI* op   = LibVEX_Alloc_inline(sizeof(PPCRI));
    383    op->tag     = Pri_Imm;
    384    op->Pri.Imm = imm64;
    385    return op;
    386 }
    387 PPCRI* PPCRI_Reg ( HReg reg ) {
    388    PPCRI* op   = LibVEX_Alloc_inline(sizeof(PPCRI));
    389    op->tag     = Pri_Reg;
    390    op->Pri.Reg = reg;
    391    return op;
    392 }
    393 
    394 void ppPPCRI ( PPCRI* dst ) {
    395    switch (dst->tag) {
    396       case Pri_Imm:
    397          vex_printf("0x%llx", dst->Pri.Imm);
    398          break;
    399       case Pri_Reg:
    400          ppHRegPPC(dst->Pri.Reg);
    401          break;
    402       default:
    403          vpanic("ppPPCRI");
    404    }
    405 }
    406 
    407 /* An PPCRI can only be used in a "read" context (what would it
    408    mean to write or modify a literal?) and so we enumerate its
    409    registers accordingly. */
    410 static void addRegUsage_PPCRI ( HRegUsage* u, PPCRI* dst ) {
    411    switch (dst->tag) {
    412       case Pri_Imm:
    413          return;
    414       case Pri_Reg:
    415          addHRegUse(u, HRmRead, dst->Pri.Reg);
    416          return;
    417       default:
    418          vpanic("addRegUsage_PPCRI");
    419    }
    420 }
    421 
    422 static void mapRegs_PPCRI ( HRegRemap* m, PPCRI* dst ) {
    423    switch (dst->tag) {
    424       case Pri_Imm:
    425          return;
    426       case Pri_Reg:
    427          dst->Pri.Reg = lookupHRegRemap(m, dst->Pri.Reg);
    428          return;
    429       default:
    430          vpanic("mapRegs_PPCRI");
    431    }
    432 }
    433 
    434 
    435 /* --------- Operand, which can be a vector reg or a simm5. --------- */
    436 
    437 PPCVI5s* PPCVI5s_Imm ( Char simm5 ) {
    438    PPCVI5s* op   = LibVEX_Alloc_inline(sizeof(PPCVI5s));
    439    op->tag       = Pvi_Imm;
    440    op->Pvi.Imm5s = simm5;
    441    vassert(simm5 >= -16 && simm5 <= 15);
    442    return op;
    443 }
    444 PPCVI5s* PPCVI5s_Reg ( HReg reg ) {
    445    PPCVI5s* op = LibVEX_Alloc_inline(sizeof(PPCVI5s));
    446    op->tag     = Pvi_Reg;
    447    op->Pvi.Reg = reg;
    448    vassert(hregClass(reg) == HRcVec128);
    449    return op;
    450 }
    451 
    452 void ppPPCVI5s ( PPCVI5s* src ) {
    453    switch (src->tag) {
    454       case Pvi_Imm:
    455          vex_printf("%d", (Int)src->Pvi.Imm5s);
    456          break;
    457       case Pvi_Reg:
    458          ppHRegPPC(src->Pvi.Reg);
    459          break;
    460       default:
    461          vpanic("ppPPCVI5s");
    462    }
    463 }
    464 
    465 /* An PPCVI5s can only be used in a "read" context (what would it
    466    mean to write or modify a literal?) and so we enumerate its
    467    registers accordingly. */
    468 static void addRegUsage_PPCVI5s ( HRegUsage* u, PPCVI5s* dst ) {
    469    switch (dst->tag) {
    470       case Pvi_Imm:
    471          return;
    472       case Pvi_Reg:
    473          addHRegUse(u, HRmRead, dst->Pvi.Reg);
    474          return;
    475       default:
    476          vpanic("addRegUsage_PPCVI5s");
    477    }
    478 }
    479 
    480 static void mapRegs_PPCVI5s ( HRegRemap* m, PPCVI5s* dst ) {
    481    switch (dst->tag) {
    482       case Pvi_Imm:
    483          return;
    484       case Pvi_Reg:
    485          dst->Pvi.Reg = lookupHRegRemap(m, dst->Pvi.Reg);
    486          return;
    487       default:
    488          vpanic("mapRegs_PPCVI5s");
    489    }
    490 }
    491 
    492 
    493 /* --------- Instructions. --------- */
    494 
    495 const HChar* showPPCUnaryOp ( PPCUnaryOp op ) {
    496    switch (op) {
    497    case Pun_NOT:   return "not";
    498    case Pun_NEG:   return "neg";
    499    case Pun_CLZ32: return "cntlzw";
    500    case Pun_CLZ64: return "cntlzd";
    501    case Pun_CTZ32: return "cnttzw";
    502    case Pun_CTZ64: return "cnttzd";
    503    case Pun_EXTSW: return "extsw";
    504    default: vpanic("showPPCUnaryOp");
    505    }
    506 }
    507 
    508 const HChar* showPPCAluOp ( PPCAluOp op, Bool immR ) {
    509    switch (op) {
    510       case Palu_ADD: return immR ? "addi"  : "add";
    511       case Palu_SUB: return immR ? "subi"  : "sub";
    512       case Palu_AND: return immR ? "andi." : "and";
    513       case Palu_OR:  return immR ? "ori"   : "or";
    514       case Palu_XOR: return immR ? "xori"  : "xor";
    515       default: vpanic("showPPCAluOp");
    516    }
    517 }
    518 
    519 const HChar* showPPCShftOp ( PPCShftOp op, Bool immR, Bool sz32 ) {
    520    switch (op) {
    521       case Pshft_SHL: return sz32 ? (immR ? "slwi"  : "slw") :
    522                                     (immR ? "sldi"  : "sld");
    523       case Pshft_SHR: return sz32 ? (immR ? "srwi"  : "srw") :
    524                                     (immR ? "srdi"  : "srd");
    525       case Pshft_SAR: return sz32 ? (immR ? "srawi" : "sraw") :
    526                                     (immR ? "sradi" : "srad");
    527       default: vpanic("showPPCShftOp");
    528    }
    529 }
    530 
    531 const HChar* showPPCFpOp ( PPCFpOp op ) {
    532    switch (op) {
    533       case Pfp_ADDD:   return "fadd";
    534       case Pfp_SUBD:   return "fsub";
    535       case Pfp_MULD:   return "fmul";
    536       case Pfp_DIVD:   return "fdiv";
    537       case Pfp_MADDD:  return "fmadd";
    538       case Pfp_MSUBD:  return "fmsub";
    539       case Pfp_MADDS:  return "fmadds";
    540       case Pfp_MSUBS:  return "fmsubs";
    541       case Pfp_ADDS:   return "fadds";
    542       case Pfp_SUBS:   return "fsubs";
    543       case Pfp_MULS:   return "fmuls";
    544       case Pfp_DIVS:   return "fdivs";
    545       case Pfp_SQRT:   return "fsqrt";
    546       case Pfp_ABS:    return "fabs";
    547       case Pfp_NEG:    return "fneg";
    548       case Pfp_MOV:    return "fmr";
    549       case Pfp_RES:    return "fres";
    550       case Pfp_RSQRTE: return "frsqrte";
    551       case Pfp_FRIM:   return "frim";
    552       case Pfp_FRIN:   return "frin";
    553       case Pfp_FRIP:   return "frip";
    554       case Pfp_FRIZ:   return "friz";
    555       case Pfp_FPADDQ:     return "xsaddqp";
    556       case Pfp_FPSUBQ:     return "xsubqp";
    557       case Pfp_FPMULQ:     return "xsmulqp";
    558       case Pfp_FPDIVQ:     return "xsdivqp";
    559       case Pfp_FPMULADDQ:        return "xsmaddqp";
    560       case Pfp_FPMULSUBQ:        return "xsmsubqp";
    561       case Pfp_FPNEGMULADDQ:     return "xsnmaddqp";
    562       case Pfp_FPNEGMULSUBQ:     return "xsnmsubqp";
    563       case Pfp_FPADDQRNDODD:     return "xsaddqpo";
    564       case Pfp_FPSUBQRNDODD:     return "xsubqpo";
    565       case Pfp_FPMULQRNDODD:     return "xsmulqpo";
    566       case Pfp_FPDIVQRNDODD:     return "xsaddqpo";
    567       case Pfp_FPMULADDQRNDODD:      return "xsmaddqpo";
    568       case Pfp_FPMULSUBQRNDODD:      return "xsmsubqpo";
    569       case Pfp_FPNEGMULADDQRNDODD:   return "xsnmaddqpo";
    570       case Pfp_FPNEGMULSUBQRNDODD:   return "xsnmsubqpo";
    571       case Pfp_FPQTOD:               return "xscvqpdp";
    572       case Pfp_FPQTODRNDODD:         return "xscvqpdpo";
    573       case Pfp_FPDTOQ:               return "xscvdpqp";
    574       case Pfp_IDSTOQ:               return "xscvsdqp";
    575       case Pfp_IDUTOQ:               return "xscvudqp";
    576       case Pfp_TRUNCFPQTOISD:        return "xscvqpsdz";
    577       case Pfp_TRUNCFPQTOISW:        return "xscvqpswz";
    578       case Pfp_TRUNCFPQTOIUD:        return "xscvqpudz";
    579       case Pfp_TRUNCFPQTOIUW:        return "xscvqpuwz";
    580       case Pfp_DFPADD:     return "dadd";
    581       case Pfp_DFPADDQ:    return "daddq";
    582       case Pfp_DFPSUB:     return "dsub";
    583       case Pfp_DFPSUBQ:    return "dsubq";
    584       case Pfp_DFPMUL:     return "dmul";
    585       case Pfp_DFPMULQ:    return "dmulq";
    586       case Pfp_DFPDIV:     return "ddivd";
    587       case Pfp_DFPDIVQ:    return "ddivq";
    588       case Pfp_DCTDP:      return "dctdp";
    589       case Pfp_DRSP:       return "drsp";
    590       case Pfp_DCTFIX:     return "dctfix";
    591       case Pfp_DCFFIX:     return "dcffix";
    592       case Pfp_DCTQPQ:     return "dctqpq";
    593       case Pfp_DCFFIXQ:    return "dcffixq";
    594       case Pfp_DQUA:       return "dqua";
    595       case Pfp_DQUAQ:      return "dquaq";
    596       case Pfp_DXEX:       return "dxex";
    597       case Pfp_DXEXQ:      return "dxexq";
    598       case Pfp_DIEX:       return "diex";
    599       case Pfp_DIEXQ:      return "diexq";
    600       case Pfp_RRDTR:      return "rrdtr";
    601       default: vpanic("showPPCFpOp");
    602    }
    603 }
    604 
    605 const HChar* showPPCAvOp ( PPCAvOp op ) {
    606    switch (op) {
    607 
    608    /* Unary */
    609    case Pav_MOV:       return "vmr";      /* Mov */
    610 
    611    case Pav_AND:       return "vand";     /* Bitwise */
    612    case Pav_OR:        return "vor";
    613    case Pav_XOR:       return "vxor";
    614    case Pav_NOT:       return "vnot";
    615 
    616    case Pav_UNPCKH8S:  return "vupkhsb";  /* Unpack */
    617    case Pav_UNPCKH16S: return "vupkhsh";
    618    case Pav_UNPCKL8S:  return "vupklsb";
    619    case Pav_UNPCKL16S: return "vupklsh";
    620    case Pav_UNPCKHPIX: return "vupkhpx";
    621    case Pav_UNPCKLPIX: return "vupklpx";
    622 
    623    /* Integer binary */
    624    case Pav_ADDU:      return "vaddu_m";  // b,h,w,dw
    625    case Pav_QADDU:     return "vaddu_s";  // b,h,w,dw
    626    case Pav_QADDS:     return "vadds_s";  // b,h,w,dw
    627 
    628    case Pav_SUBU:      return "vsubu_m";  // b,h,w,dw
    629    case Pav_QSUBU:     return "vsubu_s";  // b,h,w,dw
    630    case Pav_QSUBS:     return "vsubs_s";  // b,h,w,dw
    631 
    632    case Pav_MULU:      return "vmulu";    // w
    633    case Pav_OMULU:     return "vmulou";   // b,h,w
    634    case Pav_OMULS:     return "vmulos";   // b,h,w
    635    case Pav_EMULU:     return "vmuleu";   // b,h,w
    636    case Pav_EMULS:     return "vmules";   // b,h,w
    637 
    638    case Pav_AVGU:      return "vavgu";    // b,h,w
    639    case Pav_AVGS:      return "vavgs";    // b,h,w
    640 
    641    case Pav_MAXU:      return "vmaxu";    // b,h,w
    642    case Pav_MAXS:      return "vmaxs";    // b,h,w
    643 
    644    case Pav_MINU:      return "vminu";    // b,h,w
    645    case Pav_MINS:      return "vmins";    // b,h,w
    646 
    647    /* Compare (always affects CR field 6) */
    648    case Pav_CMPEQU:    return "vcmpequ";  // b,h,w
    649    case Pav_CMPGTU:    return "vcmpgtu";  // b,h,w
    650    case Pav_CMPGTS:    return "vcmpgts";  // b,h,w
    651 
    652    /* Shift */
    653    case Pav_SHL:       return "vsl";      // ' ',b,h,w,dw
    654    case Pav_SHR:       return "vsr";      // ' ',b,h,w,dw
    655    case Pav_SAR:       return "vsra";     // b,h,w,dw
    656    case Pav_ROTL:      return "vrl";      // b,h,w,dw
    657 
    658    /* Pack */
    659    case Pav_PACKUU:    return "vpku_um";  // h,w,dw
    660    case Pav_QPACKUU:   return "vpku_us";  // h,w
    661    case Pav_QPACKSU:   return "vpks_us";  // h,w
    662    case Pav_QPACKSS:   return "vpks_ss";  // h,w
    663    case Pav_PACKPXL:   return "vpkpx";
    664 
    665    /* Merge */
    666    case Pav_MRGHI:     return "vmrgh";    // b,h,w
    667    case Pav_MRGLO:     return "vmrgl";    // b,h,w
    668 
    669    /* Concatenation */
    670    case Pav_CATODD:     return "vmrgow";    // w
    671    case Pav_CATEVEN:    return "vmrgew";    // w
    672 
    673    /* SHA */
    674    case Pav_SHA256:     return "vshasigmaw"; // w
    675    case Pav_SHA512:     return "vshasigmaw"; // dw
    676 
    677    /* BCD */
    678    case Pav_BCDAdd:     return "bcdadd.";  // qw
    679    case Pav_BCDSub:     return "bcdsub.";  // qw
    680    case Pav_I128StoBCD128: return  "bcdcfsq.";  //qw
    681    case Pav_BCD128toI128S: return  "bcdctsq.";  //qw
    682 
    683    /* I128 mult by 10 */
    684    case Pav_MulI128by10:       return  "vmul10uq";  //qw
    685    case Pav_MulI128by10Carry:  return  "vmul10cuq";  //qw
    686    case Pav_MulI128by10E:      return  "vmul10euq";  //qw
    687    case Pav_MulI128by10ECarry: return  "vmul10ecuq";  //qw
    688 
    689       /* F128 to I128 signed */
    690    case Pav_F128toI128S:    return "xsrqpi|x";   //qw
    691 
    692       /* F128 round to F128 */
    693    case Pav_ROUNDFPQ:       return "xsrqpxp";
    694 
    695    /* Polynomial arith */
    696    case Pav_POLYMULADD: return "vpmsum";   // b, h, w, d
    697 
    698    /* Cipher */
    699    case Pav_CIPHERV128:  case Pav_CIPHERLV128:
    700    case Pav_NCIPHERV128: case Pav_NCIPHERLV128:
    701    case Pav_CIPHERSUBV128: return "v_cipher_";  // qw
    702 
    703    /* zero count */
    704    case Pav_ZEROCNTBYTE: case Pav_ZEROCNTWORD:
    705    case Pav_ZEROCNTHALF: case Pav_ZEROCNTDBL:
    706       return "vclz_";                           // b, h, w, d
    707 
    708    /* trailing zero count */
    709    case Pav_TRAILINGZEROCNTBYTE: case Pav_TRAILINGZEROCNTWORD:
    710    case Pav_TRAILINGZEROCNTHALF: case Pav_TRAILINGZEROCNTDBL:
    711       return "vctz_";                           // b, h, w, d
    712 
    713    /* vector gather (byte-by-byte bit matrix transpose) */
    714    case Pav_BITMTXXPOSE:
    715       return "vgbbd";
    716 
    717    /* Vector Half-precision format to single precision conversion */
    718    case Pav_F16toF32x4:
    719       return"xvcvhpsp";
    720 
    721    /* Vector Single-precision format to Half-precision conversion */
    722    case Pav_F32toF16x4:
    723       return"xvcvsphp";
    724 
    725    /* Vector Half-precision format to Double precision conversion */
    726    case Pav_F16toF64x2:
    727       return"xvcvhpdp";
    728 
    729       /* Vector Half-precision format to Double precision conversion */
    730    case Pav_F64toF16x2:
    731       return"xvcvdphp";
    732 
    733    default: vpanic("showPPCAvOp");
    734    }
    735 }
    736 
    737 const HChar* showPPCAvFpOp ( PPCAvFpOp op ) {
    738    switch (op) {
    739    /* Floating Point Binary */
    740    case Pavfp_ADDF:      return "vaddfp";
    741    case Pavfp_SUBF:      return "vsubfp";
    742    case Pavfp_MULF:      return "vmaddfp";
    743    case Pavfp_MAXF:      return "vmaxfp";
    744    case Pavfp_MINF:      return "vminfp";
    745    case Pavfp_CMPEQF:    return "vcmpeqfp";
    746    case Pavfp_CMPGTF:    return "vcmpgtfp";
    747    case Pavfp_CMPGEF:    return "vcmpgefp";
    748 
    749    /* Floating Point Unary */
    750    case Pavfp_RCPF:      return "vrefp";
    751    case Pavfp_RSQRTF:    return "vrsqrtefp";
    752    case Pavfp_CVTU2F:    return "vcfux";
    753    case Pavfp_CVTS2F:    return "vcfsx";
    754    case Pavfp_QCVTF2U:   return "vctuxs";
    755    case Pavfp_QCVTF2S:   return "vctsxs";
    756    case Pavfp_ROUNDM:    return "vrfim";
    757    case Pavfp_ROUNDP:    return "vrfip";
    758    case Pavfp_ROUNDN:    return "vrfin";
    759    case Pavfp_ROUNDZ:    return "vrfiz";
    760 
    761    default: vpanic("showPPCAvFpOp");
    762    }
    763 }
    764 
    765 PPCInstr* PPCInstr_LI ( HReg dst, ULong imm64, Bool mode64 )
    766 {
    767    PPCInstr* i     = LibVEX_Alloc_inline(sizeof(PPCInstr));
    768    i->tag          = Pin_LI;
    769    i->Pin.LI.dst   = dst;
    770    i->Pin.LI.imm64 = imm64;
    771    if (!mode64)
    772       vassert( (Long)imm64 == (Long)(Int)(UInt)imm64 );
    773    return i;
    774 }
    775 PPCInstr* PPCInstr_Alu ( PPCAluOp op, HReg dst,
    776                          HReg srcL, PPCRH* srcR ) {
    777    PPCInstr* i     = LibVEX_Alloc_inline(sizeof(PPCInstr));
    778    i->tag          = Pin_Alu;
    779    i->Pin.Alu.op   = op;
    780    i->Pin.Alu.dst  = dst;
    781    i->Pin.Alu.srcL = srcL;
    782    i->Pin.Alu.srcR = srcR;
    783    return i;
    784 }
    785 PPCInstr* PPCInstr_Shft ( PPCShftOp op, Bool sz32,
    786                           HReg dst, HReg srcL, PPCRH* srcR ) {
    787    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
    788    i->tag           = Pin_Shft;
    789    i->Pin.Shft.op   = op;
    790    i->Pin.Shft.sz32 = sz32;
    791    i->Pin.Shft.dst  = dst;
    792    i->Pin.Shft.srcL = srcL;
    793    i->Pin.Shft.srcR = srcR;
    794    return i;
    795 }
    796 PPCInstr* PPCInstr_AddSubC ( Bool isAdd, Bool setC,
    797                              HReg dst, HReg srcL, HReg srcR ) {
    798    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
    799    i->tag               = Pin_AddSubC;
    800    i->Pin.AddSubC.isAdd = isAdd;
    801    i->Pin.AddSubC.setC  = setC;
    802    i->Pin.AddSubC.dst   = dst;
    803    i->Pin.AddSubC.srcL  = srcL;
    804    i->Pin.AddSubC.srcR  = srcR;
    805    return i;
    806 }
    807 PPCInstr* PPCInstr_Cmp ( Bool syned, Bool sz32,
    808                          UInt crfD, HReg srcL, PPCRH* srcR ) {
    809    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
    810    i->tag           = Pin_Cmp;
    811    i->Pin.Cmp.syned = syned;
    812    i->Pin.Cmp.sz32  = sz32;
    813    i->Pin.Cmp.crfD  = crfD;
    814    i->Pin.Cmp.srcL  = srcL;
    815    i->Pin.Cmp.srcR  = srcR;
    816    return i;
    817 }
    818 PPCInstr* PPCInstr_Unary ( PPCUnaryOp op, HReg dst, HReg src ) {
    819    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
    820    i->tag           = Pin_Unary;
    821    i->Pin.Unary.op  = op;
    822    i->Pin.Unary.dst = dst;
    823    i->Pin.Unary.src = src;
    824    return i;
    825 }
    826 PPCInstr* PPCInstr_MulL ( Bool syned, Bool hi, Bool sz32,
    827                           HReg dst, HReg srcL, HReg srcR ) {
    828    PPCInstr* i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
    829    i->tag            = Pin_MulL;
    830    i->Pin.MulL.syned = syned;
    831    i->Pin.MulL.hi    = hi;
    832    i->Pin.MulL.sz32  = sz32;
    833    i->Pin.MulL.dst   = dst;
    834    i->Pin.MulL.srcL  = srcL;
    835    i->Pin.MulL.srcR  = srcR;
    836    /* if doing the low word, the signedness is irrelevant, but tie it
    837       down anyway. */
    838    if (!hi) vassert(!syned);
    839    return i;
    840 }
    841 PPCInstr* PPCInstr_Div ( Bool extended, Bool syned, Bool sz32,
    842                          HReg dst, HReg srcL, HReg srcR ) {
    843    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
    844    i->tag           = Pin_Div;
    845    i->Pin.Div.extended = extended;
    846    i->Pin.Div.syned = syned;
    847    i->Pin.Div.sz32  = sz32;
    848    i->Pin.Div.dst   = dst;
    849    i->Pin.Div.srcL  = srcL;
    850    i->Pin.Div.srcR  = srcR;
    851    return i;
    852 }
    853 PPCInstr* PPCInstr_Call ( PPCCondCode cond,
    854                           Addr64 target, UInt argiregs, RetLoc rloc ) {
    855    UInt mask;
    856    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
    857    i->tag               = Pin_Call;
    858    i->Pin.Call.cond     = cond;
    859    i->Pin.Call.target   = target;
    860    i->Pin.Call.argiregs = argiregs;
    861    i->Pin.Call.rloc     = rloc;
    862    /* Only r3 .. r10 inclusive may be used as arg regs. Hence: */
    863    mask = (1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10);
    864    vassert(0 == (argiregs & ~mask));
    865    vassert(is_sane_RetLoc(rloc));
    866    return i;
    867 }
    868 PPCInstr* PPCInstr_XDirect ( Addr64 dstGA, PPCAMode* amCIA,
    869                              PPCCondCode cond, Bool toFastEP ) {
    870    PPCInstr* i             = LibVEX_Alloc_inline(sizeof(PPCInstr));
    871    i->tag                  = Pin_XDirect;
    872    i->Pin.XDirect.dstGA    = dstGA;
    873    i->Pin.XDirect.amCIA    = amCIA;
    874    i->Pin.XDirect.cond     = cond;
    875    i->Pin.XDirect.toFastEP = toFastEP;
    876    return i;
    877 }
    878 PPCInstr* PPCInstr_XIndir ( HReg dstGA, PPCAMode* amCIA,
    879                             PPCCondCode cond ) {
    880    PPCInstr* i         = LibVEX_Alloc_inline(sizeof(PPCInstr));
    881    i->tag              = Pin_XIndir;
    882    i->Pin.XIndir.dstGA = dstGA;
    883    i->Pin.XIndir.amCIA = amCIA;
    884    i->Pin.XIndir.cond  = cond;
    885    return i;
    886 }
    887 PPCInstr* PPCInstr_XAssisted ( HReg dstGA, PPCAMode* amCIA,
    888                                PPCCondCode cond, IRJumpKind jk ) {
    889    PPCInstr* i            = LibVEX_Alloc_inline(sizeof(PPCInstr));
    890    i->tag                 = Pin_XAssisted;
    891    i->Pin.XAssisted.dstGA = dstGA;
    892    i->Pin.XAssisted.amCIA = amCIA;
    893    i->Pin.XAssisted.cond  = cond;
    894    i->Pin.XAssisted.jk    = jk;
    895    return i;
    896 }
    897 PPCInstr* PPCInstr_CMov  ( PPCCondCode cond,
    898                            HReg dst, PPCRI* src ) {
    899    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
    900    i->tag           = Pin_CMov;
    901    i->Pin.CMov.cond = cond;
    902    i->Pin.CMov.src  = src;
    903    i->Pin.CMov.dst  = dst;
    904    vassert(cond.test != Pct_ALWAYS);
    905    return i;
    906 }
    907 PPCInstr* PPCInstr_Load ( UChar sz,
    908                           HReg dst, PPCAMode* src, Bool mode64 ) {
    909    PPCInstr* i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
    910    i->tag            = Pin_Load;
    911    i->Pin.Load.sz    = sz;
    912    i->Pin.Load.src   = src;
    913    i->Pin.Load.dst   = dst;
    914    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
    915    if (sz == 8) vassert(mode64);
    916    return i;
    917 }
    918 PPCInstr* PPCInstr_LoadL ( UChar sz,
    919                            HReg dst, HReg src, Bool mode64 )
    920 {
    921    PPCInstr* i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
    922    i->tag            = Pin_LoadL;
    923    i->Pin.LoadL.sz   = sz;
    924    i->Pin.LoadL.src  = src;
    925    i->Pin.LoadL.dst  = dst;
    926    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
    927    if (sz == 8) vassert(mode64);
    928    return i;
    929 }
    930 PPCInstr* PPCInstr_Store ( UChar sz, PPCAMode* dst, HReg src,
    931                            Bool mode64 ) {
    932    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
    933    i->tag           = Pin_Store;
    934    i->Pin.Store.sz  = sz;
    935    i->Pin.Store.src = src;
    936    i->Pin.Store.dst = dst;
    937    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
    938    if (sz == 8) vassert(mode64);
    939    return i;
    940 }
    941 PPCInstr* PPCInstr_StoreC ( UChar sz, HReg dst, HReg src, Bool mode64 ) {
    942    PPCInstr* i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
    943    i->tag            = Pin_StoreC;
    944    i->Pin.StoreC.sz  = sz;
    945    i->Pin.StoreC.src = src;
    946    i->Pin.StoreC.dst = dst;
    947    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
    948    if (sz == 8) vassert(mode64);
    949    return i;
    950 }
    951 PPCInstr* PPCInstr_Set ( PPCCondCode cond, HReg dst ) {
    952    PPCInstr* i     = LibVEX_Alloc_inline(sizeof(PPCInstr));
    953    i->tag          = Pin_Set;
    954    i->Pin.Set.cond = cond;
    955    i->Pin.Set.dst  = dst;
    956    return i;
    957 }
    958 PPCInstr* PPCInstr_MfCR ( HReg dst )
    959 {
    960    PPCInstr* i     = LibVEX_Alloc_inline(sizeof(PPCInstr));
    961    i->tag          = Pin_MfCR;
    962    i->Pin.MfCR.dst = dst;
    963    return i;
    964 }
    965 PPCInstr* PPCInstr_MFence ( void )
    966 {
    967    PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr));
    968    i->tag      = Pin_MFence;
    969    return i;
    970 }
    971 
    972 PPCInstr* PPCInstr_FpUnary ( PPCFpOp op, HReg dst, HReg src ) {
    973    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
    974    i->tag             = Pin_FpUnary;
    975    i->Pin.FpUnary.op  = op;
    976    i->Pin.FpUnary.dst = dst;
    977    i->Pin.FpUnary.src = src;
    978    return i;
    979 }
    980 PPCInstr* PPCInstr_FpBinary ( PPCFpOp op, HReg dst,
    981                               HReg srcL, HReg srcR ) {
    982    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
    983    i->tag               = Pin_FpBinary;
    984    i->Pin.FpBinary.op   = op;
    985    i->Pin.FpBinary.dst  = dst;
    986    i->Pin.FpBinary.srcL = srcL;
    987    i->Pin.FpBinary.srcR = srcR;
    988    return i;
    989 }
    990 PPCInstr* PPCInstr_Fp128Unary(PPCFpOp op, HReg dst, HReg src) {
    991    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
    992    i->tag = Pin_Fp128Unary;
    993    i->Pin.Fp128Unary.op = op;
    994    i->Pin.Fp128Unary.dst = dst;
    995    i->Pin.Fp128Unary.src = src;
    996    return i;
    997 }
    998 PPCInstr* PPCInstr_Fp128Binary(PPCFpOp op, HReg dst, HReg srcL, HReg srcR) {
    999    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
   1000    i->tag = Pin_Fp128Binary;
   1001    i->Pin.Fp128Binary.op = op;
   1002    i->Pin.Fp128Binary.dst = dst;
   1003    i->Pin.Fp128Binary.srcL = srcL;
   1004    i->Pin.Fp128Binary.srcR = srcR;
   1005    return i;
   1006 }
   1007 PPCInstr* PPCInstr_Fp128Trinary(PPCFpOp op, HReg dst, HReg srcL, HReg srcR) {
   1008    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
   1009    i->tag = Pin_Fp128Trinary;
   1010    i->Pin.Fp128Trinary.op = op;
   1011    i->Pin.Fp128Trinary.dst = dst;
   1012    i->Pin.Fp128Trinary.srcL = srcL;
   1013    i->Pin.Fp128Trinary.srcR = srcR;
   1014    return i;
   1015 }
   1016 PPCInstr* PPCInstr_FpMulAcc ( PPCFpOp op, HReg dst, HReg srcML,
   1017                                           HReg srcMR, HReg srcAcc )
   1018 {
   1019    PPCInstr* i            = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1020    i->tag                 = Pin_FpMulAcc;
   1021    i->Pin.FpMulAcc.op     = op;
   1022    i->Pin.FpMulAcc.dst    = dst;
   1023    i->Pin.FpMulAcc.srcML  = srcML;
   1024    i->Pin.FpMulAcc.srcMR  = srcMR;
   1025    i->Pin.FpMulAcc.srcAcc = srcAcc;
   1026    return i;
   1027 }
   1028 PPCInstr* PPCInstr_FpLdSt ( Bool isLoad, UChar sz,
   1029                             HReg reg, PPCAMode* addr ) {
   1030    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1031    i->tag               = Pin_FpLdSt;
   1032    i->Pin.FpLdSt.isLoad = isLoad;
   1033    i->Pin.FpLdSt.sz     = sz;
   1034    i->Pin.FpLdSt.reg    = reg;
   1035    i->Pin.FpLdSt.addr   = addr;
   1036    vassert(sz == 4 || sz == 8);
   1037    return i;
   1038 }
   1039 PPCInstr* PPCInstr_FpSTFIW ( HReg addr, HReg data )
   1040 {
   1041    PPCInstr* i         = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1042    i->tag              = Pin_FpSTFIW;
   1043    i->Pin.FpSTFIW.addr = addr;
   1044    i->Pin.FpSTFIW.data = data;
   1045    return i;
   1046 }
   1047 PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src ) {
   1048    PPCInstr* i      = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1049    i->tag           = Pin_FpRSP;
   1050    i->Pin.FpRSP.dst = dst;
   1051    i->Pin.FpRSP.src = src;
   1052    return i;
   1053 }
   1054 PPCInstr* PPCInstr_Dfp64Unary(PPCFpOp op, HReg dst, HReg src) {
   1055    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
   1056    i->tag = Pin_Dfp64Unary;
   1057    i->Pin.Dfp64Unary.op = op;
   1058    i->Pin.Dfp64Unary.dst = dst;
   1059    i->Pin.Dfp64Unary.src = src;
   1060    return i;
   1061 }
   1062 PPCInstr* PPCInstr_Dfp64Binary(PPCFpOp op, HReg dst, HReg srcL, HReg srcR) {
   1063    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
   1064    i->tag = Pin_Dfp64Binary;
   1065    i->Pin.Dfp64Binary.op = op;
   1066    i->Pin.Dfp64Binary.dst = dst;
   1067    i->Pin.Dfp64Binary.srcL = srcL;
   1068    i->Pin.Dfp64Binary.srcR = srcR;
   1069    return i;
   1070 }
   1071 PPCInstr* PPCInstr_DfpShift ( PPCFpOp op, HReg dst, HReg src, PPCRI* shift ) {
   1072    PPCInstr* i            = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1073    i->tag                 = Pin_DfpShift;
   1074    i->Pin.DfpShift.op     = op;
   1075    i->Pin.DfpShift.shift  = shift;
   1076    i->Pin.DfpShift.src    = src;
   1077    i->Pin.DfpShift.dst    = dst;
   1078    return i;
   1079 }
   1080 PPCInstr* PPCInstr_Dfp128Unary(PPCFpOp op, HReg dst_hi, HReg dst_lo,
   1081                                 HReg src_hi, HReg src_lo) {
   1082    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
   1083    i->tag = Pin_Dfp128Unary;
   1084    i->Pin.Dfp128Unary.op = op;
   1085    i->Pin.Dfp128Unary.dst_hi = dst_hi;
   1086    i->Pin.Dfp128Unary.dst_lo = dst_lo;
   1087    i->Pin.Dfp128Unary.src_hi = src_hi;
   1088    i->Pin.Dfp128Unary.src_lo = src_lo;
   1089    return i;
   1090 }
   1091 PPCInstr* PPCInstr_Dfp128Binary(PPCFpOp op, HReg dst_hi, HReg dst_lo,
   1092                                 HReg srcR_hi, HReg srcR_lo) {
   1093    /* dst is used to pass the srcL argument and return the result */
   1094    PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) );
   1095    i->tag = Pin_Dfp128Binary;
   1096    i->Pin.Dfp128Binary.op = op;
   1097    i->Pin.Dfp128Binary.dst_hi = dst_hi;
   1098    i->Pin.Dfp128Binary.dst_lo = dst_lo;
   1099    i->Pin.Dfp128Binary.srcR_hi = srcR_hi;
   1100    i->Pin.Dfp128Binary.srcR_lo = srcR_lo;
   1101    return i;
   1102 }
   1103 PPCInstr* PPCInstr_DfpShift128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
   1104                                  HReg src_hi, HReg src_lo,
   1105                                  PPCRI* shift ) {
   1106    PPCInstr* i               = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1107    i->tag                    = Pin_DfpShift128;
   1108    i->Pin.DfpShift128.op     = op;
   1109    i->Pin.DfpShift128.shift  = shift;
   1110    i->Pin.DfpShift128.src_hi = src_hi;
   1111    i->Pin.DfpShift128.src_lo = src_lo;
   1112    i->Pin.DfpShift128.dst_hi = dst_hi;
   1113    i->Pin.DfpShift128.dst_lo = dst_lo;
   1114    return i;
   1115 }
   1116 PPCInstr* PPCInstr_DfpRound ( HReg dst, HReg src, PPCRI* r_rmc ) {
   1117    PPCInstr* i           = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1118    i->tag                = Pin_DfpRound;
   1119    i->Pin.DfpRound.dst   = dst;
   1120    i->Pin.DfpRound.src   = src;
   1121    i->Pin.DfpRound.r_rmc = r_rmc;
   1122    return i;
   1123 }
   1124 PPCInstr* PPCInstr_DfpRound128 ( HReg dst_hi, HReg dst_lo, HReg src_hi,
   1125                                  HReg src_lo, PPCRI* r_rmc ) {
   1126    PPCInstr* i               = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1127    i->tag                    = Pin_DfpRound128;
   1128    i->Pin.DfpRound128.dst_hi = dst_hi;
   1129    i->Pin.DfpRound128.dst_lo = dst_lo;
   1130    i->Pin.DfpRound128.src_hi = src_hi;
   1131    i->Pin.DfpRound128.src_lo = src_lo;
   1132    i->Pin.DfpRound128.r_rmc  = r_rmc;
   1133    return i;
   1134 }
   1135 PPCInstr* PPCInstr_DfpQuantize ( PPCFpOp op, HReg dst, HReg srcL, HReg srcR,
   1136                                  PPCRI* rmc ) {
   1137    PPCInstr* i             = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1138    i->tag                  = Pin_DfpQuantize;
   1139    i->Pin.DfpQuantize.op   = op;
   1140    i->Pin.DfpQuantize.dst  = dst;
   1141    i->Pin.DfpQuantize.srcL = srcL;
   1142    i->Pin.DfpQuantize.srcR = srcR;
   1143    i->Pin.DfpQuantize.rmc  = rmc;
   1144    return i;
   1145 }
   1146 PPCInstr* PPCInstr_DfpQuantize128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
   1147                                     HReg src_hi, HReg src_lo, PPCRI* rmc ) {
   1148    /* dst is used to pass left operand in and return result */
   1149    PPCInstr* i                  = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1150    i->tag                       = Pin_DfpQuantize128;
   1151    i->Pin.DfpQuantize128.op     = op;
   1152    i->Pin.DfpQuantize128.dst_hi = dst_hi;
   1153    i->Pin.DfpQuantize128.dst_lo = dst_lo;
   1154    i->Pin.DfpQuantize128.src_hi = src_hi;
   1155    i->Pin.DfpQuantize128.src_lo = src_lo;
   1156    i->Pin.DfpQuantize128.rmc    = rmc;
   1157    return i;
   1158 }
   1159 PPCInstr* PPCInstr_DfpD128toD64 ( PPCFpOp op, HReg dst,
   1160                                   HReg src_hi, HReg src_lo ) {
   1161    PPCInstr* i                = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1162    i->tag                     = Pin_DfpD128toD64;
   1163    i->Pin.DfpD128toD64.op     = op;
   1164    i->Pin.DfpD128toD64.src_hi = src_hi;
   1165    i->Pin.DfpD128toD64.src_lo = src_lo;
   1166    i->Pin.DfpD128toD64.dst    = dst;
   1167    return i;
   1168 }
   1169 PPCInstr* PPCInstr_DfpI64StoD128 ( PPCFpOp op, HReg dst_hi,
   1170                                    HReg dst_lo, HReg src ) {
   1171    PPCInstr* i                 = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1172    i->tag                      = Pin_DfpI64StoD128;
   1173    i->Pin.DfpI64StoD128.op     = op;
   1174    i->Pin.DfpI64StoD128.src    = src;
   1175    i->Pin.DfpI64StoD128.dst_hi = dst_hi;
   1176    i->Pin.DfpI64StoD128.dst_lo = dst_lo;
   1177    return i;
   1178 }
   1179 PPCInstr* PPCInstr_ExtractExpD128 ( PPCFpOp op, HReg dst,
   1180                                     HReg src_hi, HReg src_lo ) {
   1181    /* dst is used to pass the srcL argument */
   1182    PPCInstr* i                  = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1183    i->tag                       = Pin_ExtractExpD128;
   1184    i->Pin.ExtractExpD128.op     = op;
   1185    i->Pin.ExtractExpD128.dst    = dst;
   1186    i->Pin.ExtractExpD128.src_hi = src_hi;
   1187    i->Pin.ExtractExpD128.src_lo = src_lo;
   1188    return i;
   1189 }
   1190 PPCInstr* PPCInstr_InsertExpD128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
   1191                                    HReg srcL, HReg srcR_hi, HReg srcR_lo ) {
   1192    /* dst is used to pass the srcL argument */
   1193    PPCInstr* i                  = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1194    i->tag                       = Pin_InsertExpD128;
   1195    i->Pin.InsertExpD128.op      = op;
   1196    i->Pin.InsertExpD128.dst_hi  = dst_hi;
   1197    i->Pin.InsertExpD128.dst_lo  = dst_lo;
   1198    i->Pin.InsertExpD128.srcL    = srcL;
   1199    i->Pin.InsertExpD128.srcR_hi = srcR_hi;
   1200    i->Pin.InsertExpD128.srcR_lo = srcR_lo;
   1201    return i;
   1202 }
   1203 PPCInstr* PPCInstr_Dfp64Cmp (/* UInt crfD,*/ HReg dst, HReg srcL, HReg srcR ) {
   1204    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1205    i->tag               = Pin_Dfp64Cmp;
   1206    i->Pin.Dfp64Cmp.dst = dst;
   1207    i->Pin.Dfp64Cmp.srcL = srcL;
   1208    i->Pin.Dfp64Cmp.srcR = srcR;
   1209    return i;
   1210 }
   1211 PPCInstr* PPCInstr_Dfp128Cmp ( HReg dst, HReg srcL_hi, HReg srcL_lo,
   1212                                HReg srcR_hi, HReg srcR_lo ) {
   1213    PPCInstr* i               = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1214    i->tag                    = Pin_Dfp128Cmp;
   1215    i->Pin.Dfp128Cmp.dst      = dst;
   1216    i->Pin.Dfp128Cmp.srcL_hi  = srcL_hi;
   1217    i->Pin.Dfp128Cmp.srcL_lo  = srcL_lo;
   1218    i->Pin.Dfp128Cmp.srcR_hi  = srcR_hi;
   1219    i->Pin.Dfp128Cmp.srcR_lo  = srcR_lo;
   1220    return i;
   1221 }
   1222 PPCInstr* PPCInstr_EvCheck ( PPCAMode* amCounter,
   1223                              PPCAMode* amFailAddr ) {
   1224    PPCInstr* i               = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1225    i->tag                    = Pin_EvCheck;
   1226    i->Pin.EvCheck.amCounter  = amCounter;
   1227    i->Pin.EvCheck.amFailAddr = amFailAddr;
   1228    return i;
   1229 }
   1230 PPCInstr* PPCInstr_ProfInc ( void ) {
   1231    PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1232    i->tag      = Pin_ProfInc;
   1233    return i;
   1234 }
   1235 
   1236 /*
   1237 Valid combo | fromI | int32 | syned | flt64 |
   1238 --------------------------------------------
   1239             |  n       n       n       n    |
   1240 --------------------------------------------
   1241  F64->I64U  |  n       n       n       y    |
   1242 --------------------------------------------
   1243             |  n       n       y       n    |
   1244 --------------------------------------------
   1245  F64->I64S  |  n       n       y       y    |
   1246 --------------------------------------------
   1247             |  n       y       n       n    |
   1248 --------------------------------------------
   1249  F64->I32U  |  n       y       n       y    |
   1250 --------------------------------------------
   1251             |  n       y       y       n    |
   1252 --------------------------------------------
   1253  F64->I32S  |  n       y       y       y    |
   1254 --------------------------------------------
   1255  I64U->F32  |  y       n       n       n    |
   1256 --------------------------------------------
   1257  I64U->F64  |  y       n       n       y    |
   1258 --------------------------------------------
   1259             |  y       n       y       n    |
   1260 --------------------------------------------
   1261  I64S->F64  |  y       n       y       y    |
   1262 --------------------------------------------
   1263             |  y       y       n       n    |
   1264 --------------------------------------------
   1265             |  y       y       n       y    |
   1266 --------------------------------------------
   1267             |  y       y       y       n    |
   1268 --------------------------------------------
   1269             |  y       y       y       y    |
   1270 --------------------------------------------
   1271 */
   1272 PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, Bool syned,
   1273                             Bool flt64, HReg dst, HReg src ) {
   1274    Bool tmp = fromI | int32 | syned | flt64;
   1275    vassert(tmp == True || tmp == False); // iow, no high bits set
   1276    UShort conversion = 0;
   1277    conversion = (fromI << 3) | (int32 << 2) | (syned << 1) | flt64;
   1278    switch (conversion) {
   1279       // Supported conversion operations
   1280       case 1: case 3: case 5: case 7:
   1281       case 8: case 9: case 11:
   1282          break;
   1283       default:
   1284          vpanic("PPCInstr_FpCftI(ppc_host)");
   1285    }
   1286    PPCInstr* i         = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1287    i->tag              = Pin_FpCftI;
   1288    i->Pin.FpCftI.fromI = fromI;
   1289    i->Pin.FpCftI.int32 = int32;
   1290    i->Pin.FpCftI.syned = syned;
   1291    i->Pin.FpCftI.flt64 = flt64;
   1292    i->Pin.FpCftI.dst   = dst;
   1293    i->Pin.FpCftI.src   = src;
   1294    return i;
   1295 }
   1296 PPCInstr* PPCInstr_FpCMov ( PPCCondCode cond, HReg dst, HReg src ) {
   1297    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1298    i->tag             = Pin_FpCMov;
   1299    i->Pin.FpCMov.cond = cond;
   1300    i->Pin.FpCMov.dst  = dst;
   1301    i->Pin.FpCMov.src  = src;
   1302    vassert(cond.test != Pct_ALWAYS);
   1303    return i;
   1304 }
   1305 PPCInstr* PPCInstr_FpLdFPSCR ( HReg src, Bool dfp_rm ) {
   1306    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1307    i->tag               = Pin_FpLdFPSCR;
   1308    i->Pin.FpLdFPSCR.src = src;
   1309    i->Pin.FpLdFPSCR.dfp_rm = dfp_rm ? 1 : 0;
   1310    return i;
   1311 }
   1312 PPCInstr* PPCInstr_FpCmp ( HReg dst, HReg srcL, HReg srcR ) {
   1313    PPCInstr* i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1314    i->tag            = Pin_FpCmp;
   1315    i->Pin.FpCmp.dst  = dst;
   1316    i->Pin.FpCmp.srcL = srcL;
   1317    i->Pin.FpCmp.srcR = srcR;
   1318    return i;
   1319 }
   1320 
   1321 /* Read/Write Link Register */
   1322 PPCInstr* PPCInstr_RdWrLR ( Bool wrLR, HReg gpr ) {
   1323    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1324    i->tag             = Pin_RdWrLR;
   1325    i->Pin.RdWrLR.wrLR = wrLR;
   1326    i->Pin.RdWrLR.gpr  = gpr;
   1327    return i;
   1328 }
   1329 
   1330 /* AltiVec */
   1331 PPCInstr* PPCInstr_AvLdSt ( Bool isLoad, UChar sz,
   1332                             HReg reg, PPCAMode* addr ) {
   1333    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1334    i->tag               = Pin_AvLdSt;
   1335    i->Pin.AvLdSt.isLoad = isLoad;
   1336    i->Pin.AvLdSt.sz     = sz;
   1337    i->Pin.AvLdSt.reg    = reg;
   1338    i->Pin.AvLdSt.addr   = addr;
   1339    return i;
   1340 }
   1341 PPCInstr* PPCInstr_AvUnary ( PPCAvOp op, HReg dst, HReg src ) {
   1342    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1343    i->tag             = Pin_AvUnary;
   1344    i->Pin.AvUnary.op  = op;
   1345    i->Pin.AvUnary.dst = dst;
   1346    i->Pin.AvUnary.src = src;
   1347    return i;
   1348 }
   1349 PPCInstr* PPCInstr_AvBinary ( PPCAvOp op, HReg dst,
   1350                               HReg srcL, HReg srcR ) {
   1351    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1352    i->tag               = Pin_AvBinary;
   1353    i->Pin.AvBinary.op   = op;
   1354    i->Pin.AvBinary.dst  = dst;
   1355    i->Pin.AvBinary.srcL = srcL;
   1356    i->Pin.AvBinary.srcR = srcR;
   1357    return i;
   1358 }
   1359 PPCInstr* PPCInstr_AvBinaryInt ( PPCAvOp op, HReg dst,
   1360                                  HReg src, PPCRI* val ) {
   1361    PPCInstr* i            = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1362    i->tag                 = Pin_AvBinaryInt;
   1363    i->Pin.AvBinaryInt.op  = op;
   1364    i->Pin.AvBinaryInt.dst = dst;
   1365    i->Pin.AvBinaryInt.src = src;
   1366    i->Pin.AvBinaryInt.val = val;
   1367    return i;
   1368 }
   1369 PPCInstr* PPCInstr_AvBin8x16 ( PPCAvOp op, HReg dst,
   1370                                HReg srcL, HReg srcR ) {
   1371    PPCInstr* i           = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1372    i->tag                = Pin_AvBin8x16;
   1373    i->Pin.AvBin8x16.op   = op;
   1374    i->Pin.AvBin8x16.dst  = dst;
   1375    i->Pin.AvBin8x16.srcL = srcL;
   1376    i->Pin.AvBin8x16.srcR = srcR;
   1377    return i;
   1378 }
   1379 PPCInstr* PPCInstr_AvBin16x8 ( PPCAvOp op, HReg dst,
   1380                                HReg srcL, HReg srcR ) {
   1381    PPCInstr* i           = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1382    i->tag                = Pin_AvBin16x8;
   1383    i->Pin.AvBin16x8.op   = op;
   1384    i->Pin.AvBin16x8.dst  = dst;
   1385    i->Pin.AvBin16x8.srcL = srcL;
   1386    i->Pin.AvBin16x8.srcR = srcR;
   1387    return i;
   1388 }
   1389 PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst,
   1390                                HReg srcL, HReg srcR ) {
   1391    PPCInstr* i           = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1392    i->tag                = Pin_AvBin32x4;
   1393    i->Pin.AvBin32x4.op   = op;
   1394    i->Pin.AvBin32x4.dst  = dst;
   1395    i->Pin.AvBin32x4.srcL = srcL;
   1396    i->Pin.AvBin32x4.srcR = srcR;
   1397    return i;
   1398 }
   1399 PPCInstr* PPCInstr_AvBin64x2 ( PPCAvOp op, HReg dst,
   1400                                HReg srcL, HReg srcR ) {
   1401    PPCInstr* i           = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1402    i->tag                = Pin_AvBin64x2;
   1403    i->Pin.AvBin64x2.op   = op;
   1404    i->Pin.AvBin64x2.dst  = dst;
   1405    i->Pin.AvBin64x2.srcL = srcL;
   1406    i->Pin.AvBin64x2.srcR = srcR;
   1407    return i;
   1408 }
   1409 
   1410 PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst,
   1411                                 HReg srcL, HReg srcR ) {
   1412    PPCInstr* i            = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1413    i->tag                 = Pin_AvBin32Fx4;
   1414    i->Pin.AvBin32Fx4.op   = op;
   1415    i->Pin.AvBin32Fx4.dst  = dst;
   1416    i->Pin.AvBin32Fx4.srcL = srcL;
   1417    i->Pin.AvBin32Fx4.srcR = srcR;
   1418    return i;
   1419 }
   1420 PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op, HReg dst, HReg src ) {
   1421    PPCInstr* i          = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1422    i->tag               = Pin_AvUn32Fx4;
   1423    i->Pin.AvUn32Fx4.op  = op;
   1424    i->Pin.AvUn32Fx4.dst = dst;
   1425    i->Pin.AvUn32Fx4.src = src;
   1426    return i;
   1427 }
   1428 PPCInstr* PPCInstr_AvPerm ( HReg dst, HReg srcL, HReg srcR, HReg ctl ) {
   1429    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1430    i->tag             = Pin_AvPerm;
   1431    i->Pin.AvPerm.dst  = dst;
   1432    i->Pin.AvPerm.srcL = srcL;
   1433    i->Pin.AvPerm.srcR = srcR;
   1434    i->Pin.AvPerm.ctl  = ctl;
   1435    return i;
   1436 }
   1437 
   1438 PPCInstr* PPCInstr_AvSel ( HReg ctl, HReg dst, HReg srcL, HReg srcR ) {
   1439    PPCInstr* i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1440    i->tag            = Pin_AvSel;
   1441    i->Pin.AvSel.ctl  = ctl;
   1442    i->Pin.AvSel.dst  = dst;
   1443    i->Pin.AvSel.srcL = srcL;
   1444    i->Pin.AvSel.srcR = srcR;
   1445    return i;
   1446 }
   1447 PPCInstr* PPCInstr_AvSh ( Bool shLeft, HReg dst, PPCAMode* addr ) {
   1448    PPCInstr*  i       = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1449    i->tag             = Pin_AvSh;
   1450    i->Pin.AvSh.shLeft = shLeft;
   1451    i->Pin.AvSh.dst    = dst;
   1452    i->Pin.AvSh.addr   = addr;
   1453    return i;
   1454 }
   1455 PPCInstr* PPCInstr_AvShlDbl ( UChar shift, HReg dst,
   1456                               HReg srcL, HReg srcR ) {
   1457    PPCInstr* i           = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1458    i->tag                = Pin_AvShlDbl;
   1459    i->Pin.AvShlDbl.shift = shift;
   1460    i->Pin.AvShlDbl.dst   = dst;
   1461    i->Pin.AvShlDbl.srcL  = srcL;
   1462    i->Pin.AvShlDbl.srcR  = srcR;
   1463    return i;
   1464 }
   1465 PPCInstr* PPCInstr_AvSplat ( UChar sz, HReg dst, PPCVI5s* src ) {
   1466    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1467    i->tag             = Pin_AvSplat;
   1468    i->Pin.AvSplat.sz  = sz;
   1469    i->Pin.AvSplat.dst = dst;
   1470    i->Pin.AvSplat.src = src;
   1471    return i;
   1472 }
   1473 PPCInstr* PPCInstr_AvCMov ( PPCCondCode cond, HReg dst, HReg src ) {
   1474    PPCInstr* i        = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1475    i->tag             = Pin_AvCMov;
   1476    i->Pin.AvCMov.cond = cond;
   1477    i->Pin.AvCMov.dst  = dst;
   1478    i->Pin.AvCMov.src  = src;
   1479    vassert(cond.test != Pct_ALWAYS);
   1480    return i;
   1481 }
   1482 PPCInstr* PPCInstr_AvLdVSCR ( HReg src ) {
   1483    PPCInstr* i         = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1484    i->tag              = Pin_AvLdVSCR;
   1485    i->Pin.AvLdVSCR.src = src;
   1486    return i;
   1487 }
   1488 PPCInstr* PPCInstr_AvCipherV128Unary ( PPCAvOp op, HReg dst, HReg src ) {
   1489    PPCInstr* i              = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1490    i->tag                   = Pin_AvCipherV128Unary;
   1491    i->Pin.AvCipherV128Unary.op   = op;
   1492    i->Pin.AvCipherV128Unary.dst  = dst;
   1493    i->Pin.AvCipherV128Unary.src  = src;
   1494    return i;
   1495 }
   1496 PPCInstr* PPCInstr_AvCipherV128Binary ( PPCAvOp op, HReg dst,
   1497                                         HReg srcL, HReg srcR ) {
   1498    PPCInstr* i              = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1499    i->tag                   = Pin_AvCipherV128Binary;
   1500    i->Pin.AvCipherV128Binary.op   = op;
   1501    i->Pin.AvCipherV128Binary.dst  = dst;
   1502    i->Pin.AvCipherV128Binary.srcL = srcL;
   1503    i->Pin.AvCipherV128Binary.srcR = srcR;
   1504    return i;
   1505 }
   1506 PPCInstr* PPCInstr_AvHashV128Binary ( PPCAvOp op, HReg dst,
   1507                                       HReg src, PPCRI* s_field ) {
   1508    PPCInstr* i              = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1509    i->tag                   = Pin_AvHashV128Binary;
   1510    i->Pin.AvHashV128Binary.op  = op;
   1511    i->Pin.AvHashV128Binary.dst = dst;
   1512    i->Pin.AvHashV128Binary.src = src;
   1513    i->Pin.AvHashV128Binary.s_field = s_field;
   1514    return i;
   1515 }
   1516 PPCInstr* PPCInstr_AvBCDV128Binary ( PPCAvOp op, HReg dst,
   1517                                      HReg src1, HReg src2 ) {
   1518    PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr));
   1519    i->tag      = Pin_AvBCDV128Binary;
   1520    i->Pin.AvBCDV128Binary.op   = op;
   1521    i->Pin.AvBCDV128Binary.dst  = dst;
   1522    i->Pin.AvBCDV128Binary.src1 = src1;
   1523    i->Pin.AvBCDV128Binary.src2 = src2;
   1524    return i;
   1525 }
   1526 
   1527 
   1528 /* Pretty Print instructions */
   1529 static void ppLoadImm ( HReg dst, ULong imm, Bool mode64 ) {
   1530    vex_printf("li_word ");
   1531    ppHRegPPC(dst);
   1532    if (!mode64) {
   1533       vex_printf(",0x%08x", (UInt)imm);
   1534    } else {
   1535       vex_printf(",0x%016llx", imm);
   1536    }
   1537 }
   1538 
   1539 static void ppMovReg ( HReg dst, HReg src ) {
   1540    if (!sameHReg(dst, src)) {
   1541       vex_printf("mr ");
   1542       ppHRegPPC(dst);
   1543       vex_printf(",");
   1544       ppHRegPPC(src);
   1545    }
   1546 }
   1547 
   1548 void ppPPCInstr ( const PPCInstr* i, Bool mode64 )
   1549 {
   1550    switch (i->tag) {
   1551    case Pin_LI:
   1552       ppLoadImm(i->Pin.LI.dst, i->Pin.LI.imm64, mode64);
   1553       break;
   1554    case Pin_Alu: {
   1555       HReg   r_srcL  = i->Pin.Alu.srcL;
   1556       PPCRH* rh_srcR = i->Pin.Alu.srcR;
   1557       /* special-case "mr" */
   1558       if (i->Pin.Alu.op == Palu_OR &&   // or Rd,Rs,Rs == mr Rd,Rs
   1559           rh_srcR->tag == Prh_Reg &&
   1560           sameHReg(rh_srcR->Prh.Reg.reg, r_srcL)) {
   1561          vex_printf("mr ");
   1562          ppHRegPPC(i->Pin.Alu.dst);
   1563          vex_printf(",");
   1564          ppHRegPPC(r_srcL);
   1565          return;
   1566       }
   1567       /* special-case "li" */
   1568       if (i->Pin.Alu.op == Palu_ADD &&   // addi Rd,0,imm == li Rd,imm
   1569           rh_srcR->tag == Prh_Imm &&
   1570           hregEncoding(r_srcL) == 0) {
   1571          vex_printf("li ");
   1572          ppHRegPPC(i->Pin.Alu.dst);
   1573          vex_printf(",");
   1574          ppPPCRH(rh_srcR);
   1575          return;
   1576       }
   1577       /* generic */
   1578       vex_printf("%s ", showPPCAluOp(i->Pin.Alu.op,
   1579                                      toBool(rh_srcR->tag == Prh_Imm)));
   1580       ppHRegPPC(i->Pin.Alu.dst);
   1581       vex_printf(",");
   1582       ppHRegPPC(r_srcL);
   1583       vex_printf(",");
   1584       ppPPCRH(rh_srcR);
   1585       return;
   1586    }
   1587    case Pin_Shft: {
   1588       HReg   r_srcL  = i->Pin.Shft.srcL;
   1589       PPCRH* rh_srcR = i->Pin.Shft.srcR;
   1590       vex_printf("%s ", showPPCShftOp(i->Pin.Shft.op,
   1591                                       toBool(rh_srcR->tag == Prh_Imm),
   1592                                       i->Pin.Shft.sz32));
   1593       ppHRegPPC(i->Pin.Shft.dst);
   1594       vex_printf(",");
   1595       ppHRegPPC(r_srcL);
   1596       vex_printf(",");
   1597       ppPPCRH(rh_srcR);
   1598       return;
   1599    }
   1600    case Pin_AddSubC:
   1601       vex_printf("%s%s ",
   1602                  i->Pin.AddSubC.isAdd ? "add" : "sub",
   1603                  i->Pin.AddSubC.setC ? "c" : "e");
   1604       ppHRegPPC(i->Pin.AddSubC.dst);
   1605       vex_printf(",");
   1606       ppHRegPPC(i->Pin.AddSubC.srcL);
   1607       vex_printf(",");
   1608       ppHRegPPC(i->Pin.AddSubC.srcR);
   1609       return;
   1610    case Pin_Cmp:
   1611       vex_printf("%s%c%s %%cr%u,",
   1612                  i->Pin.Cmp.syned ? "cmp" : "cmpl",
   1613                  i->Pin.Cmp.sz32 ? 'w' : 'd',
   1614                  i->Pin.Cmp.srcR->tag == Prh_Imm ? "i" : "",
   1615                  i->Pin.Cmp.crfD);
   1616       ppHRegPPC(i->Pin.Cmp.srcL);
   1617       vex_printf(",");
   1618       ppPPCRH(i->Pin.Cmp.srcR);
   1619       return;
   1620    case Pin_Unary:
   1621       vex_printf("%s ", showPPCUnaryOp(i->Pin.Unary.op));
   1622       ppHRegPPC(i->Pin.Unary.dst);
   1623       vex_printf(",");
   1624       ppHRegPPC(i->Pin.Unary.src);
   1625       return;
   1626    case Pin_MulL:
   1627       vex_printf("mul%c%c%s ",
   1628                  i->Pin.MulL.hi ? 'h' : 'l',
   1629                  i->Pin.MulL.sz32 ? 'w' : 'd',
   1630                  i->Pin.MulL.hi ? (i->Pin.MulL.syned ? "s" : "u") : "");
   1631       ppHRegPPC(i->Pin.MulL.dst);
   1632       vex_printf(",");
   1633       ppHRegPPC(i->Pin.MulL.srcL);
   1634       vex_printf(",");
   1635       ppHRegPPC(i->Pin.MulL.srcR);
   1636       return;
   1637    case Pin_Div:
   1638       vex_printf("div%c%s%s ",
   1639                  i->Pin.Div.sz32 ? 'w' : 'd',
   1640                  i->Pin.Div.extended ? "e" : "",
   1641                  i->Pin.Div.syned ? "" : "u");
   1642       ppHRegPPC(i->Pin.Div.dst);
   1643       vex_printf(",");
   1644       ppHRegPPC(i->Pin.Div.srcL);
   1645       vex_printf(",");
   1646       ppHRegPPC(i->Pin.Div.srcR);
   1647       return;
   1648    case Pin_Call: {
   1649       Int n;
   1650       vex_printf("call: ");
   1651       if (i->Pin.Call.cond.test != Pct_ALWAYS) {
   1652          vex_printf("if (%s) ", showPPCCondCode(i->Pin.Call.cond));
   1653       }
   1654       vex_printf("{ ");
   1655       ppLoadImm(hregPPC_GPR10(mode64), i->Pin.Call.target, mode64);
   1656       vex_printf(" ; mtctr r10 ; bctrl [");
   1657       for (n = 0; n < 32; n++) {
   1658          if (i->Pin.Call.argiregs & (1<<n)) {
   1659             vex_printf("r%d", n);
   1660             if ((i->Pin.Call.argiregs >> n) > 1)
   1661                vex_printf(",");
   1662          }
   1663       }
   1664       vex_printf(",");
   1665       ppRetLoc(i->Pin.Call.rloc);
   1666       vex_printf("] }");
   1667       break;
   1668    }
   1669    case Pin_XDirect:
   1670       vex_printf("(xDirect) ");
   1671       vex_printf("if (%s) { ",
   1672                  showPPCCondCode(i->Pin.XDirect.cond));
   1673       if (mode64) {
   1674          vex_printf("imm64 r30,0x%llx; ", i->Pin.XDirect.dstGA);
   1675          vex_printf("std r30,");
   1676       } else {
   1677          vex_printf("imm32 r30,0x%llx; ", i->Pin.XDirect.dstGA);
   1678          vex_printf("stw r30,");
   1679       }
   1680       ppPPCAMode(i->Pin.XDirect.amCIA);
   1681       vex_printf("; ");
   1682       if (mode64) {
   1683          vex_printf("imm64-fixed5 r30,$disp_cp_chain_me_to_%sEP; ",
   1684                     i->Pin.XDirect.toFastEP ? "fast" : "slow");
   1685       } else {
   1686          vex_printf("imm32-fixed2 r30,$disp_cp_chain_me_to_%sEP; ",
   1687                     i->Pin.XDirect.toFastEP ? "fast" : "slow");
   1688       }
   1689       vex_printf("mtctr r30; bctrl }");
   1690       return;
   1691    case Pin_XIndir:
   1692       vex_printf("(xIndir) ");
   1693       vex_printf("if (%s) { ",
   1694                  showPPCCondCode(i->Pin.XIndir.cond));
   1695       vex_printf("%s ", mode64 ? "std" : "stw");
   1696       ppHRegPPC(i->Pin.XIndir.dstGA);
   1697       vex_printf(",");
   1698       ppPPCAMode(i->Pin.XIndir.amCIA);
   1699       vex_printf("; ");
   1700       vex_printf("imm%s r30,$disp_cp_xindir; ", mode64 ? "64" : "32");
   1701       vex_printf("mtctr r30; bctr }");
   1702       return;
   1703    case Pin_XAssisted:
   1704       vex_printf("(xAssisted) ");
   1705       vex_printf("if (%s) { ",
   1706                  showPPCCondCode(i->Pin.XAssisted.cond));
   1707       vex_printf("%s ", mode64 ? "std" : "stw");
   1708       ppHRegPPC(i->Pin.XAssisted.dstGA);
   1709       vex_printf(",");
   1710       ppPPCAMode(i->Pin.XAssisted.amCIA);
   1711       vex_printf("; ");
   1712       vex_printf("li r31,$IRJumpKind_to_TRCVAL(%d); ",
   1713                  (Int)i->Pin.XAssisted.jk);
   1714       vex_printf("imm%s r30,$disp_cp_xindir; ", mode64 ? "64" : "32");
   1715       vex_printf("mtctr r30; bctr }");
   1716       return;
   1717    case Pin_CMov:
   1718       vex_printf("cmov (%s) ", showPPCCondCode(i->Pin.CMov.cond));
   1719       ppHRegPPC(i->Pin.CMov.dst);
   1720       vex_printf(",");
   1721       ppPPCRI(i->Pin.CMov.src);
   1722       vex_printf(": ");
   1723       if (i->Pin.CMov.cond.test != Pct_ALWAYS) {
   1724          vex_printf("if (%s) ", showPPCCondCode(i->Pin.CMov.cond));
   1725       }
   1726       vex_printf("{ ");
   1727       if (i->Pin.CMov.src->tag == Pri_Imm) {
   1728          ppLoadImm(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Imm, mode64);
   1729       } else {
   1730          ppMovReg(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Reg);
   1731       }
   1732       vex_printf(" }");
   1733       return;
   1734    case Pin_Load: {
   1735       Bool idxd = toBool(i->Pin.Load.src->tag == Pam_RR);
   1736       UChar sz = i->Pin.Load.sz;
   1737       HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd';
   1738       vex_printf("l%c%s%s ", c_sz, sz==8 ? "" : "z", idxd ? "x" : "" );
   1739       ppHRegPPC(i->Pin.Load.dst);
   1740       vex_printf(",");
   1741       ppPPCAMode(i->Pin.Load.src);
   1742       return;
   1743    }
   1744    case Pin_LoadL: {
   1745       UChar sz = i->Pin.LoadL.sz;
   1746       HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd';
   1747       vex_printf("l%carx ", c_sz);
   1748       ppHRegPPC(i->Pin.LoadL.dst);
   1749       vex_printf(",%%r0,");
   1750       ppHRegPPC(i->Pin.LoadL.src);
   1751       return;
   1752    }
   1753    case Pin_Store: {
   1754       UChar sz = i->Pin.Store.sz;
   1755       Bool idxd = toBool(i->Pin.Store.dst->tag == Pam_RR);
   1756       HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : /*8*/ 'd';
   1757       vex_printf("st%c%s ", c_sz, idxd ? "x" : "" );
   1758       ppHRegPPC(i->Pin.Store.src);
   1759       vex_printf(",");
   1760       ppPPCAMode(i->Pin.Store.dst);
   1761       return;
   1762    }
   1763    case Pin_StoreC: {
   1764       UChar sz = i->Pin.StoreC.sz;
   1765       HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd';
   1766       vex_printf("st%ccx. ", c_sz);
   1767       ppHRegPPC(i->Pin.StoreC.src);
   1768       vex_printf(",%%r0,");
   1769       ppHRegPPC(i->Pin.StoreC.dst);
   1770       return;
   1771    }
   1772    case Pin_Set: {
   1773       PPCCondCode cc = i->Pin.Set.cond;
   1774       vex_printf("set (%s),", showPPCCondCode(cc));
   1775       ppHRegPPC(i->Pin.Set.dst);
   1776       if (cc.test == Pct_ALWAYS) {
   1777          vex_printf(": { li ");
   1778          ppHRegPPC(i->Pin.Set.dst);
   1779          vex_printf(",1 }");
   1780       } else {
   1781          vex_printf(": { mfcr r0 ; rlwinm ");
   1782          ppHRegPPC(i->Pin.Set.dst);
   1783          vex_printf(",r0,%u,31,31", cc.flag+1);
   1784          if (cc.test == Pct_FALSE) {
   1785             vex_printf("; xori ");
   1786             ppHRegPPC(i->Pin.Set.dst);
   1787             vex_printf(",");
   1788             ppHRegPPC(i->Pin.Set.dst);
   1789             vex_printf(",1");
   1790          }
   1791          vex_printf(" }");
   1792       }
   1793       return;
   1794    }
   1795    case Pin_MfCR:
   1796       vex_printf("mfcr ");
   1797       ppHRegPPC(i->Pin.MfCR.dst);
   1798       break;
   1799    case Pin_MFence:
   1800       vex_printf("mfence (=sync)");
   1801       return;
   1802 
   1803    case Pin_FpUnary:
   1804       vex_printf("%s ", showPPCFpOp(i->Pin.FpUnary.op));
   1805       ppHRegPPC(i->Pin.FpUnary.dst);
   1806       vex_printf(",");
   1807       ppHRegPPC(i->Pin.FpUnary.src);
   1808       return;
   1809    case Pin_FpBinary:
   1810       vex_printf("%s ", showPPCFpOp(i->Pin.FpBinary.op));
   1811       ppHRegPPC(i->Pin.FpBinary.dst);
   1812       vex_printf(",");
   1813       ppHRegPPC(i->Pin.FpBinary.srcL);
   1814       vex_printf(",");
   1815       ppHRegPPC(i->Pin.FpBinary.srcR);
   1816       return;
   1817    case Pin_Fp128Unary:
   1818       vex_printf("%s ", showPPCFpOp(i->Pin.Fp128Unary.op));
   1819       ppHRegPPC(i->Pin.Fp128Unary.dst);
   1820       vex_printf(",");
   1821       ppHRegPPC(i->Pin.Fp128Unary.src);
   1822       return;
   1823    case Pin_Fp128Binary:
   1824       vex_printf("%s ", showPPCFpOp(i->Pin.Fp128Binary.op));
   1825       ppHRegPPC(i->Pin.Fp128Binary.dst);
   1826       vex_printf(",");
   1827       ppHRegPPC(i->Pin.Fp128Binary.srcL);
   1828       vex_printf(",");
   1829       ppHRegPPC(i->Pin.Fp128Binary.srcR);
   1830       return;
   1831    case Pin_Fp128Trinary:
   1832       vex_printf("%s ", showPPCFpOp(i->Pin.Fp128Trinary.op));
   1833       ppHRegPPC(i->Pin.Fp128Trinary.dst);
   1834       vex_printf(",");
   1835       ppHRegPPC(i->Pin.Fp128Trinary.srcL);
   1836       vex_printf(",");
   1837       ppHRegPPC(i->Pin.Fp128Trinary.srcR);
   1838       return;
   1839    case Pin_FpMulAcc:
   1840       vex_printf("%s ", showPPCFpOp(i->Pin.FpMulAcc.op));
   1841       ppHRegPPC(i->Pin.FpMulAcc.dst);
   1842       vex_printf(",");
   1843       ppHRegPPC(i->Pin.FpMulAcc.srcML);
   1844       vex_printf(",");
   1845       ppHRegPPC(i->Pin.FpMulAcc.srcMR);
   1846       vex_printf(",");
   1847       ppHRegPPC(i->Pin.FpMulAcc.srcAcc);
   1848       return;
   1849    case Pin_FpLdSt: {
   1850       UChar sz = i->Pin.FpLdSt.sz;
   1851       Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR);
   1852       if (i->Pin.FpLdSt.isLoad) {
   1853          vex_printf("lf%c%s ",
   1854                     (sz==4 ? 's' : 'd'),
   1855                     idxd ? "x" : "" );
   1856          ppHRegPPC(i->Pin.FpLdSt.reg);
   1857          vex_printf(",");
   1858          ppPPCAMode(i->Pin.FpLdSt.addr);
   1859       } else {
   1860          vex_printf("stf%c%s ",
   1861                     (sz==4 ? 's' : 'd'),
   1862                     idxd ? "x" : "" );
   1863          ppHRegPPC(i->Pin.FpLdSt.reg);
   1864          vex_printf(",");
   1865          ppPPCAMode(i->Pin.FpLdSt.addr);
   1866       }
   1867       return;
   1868    }
   1869    case Pin_FpSTFIW:
   1870       vex_printf("stfiwz ");
   1871       ppHRegPPC(i->Pin.FpSTFIW.data);
   1872       vex_printf(",0(");
   1873       ppHRegPPC(i->Pin.FpSTFIW.addr);
   1874       vex_printf(")");
   1875       return;
   1876    case Pin_FpRSP:
   1877       vex_printf("frsp ");
   1878       ppHRegPPC(i->Pin.FpRSP.dst);
   1879       vex_printf(",");
   1880       ppHRegPPC(i->Pin.FpRSP.src);
   1881       return;
   1882    case Pin_FpCftI: {
   1883       const HChar* str = "fc?????";
   1884       /* Note that "fcfids" is missing from below. That instruction would
   1885        * satisfy the predicate:
   1886        *    (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False)
   1887        * which would go into a final "else" clause to make this if-else
   1888        * block balanced.  But we're able to implement fcfids by leveraging
   1889        * the fcfid implementation, so it wasn't necessary to include it here.
   1890        */
   1891       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False)
   1892          if (i->Pin.FpCftI.syned == True)
   1893             str = "fctid";
   1894          else
   1895             str = "fctidu";
   1896       else if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True)
   1897          if (i->Pin.FpCftI.syned == True)
   1898             str = "fctiw";
   1899          else
   1900             str = "fctiwu";
   1901       else if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
   1902          if (i->Pin.FpCftI.syned == True) {
   1903             str = "fcfid";
   1904          } else {
   1905             if (i->Pin.FpCftI.flt64 == True)
   1906                str = "fcfidu";
   1907             else
   1908                str = "fcfidus";
   1909          }
   1910       }
   1911       vex_printf("%s ", str);
   1912       ppHRegPPC(i->Pin.FpCftI.dst);
   1913       vex_printf(",");
   1914       ppHRegPPC(i->Pin.FpCftI.src);
   1915       return;
   1916    }
   1917    case Pin_FpCMov:
   1918       vex_printf("fpcmov (%s) ", showPPCCondCode(i->Pin.FpCMov.cond));
   1919       ppHRegPPC(i->Pin.FpCMov.dst);
   1920       vex_printf(",");
   1921       ppHRegPPC(i->Pin.FpCMov.src);
   1922       vex_printf(": ");
   1923       vex_printf("if (fr_dst != fr_src) { ");
   1924       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS) {
   1925          vex_printf("if (%s) { ", showPPCCondCode(i->Pin.FpCMov.cond));
   1926       }
   1927       vex_printf("fmr ");
   1928       ppHRegPPC(i->Pin.FpCMov.dst);
   1929       vex_printf(",");
   1930       ppHRegPPC(i->Pin.FpCMov.src);
   1931       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS)
   1932          vex_printf(" }");
   1933       vex_printf(" }");
   1934       return;
   1935    case Pin_FpLdFPSCR:
   1936       vex_printf("mtfsf 0xFF,");
   1937       ppHRegPPC(i->Pin.FpLdFPSCR.src);
   1938       vex_printf(",0, %s", i->Pin.FpLdFPSCR.dfp_rm ? "1" : "0");
   1939       return;
   1940    case Pin_FpCmp:
   1941       vex_printf("fcmpo %%cr1,");
   1942       ppHRegPPC(i->Pin.FpCmp.srcL);
   1943       vex_printf(",");
   1944       ppHRegPPC(i->Pin.FpCmp.srcR);
   1945       vex_printf("; mfcr ");
   1946       ppHRegPPC(i->Pin.FpCmp.dst);
   1947       vex_printf("; rlwinm ");
   1948       ppHRegPPC(i->Pin.FpCmp.dst);
   1949       vex_printf(",");
   1950       ppHRegPPC(i->Pin.FpCmp.dst);
   1951       vex_printf(",8,28,31");
   1952       return;
   1953 
   1954    case Pin_RdWrLR:
   1955       vex_printf("%s ", i->Pin.RdWrLR.wrLR ? "mtlr" : "mflr");
   1956       ppHRegPPC(i->Pin.RdWrLR.gpr);
   1957       return;
   1958 
   1959    case Pin_AvLdSt: {
   1960       UChar  sz = i->Pin.AvLdSt.sz;
   1961       const HChar* str_size;
   1962       if (i->Pin.AvLdSt.addr->tag == Pam_IR) {
   1963          ppLoadImm(hregPPC_GPR30(mode64),
   1964                    i->Pin.AvLdSt.addr->Pam.IR.index, mode64);
   1965          vex_printf(" ; ");
   1966       }
   1967       str_size = sz==1 ? "eb" : sz==2 ? "eh" : sz==4 ? "ew" : "";
   1968       if (i->Pin.AvLdSt.isLoad)
   1969          vex_printf("lv%sx ", str_size);
   1970       else
   1971          vex_printf("stv%sx ", str_size);
   1972       ppHRegPPC(i->Pin.AvLdSt.reg);
   1973       vex_printf(",");
   1974       if (i->Pin.AvLdSt.addr->tag == Pam_IR)
   1975          vex_printf("%%r30");
   1976       else
   1977          ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.index);
   1978       vex_printf(",");
   1979       ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.base);
   1980       return;
   1981    }
   1982    case Pin_AvUnary:
   1983       vex_printf("%s ", showPPCAvOp(i->Pin.AvUnary.op));
   1984       ppHRegPPC(i->Pin.AvUnary.dst);
   1985       vex_printf(",");
   1986       ppHRegPPC(i->Pin.AvUnary.src);
   1987       return;
   1988    case Pin_AvBinary:
   1989       vex_printf("%s ", showPPCAvOp(i->Pin.AvBinary.op));
   1990       ppHRegPPC(i->Pin.AvBinary.dst);
   1991       vex_printf(",");
   1992       ppHRegPPC(i->Pin.AvBinary.srcL);
   1993       vex_printf(",");
   1994       ppHRegPPC(i->Pin.AvBinary.srcR);
   1995       return;
   1996    case Pin_AvBinaryInt:
   1997       vex_printf("%s ", showPPCAvOp(i->Pin.AvBinaryInt.op));
   1998       ppHRegPPC(i->Pin.AvBinaryInt.dst);
   1999       vex_printf(",");
   2000       ppHRegPPC(i->Pin.AvBinaryInt.src);
   2001       vex_printf(",");
   2002       ppPPCRI(i->Pin.AvBinaryInt.val);
   2003       return;
   2004    case Pin_AvBin8x16:
   2005       vex_printf("%s(b) ", showPPCAvOp(i->Pin.AvBin8x16.op));
   2006       ppHRegPPC(i->Pin.AvBin8x16.dst);
   2007       vex_printf(",");
   2008       ppHRegPPC(i->Pin.AvBin8x16.srcL);
   2009       vex_printf(",");
   2010       ppHRegPPC(i->Pin.AvBin8x16.srcR);
   2011       return;
   2012    case Pin_AvBin16x8:
   2013       vex_printf("%s(h) ", showPPCAvOp(i->Pin.AvBin16x8.op));
   2014       ppHRegPPC(i->Pin.AvBin16x8.dst);
   2015       vex_printf(",");
   2016       ppHRegPPC(i->Pin.AvBin16x8.srcL);
   2017       vex_printf(",");
   2018       ppHRegPPC(i->Pin.AvBin16x8.srcR);
   2019       return;
   2020    case Pin_AvBin32x4:
   2021       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin32x4.op));
   2022       ppHRegPPC(i->Pin.AvBin32x4.dst);
   2023       vex_printf(",");
   2024       ppHRegPPC(i->Pin.AvBin32x4.srcL);
   2025       vex_printf(",");
   2026       ppHRegPPC(i->Pin.AvBin32x4.srcR);
   2027       return;
   2028    case Pin_AvBin64x2:
   2029       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin64x2.op));
   2030       ppHRegPPC(i->Pin.AvBin64x2.dst);
   2031       vex_printf(",");
   2032       ppHRegPPC(i->Pin.AvBin64x2.srcL);
   2033       vex_printf(",");
   2034       ppHRegPPC(i->Pin.AvBin64x2.srcR);
   2035       return;
   2036    case Pin_AvBin32Fx4:
   2037       vex_printf("%s ", showPPCAvFpOp(i->Pin.AvBin32Fx4.op));
   2038       ppHRegPPC(i->Pin.AvBin32Fx4.dst);
   2039       vex_printf(",");
   2040       ppHRegPPC(i->Pin.AvBin32Fx4.srcL);
   2041       vex_printf(",");
   2042       ppHRegPPC(i->Pin.AvBin32Fx4.srcR);
   2043       return;
   2044    case Pin_AvUn32Fx4:
   2045       vex_printf("%s ", showPPCAvFpOp(i->Pin.AvUn32Fx4.op));
   2046       ppHRegPPC(i->Pin.AvUn32Fx4.dst);
   2047       vex_printf(",");
   2048       ppHRegPPC(i->Pin.AvUn32Fx4.src);
   2049       return;
   2050    case Pin_AvPerm:
   2051       vex_printf("vperm ");
   2052       ppHRegPPC(i->Pin.AvPerm.dst);
   2053       vex_printf(",");
   2054       ppHRegPPC(i->Pin.AvPerm.srcL);
   2055       vex_printf(",");
   2056       ppHRegPPC(i->Pin.AvPerm.srcR);
   2057       vex_printf(",");
   2058       ppHRegPPC(i->Pin.AvPerm.ctl);
   2059       return;
   2060 
   2061    case Pin_AvSel:
   2062       vex_printf("vsel ");
   2063       ppHRegPPC(i->Pin.AvSel.dst);
   2064       vex_printf(",");
   2065       ppHRegPPC(i->Pin.AvSel.srcL);
   2066       vex_printf(",");
   2067       ppHRegPPC(i->Pin.AvSel.srcR);
   2068       vex_printf(",");
   2069       ppHRegPPC(i->Pin.AvSel.ctl);
   2070       return;
   2071 
   2072    case Pin_AvSh:
   2073       /* This only generates the following instructions with RA
   2074        * register number set to 0.
   2075        */
   2076       if (i->Pin.AvSh.addr->tag == Pam_IR) {
   2077          ppLoadImm(hregPPC_GPR30(mode64),
   2078                    i->Pin.AvSh.addr->Pam.IR.index, mode64);
   2079          vex_printf(" ; ");
   2080       }
   2081 
   2082       if (i->Pin.AvSh.shLeft)
   2083          vex_printf("lvsl ");
   2084       else
   2085          vex_printf("lvsr ");
   2086 
   2087       ppHRegPPC(i->Pin.AvSh.dst);
   2088       if (i->Pin.AvSh.addr->tag == Pam_IR)
   2089          vex_printf("%%r30");
   2090       else
   2091          ppHRegPPC(i->Pin.AvSh.addr->Pam.RR.index);
   2092       vex_printf(",");
   2093       ppHRegPPC(i->Pin.AvSh.addr->Pam.RR.base);
   2094       return;
   2095 
   2096    case Pin_AvShlDbl:
   2097       vex_printf("vsldoi ");
   2098       ppHRegPPC(i->Pin.AvShlDbl.dst);
   2099       vex_printf(",");
   2100       ppHRegPPC(i->Pin.AvShlDbl.srcL);
   2101       vex_printf(",");
   2102       ppHRegPPC(i->Pin.AvShlDbl.srcR);
   2103       vex_printf(",%d", i->Pin.AvShlDbl.shift);
   2104       return;
   2105 
   2106    case Pin_AvSplat: {
   2107       UChar sz = i->Pin.AvSplat.sz;
   2108       HChar ch_sz = toUChar( (sz == 8) ? 'b' : (sz == 16) ? 'h' : 'w' );
   2109       vex_printf("vsplt%s%c ",
   2110                  i->Pin.AvSplat.src->tag == Pvi_Imm ? "is" : "", ch_sz);
   2111       ppHRegPPC(i->Pin.AvSplat.dst);
   2112       vex_printf(",");
   2113       ppPPCVI5s(i->Pin.AvSplat.src);
   2114       if (i->Pin.AvSplat.src->tag == Pvi_Reg)
   2115          vex_printf(", %d", (128/sz)-1);   /* louis lane */
   2116       return;
   2117    }
   2118 
   2119    case Pin_AvCMov:
   2120       vex_printf("avcmov (%s) ", showPPCCondCode(i->Pin.AvCMov.cond));
   2121       ppHRegPPC(i->Pin.AvCMov.dst);
   2122       vex_printf(",");
   2123       ppHRegPPC(i->Pin.AvCMov.src);
   2124       vex_printf(": ");
   2125       vex_printf("if (v_dst != v_src) { ");
   2126       if (i->Pin.AvCMov.cond.test != Pct_ALWAYS) {
   2127          vex_printf("if (%s) { ", showPPCCondCode(i->Pin.AvCMov.cond));
   2128       }
   2129       vex_printf("vmr ");
   2130       ppHRegPPC(i->Pin.AvCMov.dst);
   2131       vex_printf(",");
   2132       ppHRegPPC(i->Pin.AvCMov.src);
   2133       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS)
   2134          vex_printf(" }");
   2135       vex_printf(" }");
   2136       return;
   2137 
   2138    case Pin_AvLdVSCR:
   2139       vex_printf("mtvscr ");
   2140       ppHRegPPC(i->Pin.AvLdVSCR.src);
   2141       return;
   2142 
   2143    case Pin_AvCipherV128Unary:
   2144       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvCipherV128Unary.op));
   2145       ppHRegPPC(i->Pin.AvCipherV128Unary.dst);
   2146       vex_printf(",");
   2147       ppHRegPPC(i->Pin.AvCipherV128Unary.src);
   2148       return;
   2149 
   2150    case Pin_AvCipherV128Binary:
   2151       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvCipherV128Binary.op));
   2152       ppHRegPPC(i->Pin.AvCipherV128Binary.dst);
   2153       vex_printf(",");
   2154       ppHRegPPC(i->Pin.AvCipherV128Binary.srcL);
   2155       vex_printf(",");
   2156       ppHRegPPC(i->Pin.AvCipherV128Binary.srcR);
   2157       return;
   2158 
   2159    case Pin_AvHashV128Binary:
   2160       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvHashV128Binary.op));
   2161       ppHRegPPC(i->Pin.AvHashV128Binary.dst);
   2162       vex_printf(",");
   2163       ppHRegPPC(i->Pin.AvHashV128Binary.src);
   2164       vex_printf(",");
   2165       ppPPCRI(i->Pin.AvHashV128Binary.s_field);
   2166       return;
   2167 
   2168    case Pin_AvBCDV128Binary:
   2169       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBCDV128Binary.op));
   2170       ppHRegPPC(i->Pin.AvBCDV128Binary.dst);
   2171       vex_printf(",");
   2172       ppHRegPPC(i->Pin.AvBCDV128Binary.src1);
   2173       vex_printf(",");
   2174       ppHRegPPC(i->Pin.AvBCDV128Binary.src2);
   2175       return;
   2176 
   2177    case Pin_Dfp64Unary:
   2178       vex_printf("%s ", showPPCFpOp(i->Pin.Dfp64Unary.op));
   2179       ppHRegPPC(i->Pin.Dfp64Unary.dst);
   2180       vex_printf(",");
   2181       ppHRegPPC(i->Pin.Dfp64Unary.src);
   2182       return;
   2183 
   2184    case Pin_Dfp64Binary:
   2185       vex_printf("%s ", showPPCFpOp(i->Pin.Dfp64Binary.op));
   2186       ppHRegPPC(i->Pin.Dfp64Binary.dst);
   2187       vex_printf(",");
   2188       ppHRegPPC(i->Pin.Dfp64Binary.srcL);
   2189       vex_printf(",");
   2190       ppHRegPPC(i->Pin.Dfp64Binary.srcR);
   2191       return;
   2192 
   2193    case Pin_DfpShift:
   2194       vex_printf("%s ", showPPCFpOp(i->Pin.DfpShift.op));
   2195       ppHRegPPC(i->Pin.DfpShift.dst);
   2196       vex_printf(",");
   2197       ppHRegPPC(i->Pin.DfpShift.src);
   2198       vex_printf(",");
   2199       ppPPCRI(i->Pin.DfpShift.shift);
   2200       return;
   2201 
   2202    case Pin_Dfp128Unary:
   2203       vex_printf("%s ", showPPCFpOp(i->Pin.Dfp128Unary.op));
   2204       ppHRegPPC(i->Pin.Dfp128Unary.dst_hi);
   2205       vex_printf(",");
   2206       ppHRegPPC(i->Pin.Dfp128Unary.src_hi);
   2207       return;
   2208 
   2209    case Pin_Dfp128Binary:
   2210       vex_printf("%s ", showPPCFpOp(i->Pin.Dfp128Binary.op));
   2211       ppHRegPPC(i->Pin.Dfp128Binary.dst_hi);
   2212       vex_printf(",");
   2213       ppHRegPPC(i->Pin.Dfp128Binary.srcR_hi);
   2214       return;
   2215 
   2216    case Pin_DfpShift128:
   2217       vex_printf("%s ", showPPCFpOp(i->Pin.DfpShift128.op));
   2218       ppHRegPPC(i->Pin.DfpShift128.dst_hi);
   2219       vex_printf(",");
   2220       ppHRegPPC(i->Pin.DfpShift128.src_hi);
   2221       vex_printf(",");
   2222       ppPPCRI(i->Pin.DfpShift128.shift);
   2223       return;
   2224 
   2225    case Pin_DfpRound:
   2226       vex_printf("drintx ");
   2227       ppHRegPPC(i->Pin.DfpRound.dst);
   2228       vex_printf(",");
   2229       ppHRegPPC(i->Pin.DfpRound.src);
   2230       vex_printf(",");
   2231       ppPPCRI(i->Pin.DfpRound.r_rmc); /*  R in bit 3 and RMC in bits 2:0 */
   2232       return;
   2233 
   2234    case Pin_DfpRound128:
   2235       vex_printf("drintxq ");
   2236       ppHRegPPC(i->Pin.DfpRound128.dst_hi);
   2237       vex_printf(",");
   2238       ppHRegPPC(i->Pin.DfpRound128.src_hi);
   2239       vex_printf(",");
   2240       ppPPCRI(i->Pin.DfpRound128.r_rmc); /*  R in bit 3 and RMC in bits 2:0 */
   2241       return;
   2242 
   2243    case Pin_DfpQuantize:
   2244       vex_printf("%s ", showPPCFpOp(i->Pin.DfpQuantize.op));
   2245       ppHRegPPC(i->Pin.DfpQuantize.dst);
   2246       vex_printf(",");
   2247       ppHRegPPC(i->Pin.DfpQuantize.srcL);
   2248       vex_printf(",");
   2249       ppHRegPPC(i->Pin.DfpQuantize.srcR);
   2250       vex_printf(",");
   2251       ppPPCRI(i->Pin.DfpQuantize.rmc);
   2252       return;
   2253 
   2254    case Pin_DfpQuantize128:
   2255       /*  Dst is used to pass in left source and return result */
   2256       vex_printf("dquaq ");
   2257       ppHRegPPC(i->Pin.DfpQuantize128.dst_hi);
   2258       vex_printf(",");
   2259       ppHRegPPC(i->Pin.DfpQuantize128.dst_hi);
   2260       vex_printf(",");
   2261       ppHRegPPC(i->Pin.DfpQuantize128.src_hi);
   2262       vex_printf(",");
   2263       ppPPCRI(i->Pin.DfpQuantize128.rmc);
   2264       return;
   2265 
   2266    case Pin_DfpD128toD64:
   2267       vex_printf("%s ", showPPCFpOp(i->Pin.DfpD128toD64.op));
   2268       ppHRegPPC(i->Pin.DfpD128toD64.dst);
   2269       vex_printf(",");
   2270       ppHRegPPC(i->Pin.DfpD128toD64.src_hi);
   2271       vex_printf(",");
   2272       return;
   2273 
   2274    case Pin_DfpI64StoD128:
   2275       vex_printf("%s ", showPPCFpOp(i->Pin.DfpI64StoD128.op));
   2276       ppHRegPPC(i->Pin.DfpI64StoD128.dst_hi);
   2277       vex_printf(",");
   2278       ppHRegPPC(i->Pin.DfpI64StoD128.src);
   2279       vex_printf(",");
   2280       return;
   2281    case Pin_ExtractExpD128:
   2282       vex_printf("dxexq ");
   2283       ppHRegPPC(i->Pin.ExtractExpD128.dst);
   2284       vex_printf(",");
   2285       ppHRegPPC(i->Pin.ExtractExpD128.src_hi);
   2286       return;
   2287    case Pin_InsertExpD128:
   2288       vex_printf("diexq ");
   2289       ppHRegPPC(i->Pin.InsertExpD128.dst_hi);
   2290       vex_printf(",");
   2291       ppHRegPPC(i->Pin.InsertExpD128.srcL);
   2292       vex_printf(",");
   2293       ppHRegPPC(i->Pin.InsertExpD128.srcR_hi);
   2294       return;
   2295    case Pin_Dfp64Cmp:
   2296       vex_printf("dcmpo %%cr1,");
   2297       ppHRegPPC(i->Pin.Dfp64Cmp.srcL);
   2298       vex_printf(",");
   2299       ppHRegPPC(i->Pin.Dfp64Cmp.srcR);
   2300       vex_printf("; mfcr ");
   2301       ppHRegPPC(i->Pin.Dfp64Cmp.dst);
   2302       vex_printf("; rlwinm ");
   2303       ppHRegPPC(i->Pin.Dfp64Cmp.dst);
   2304       vex_printf(",");
   2305       ppHRegPPC(i->Pin.Dfp64Cmp.dst);
   2306       vex_printf(",8,28,31");
   2307       return;
   2308    case Pin_Dfp128Cmp:
   2309       vex_printf("dcmpoq %%cr1,");
   2310       ppHRegPPC(i->Pin.Dfp128Cmp.srcL_hi);
   2311       vex_printf(",");
   2312       ppHRegPPC(i->Pin.Dfp128Cmp.srcR_hi);
   2313       vex_printf("; mfcr ");
   2314       ppHRegPPC(i->Pin.Dfp128Cmp.dst);
   2315       vex_printf("; rlwinm ");
   2316       ppHRegPPC(i->Pin.Dfp128Cmp.dst);
   2317       vex_printf(",");
   2318       ppHRegPPC(i->Pin.Dfp128Cmp.dst);
   2319       vex_printf(",8,28,31");
   2320       return;
   2321    case Pin_EvCheck:
   2322       /* Note that the counter dec is 32 bit even in 64-bit mode. */
   2323       vex_printf("(evCheck) ");
   2324       vex_printf("lwz r30,");
   2325       ppPPCAMode(i->Pin.EvCheck.amCounter);
   2326       vex_printf("; addic. r30,r30,-1; ");
   2327       vex_printf("stw r30,");
   2328       ppPPCAMode(i->Pin.EvCheck.amCounter);
   2329       vex_printf("; bge nofail; lwz r30,");
   2330       ppPPCAMode(i->Pin.EvCheck.amFailAddr);
   2331       vex_printf("; mtctr r30; bctr; nofail:");
   2332       return;
   2333    case Pin_ProfInc:
   2334       if (mode64) {
   2335          vex_printf("(profInc) imm64-fixed5 r30,$NotKnownYet; ");
   2336          vex_printf("ld r29,(r30); addi r29,r29,1; std r29,(r30)");
   2337       } else {
   2338          vex_printf("(profInc) imm32-fixed2 r30,$NotKnownYet; ");
   2339          vex_printf("lwz r29,4(r30); addic. r29,r29,1; stw r29,4(r30)");
   2340          vex_printf("lwz r29,0(r30); addze r29,r29; stw r29,0(r30)");
   2341       }
   2342       break;
   2343    default:
   2344       vex_printf("\nppPPCInstr: No such tag(%d)\n", (Int)i->tag);
   2345       vpanic("ppPPCInstr");
   2346    }
   2347 }
   2348 
   2349 /* --------- Helpers for register allocation. --------- */
   2350 
   2351 void getRegUsage_PPCInstr ( HRegUsage* u, const PPCInstr* i, Bool mode64 )
   2352 {
   2353    initHRegUsage(u);
   2354    switch (i->tag) {
   2355    case Pin_LI:
   2356       addHRegUse(u, HRmWrite, i->Pin.LI.dst);
   2357       break;
   2358    case Pin_Alu:
   2359       addHRegUse(u, HRmRead,  i->Pin.Alu.srcL);
   2360       addRegUsage_PPCRH(u,    i->Pin.Alu.srcR);
   2361       addHRegUse(u, HRmWrite, i->Pin.Alu.dst);
   2362       return;
   2363    case Pin_Shft:
   2364       addHRegUse(u, HRmRead,  i->Pin.Shft.srcL);
   2365       addRegUsage_PPCRH(u,    i->Pin.Shft.srcR);
   2366       addHRegUse(u, HRmWrite, i->Pin.Shft.dst);
   2367       return;
   2368    case Pin_AddSubC:
   2369       addHRegUse(u, HRmWrite, i->Pin.AddSubC.dst);
   2370       addHRegUse(u, HRmRead,  i->Pin.AddSubC.srcL);
   2371       addHRegUse(u, HRmRead,  i->Pin.AddSubC.srcR);
   2372       return;
   2373    case Pin_Cmp:
   2374       addHRegUse(u, HRmRead, i->Pin.Cmp.srcL);
   2375       addRegUsage_PPCRH(u,   i->Pin.Cmp.srcR);
   2376       return;
   2377    case Pin_Unary:
   2378       addHRegUse(u, HRmWrite, i->Pin.Unary.dst);
   2379       addHRegUse(u, HRmRead,  i->Pin.Unary.src);
   2380       return;
   2381    case Pin_MulL:
   2382       addHRegUse(u, HRmWrite, i->Pin.MulL.dst);
   2383       addHRegUse(u, HRmRead,  i->Pin.MulL.srcL);
   2384       addHRegUse(u, HRmRead,  i->Pin.MulL.srcR);
   2385       return;
   2386    case Pin_Div:
   2387       addHRegUse(u, HRmWrite, i->Pin.Div.dst);
   2388       addHRegUse(u, HRmRead,  i->Pin.Div.srcL);
   2389       addHRegUse(u, HRmRead,  i->Pin.Div.srcR);
   2390       return;
   2391    case Pin_Call: {
   2392       UInt argir;
   2393       /* This is a bit subtle. */
   2394       /* First off, claim it trashes all the caller-saved regs
   2395          which fall within the register allocator's jurisdiction.
   2396          These I believe to be:
   2397          mode32: r3 to r12
   2398          mode64: r3 to r10
   2399       */
   2400       /* XXXXXXXXXXXXXXXXX BUG! This doesn't say anything about the FP
   2401          or Altivec registers.  We get away with this ONLY because
   2402          getAllocatableRegs_PPC gives the allocator callee-saved fp
   2403          and Altivec regs, and no caller-save ones. */
   2404       addHRegUse(u, HRmWrite, hregPPC_GPR3(mode64));
   2405       addHRegUse(u, HRmWrite, hregPPC_GPR4(mode64));
   2406       addHRegUse(u, HRmWrite, hregPPC_GPR5(mode64));
   2407       addHRegUse(u, HRmWrite, hregPPC_GPR6(mode64));
   2408       addHRegUse(u, HRmWrite, hregPPC_GPR7(mode64));
   2409       addHRegUse(u, HRmWrite, hregPPC_GPR8(mode64));
   2410       addHRegUse(u, HRmWrite, hregPPC_GPR9(mode64));
   2411       addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64));
   2412       if (!mode64) {
   2413          addHRegUse(u, HRmWrite, hregPPC_GPR11(mode64));
   2414          addHRegUse(u, HRmWrite, hregPPC_GPR12(mode64));
   2415       }
   2416 
   2417       /* Now we have to state any parameter-carrying registers
   2418          which might be read.  This depends on the argiregs field. */
   2419       argir = i->Pin.Call.argiregs;
   2420       if (argir &(1<<10)) addHRegUse(u, HRmRead, hregPPC_GPR10(mode64));
   2421       if (argir & (1<<9)) addHRegUse(u, HRmRead, hregPPC_GPR9(mode64));
   2422       if (argir & (1<<8)) addHRegUse(u, HRmRead, hregPPC_GPR8(mode64));
   2423       if (argir & (1<<7)) addHRegUse(u, HRmRead, hregPPC_GPR7(mode64));
   2424       if (argir & (1<<6)) addHRegUse(u, HRmRead, hregPPC_GPR6(mode64));
   2425       if (argir & (1<<5)) addHRegUse(u, HRmRead, hregPPC_GPR5(mode64));
   2426       if (argir & (1<<4)) addHRegUse(u, HRmRead, hregPPC_GPR4(mode64));
   2427       if (argir & (1<<3)) addHRegUse(u, HRmRead, hregPPC_GPR3(mode64));
   2428 
   2429       vassert(0 == (argir & ~((1<<3)|(1<<4)|(1<<5)|(1<<6)
   2430                               |(1<<7)|(1<<8)|(1<<9)|(1<<10))));
   2431 
   2432       /* Finally, there is the issue that the insn trashes a
   2433          register because the literal target address has to be
   2434          loaded into a register.  %r10 seems a suitable victim.
   2435          (Can't use %r0, as some insns interpret it as value zero). */
   2436       addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64));
   2437       /* Upshot of this is that the assembler really must use %r10,
   2438          and no other, as a destination temporary. */
   2439       return;
   2440    }
   2441    /* XDirect/XIndir/XAssisted are also a bit subtle.  They
   2442       conditionally exit the block.  Hence we only need to list (1)
   2443       the registers that they read, and (2) the registers that they
   2444       write in the case where the block is not exited.  (2) is empty,
   2445       hence only (1) is relevant here. */
   2446    case Pin_XDirect:
   2447       addRegUsage_PPCAMode(u, i->Pin.XDirect.amCIA);
   2448       return;
   2449    case Pin_XIndir:
   2450       addHRegUse(u, HRmRead, i->Pin.XIndir.dstGA);
   2451       addRegUsage_PPCAMode(u, i->Pin.XIndir.amCIA);
   2452       return;
   2453    case Pin_XAssisted:
   2454       addHRegUse(u, HRmRead, i->Pin.XAssisted.dstGA);
   2455       addRegUsage_PPCAMode(u, i->Pin.XAssisted.amCIA);
   2456       return;
   2457    case Pin_CMov:
   2458       addRegUsage_PPCRI(u,  i->Pin.CMov.src);
   2459       addHRegUse(u, HRmWrite, i->Pin.CMov.dst);
   2460       return;
   2461    case Pin_Load:
   2462       addRegUsage_PPCAMode(u, i->Pin.Load.src);
   2463       addHRegUse(u, HRmWrite, i->Pin.Load.dst);
   2464       return;
   2465    case Pin_LoadL:
   2466       addHRegUse(u, HRmRead,  i->Pin.LoadL.src);
   2467       addHRegUse(u, HRmWrite, i->Pin.LoadL.dst);
   2468       return;
   2469    case Pin_Store:
   2470       addHRegUse(u, HRmRead,  i->Pin.Store.src);
   2471       addRegUsage_PPCAMode(u, i->Pin.Store.dst);
   2472       return;
   2473    case Pin_StoreC:
   2474       addHRegUse(u, HRmRead, i->Pin.StoreC.src);
   2475       addHRegUse(u, HRmRead, i->Pin.StoreC.dst);
   2476       return;
   2477    case Pin_Set:
   2478       addHRegUse(u, HRmWrite, i->Pin.Set.dst);
   2479       return;
   2480    case Pin_MfCR:
   2481       addHRegUse(u, HRmWrite, i->Pin.MfCR.dst);
   2482       return;
   2483    case Pin_MFence:
   2484       return;
   2485 
   2486    case Pin_FpUnary:
   2487       addHRegUse(u, HRmWrite, i->Pin.FpUnary.dst);
   2488       addHRegUse(u, HRmRead,  i->Pin.FpUnary.src);
   2489       return;
   2490    case Pin_FpBinary:
   2491       addHRegUse(u, HRmWrite, i->Pin.FpBinary.dst);
   2492       addHRegUse(u, HRmRead,  i->Pin.FpBinary.srcL);
   2493       addHRegUse(u, HRmRead,  i->Pin.FpBinary.srcR);
   2494       return;
   2495 
   2496    case Pin_Fp128Unary:
   2497       addHRegUse(u, HRmWrite, i->Pin.Fp128Unary.dst);
   2498       addHRegUse(u, HRmRead, i->Pin.Fp128Unary.src);
   2499       return;
   2500    case Pin_Fp128Binary:
   2501       addHRegUse(u, HRmWrite, i->Pin.Fp128Binary.dst);
   2502       addHRegUse(u, HRmRead, i->Pin.Fp128Binary.srcL);
   2503       addHRegUse(u, HRmRead, i->Pin.Fp128Binary.srcR);
   2504       return;
   2505    case Pin_Fp128Trinary:
   2506       addHRegUse(u, HRmModify, i->Pin.Fp128Trinary.dst);
   2507       addHRegUse(u, HRmRead, i->Pin.Fp128Trinary.srcL);
   2508       addHRegUse(u, HRmRead, i->Pin.Fp128Trinary.srcR);
   2509       return;
   2510    case Pin_FpMulAcc:
   2511       addHRegUse(u, HRmWrite, i->Pin.FpMulAcc.dst);
   2512       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcML);
   2513       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcMR);
   2514       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcAcc);
   2515       return;
   2516    case Pin_FpLdSt:
   2517       addHRegUse(u, (i->Pin.FpLdSt.isLoad ? HRmWrite : HRmRead),
   2518                  i->Pin.FpLdSt.reg);
   2519       addRegUsage_PPCAMode(u, i->Pin.FpLdSt.addr);
   2520       return;
   2521    case Pin_FpSTFIW:
   2522       addHRegUse(u, HRmRead, i->Pin.FpSTFIW.addr);
   2523       addHRegUse(u, HRmRead, i->Pin.FpSTFIW.data);
   2524       return;
   2525    case Pin_FpRSP:
   2526       addHRegUse(u, HRmWrite, i->Pin.FpRSP.dst);
   2527       addHRegUse(u, HRmRead,  i->Pin.FpRSP.src);
   2528       return;
   2529    case Pin_FpCftI:
   2530       addHRegUse(u, HRmWrite, i->Pin.FpCftI.dst);
   2531       addHRegUse(u, HRmRead,  i->Pin.FpCftI.src);
   2532       return;
   2533    case Pin_FpCMov:
   2534       addHRegUse(u, HRmModify, i->Pin.FpCMov.dst);
   2535       addHRegUse(u, HRmRead,   i->Pin.FpCMov.src);
   2536       return;
   2537    case Pin_FpLdFPSCR:
   2538       addHRegUse(u, HRmRead, i->Pin.FpLdFPSCR.src);
   2539       return;
   2540    case Pin_FpCmp:
   2541       addHRegUse(u, HRmWrite, i->Pin.FpCmp.dst);
   2542       addHRegUse(u, HRmRead,  i->Pin.FpCmp.srcL);
   2543       addHRegUse(u, HRmRead,  i->Pin.FpCmp.srcR);
   2544       return;
   2545 
   2546    case Pin_RdWrLR:
   2547       addHRegUse(u, (i->Pin.RdWrLR.wrLR ? HRmRead : HRmWrite),
   2548                  i->Pin.RdWrLR.gpr);
   2549       return;
   2550 
   2551    case Pin_AvLdSt:
   2552       addHRegUse(u, (i->Pin.AvLdSt.isLoad ? HRmWrite : HRmRead),
   2553                  i->Pin.AvLdSt.reg);
   2554       if (i->Pin.AvLdSt.addr->tag == Pam_IR)
   2555          addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64));
   2556       addRegUsage_PPCAMode(u, i->Pin.AvLdSt.addr);
   2557       return;
   2558    case Pin_AvUnary:
   2559       addHRegUse(u, HRmWrite, i->Pin.AvUnary.dst);
   2560       addHRegUse(u, HRmRead,  i->Pin.AvUnary.src);
   2561       return;
   2562    case Pin_AvBinary:
   2563       if (i->Pin.AvBinary.op == Pav_XOR
   2564           && sameHReg(i->Pin.AvBinary.dst, i->Pin.AvBinary.srcL)
   2565           && sameHReg(i->Pin.AvBinary.dst, i->Pin.AvBinary.srcR)) {
   2566          /* reg-alloc needs to understand 'xor r,r,r' as a write of r */
   2567          /* (as opposed to a rite of passage :-) */
   2568          addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
   2569       } else {
   2570          addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
   2571          addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcL);
   2572          addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcR);
   2573       }
   2574       return;
   2575    case Pin_AvBinaryInt:
   2576       addHRegUse(u, HRmWrite, i->Pin.AvBinaryInt.dst);
   2577       addHRegUse(u, HRmRead,  i->Pin.AvBinaryInt.src);
   2578       return;
   2579    case Pin_AvBin8x16:
   2580       addHRegUse(u, HRmWrite, i->Pin.AvBin8x16.dst);
   2581       addHRegUse(u, HRmRead,  i->Pin.AvBin8x16.srcL);
   2582       addHRegUse(u, HRmRead,  i->Pin.AvBin8x16.srcR);
   2583       return;
   2584    case Pin_AvBin16x8:
   2585       addHRegUse(u, HRmWrite, i->Pin.AvBin16x8.dst);
   2586       addHRegUse(u, HRmRead,  i->Pin.AvBin16x8.srcL);
   2587       addHRegUse(u, HRmRead,  i->Pin.AvBin16x8.srcR);
   2588       return;
   2589    case Pin_AvBin32x4:
   2590       addHRegUse(u, HRmWrite, i->Pin.AvBin32x4.dst);
   2591       addHRegUse(u, HRmRead,  i->Pin.AvBin32x4.srcL);
   2592       addHRegUse(u, HRmRead,  i->Pin.AvBin32x4.srcR);
   2593       return;
   2594    case Pin_AvBin64x2:
   2595       addHRegUse(u, HRmWrite, i->Pin.AvBin64x2.dst);
   2596       addHRegUse(u, HRmRead,  i->Pin.AvBin64x2.srcL);
   2597       addHRegUse(u, HRmRead,  i->Pin.AvBin64x2.srcR);
   2598       return;
   2599    case Pin_AvBin32Fx4:
   2600       addHRegUse(u, HRmWrite, i->Pin.AvBin32Fx4.dst);
   2601       addHRegUse(u, HRmRead,  i->Pin.AvBin32Fx4.srcL);
   2602       addHRegUse(u, HRmRead,  i->Pin.AvBin32Fx4.srcR);
   2603       if (i->Pin.AvBin32Fx4.op == Pavfp_MULF)
   2604          addHRegUse(u, HRmWrite, hregPPC_VR29(mode64));
   2605       return;
   2606    case Pin_AvUn32Fx4:
   2607       addHRegUse(u, HRmWrite, i->Pin.AvUn32Fx4.dst);
   2608       addHRegUse(u, HRmRead,  i->Pin.AvUn32Fx4.src);
   2609       return;
   2610    case Pin_AvPerm:
   2611       addHRegUse(u, HRmWrite, i->Pin.AvPerm.dst);
   2612       addHRegUse(u, HRmRead,  i->Pin.AvPerm.srcL);
   2613       addHRegUse(u, HRmRead,  i->Pin.AvPerm.srcR);
   2614       addHRegUse(u, HRmRead,  i->Pin.AvPerm.ctl);
   2615       return;
   2616    case Pin_AvSel:
   2617       addHRegUse(u, HRmWrite, i->Pin.AvSel.dst);
   2618       addHRegUse(u, HRmRead,  i->Pin.AvSel.ctl);
   2619       addHRegUse(u, HRmRead,  i->Pin.AvSel.srcL);
   2620       addHRegUse(u, HRmRead,  i->Pin.AvSel.srcR);
   2621       return;
   2622    case Pin_AvSh:
   2623       addHRegUse(u, HRmWrite, i->Pin.AvSh.dst);
   2624       if (i->Pin.AvSh.addr->tag == Pam_IR)
   2625          addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64));
   2626       addRegUsage_PPCAMode(u, i->Pin.AvSh.addr);
   2627       return;
   2628    case Pin_AvShlDbl:
   2629       addHRegUse(u, HRmWrite, i->Pin.AvShlDbl.dst);
   2630       addHRegUse(u, HRmRead,  i->Pin.AvShlDbl.srcL);
   2631       addHRegUse(u, HRmRead,  i->Pin.AvShlDbl.srcR);
   2632       return;
   2633    case Pin_AvSplat:
   2634       addHRegUse(u, HRmWrite, i->Pin.AvSplat.dst);
   2635       addRegUsage_PPCVI5s(u,  i->Pin.AvSplat.src);
   2636       return;
   2637    case Pin_AvCMov:
   2638       addHRegUse(u, HRmModify, i->Pin.AvCMov.dst);
   2639       addHRegUse(u, HRmRead,   i->Pin.AvCMov.src);
   2640       return;
   2641    case Pin_AvLdVSCR:
   2642       addHRegUse(u, HRmRead, i->Pin.AvLdVSCR.src);
   2643       return;
   2644    case Pin_AvCipherV128Unary:
   2645       addHRegUse(u, HRmWrite, i->Pin.AvCipherV128Unary.dst);
   2646       addHRegUse(u, HRmRead,  i->Pin.AvCipherV128Unary.src);
   2647       return;
   2648    case Pin_AvCipherV128Binary:
   2649       addHRegUse(u, HRmWrite, i->Pin.AvCipherV128Binary.dst);
   2650       addHRegUse(u, HRmRead,  i->Pin.AvCipherV128Binary.srcL);
   2651       addHRegUse(u, HRmRead,  i->Pin.AvCipherV128Binary.srcR);
   2652       return;
   2653    case Pin_AvHashV128Binary:
   2654       addHRegUse(u, HRmWrite, i->Pin.AvHashV128Binary.dst);
   2655       addHRegUse(u, HRmRead,  i->Pin.AvHashV128Binary.src);
   2656       addRegUsage_PPCRI(u,    i->Pin.AvHashV128Binary.s_field);
   2657       return;
   2658    case Pin_AvBCDV128Binary:
   2659       addHRegUse(u, HRmWrite, i->Pin.AvBCDV128Binary.dst);
   2660       addHRegUse(u, HRmRead,  i->Pin.AvBCDV128Binary.src1);
   2661       addHRegUse(u, HRmRead,  i->Pin.AvBCDV128Binary.src2);
   2662       return;
   2663    case Pin_Dfp64Unary:
   2664       addHRegUse(u, HRmWrite, i->Pin.Dfp64Unary.dst);
   2665       addHRegUse(u, HRmRead, i->Pin.Dfp64Unary.src);
   2666       return;
   2667    case Pin_Dfp64Binary:
   2668       addHRegUse(u, HRmWrite, i->Pin.Dfp64Binary.dst);
   2669       addHRegUse(u, HRmRead, i->Pin.Dfp64Binary.srcL);
   2670       addHRegUse(u, HRmRead, i->Pin.Dfp64Binary.srcR);
   2671       return;
   2672    case Pin_DfpShift:
   2673       addRegUsage_PPCRI(u,    i->Pin.DfpShift.shift);
   2674       addHRegUse(u, HRmWrite, i->Pin.DfpShift.src);
   2675       addHRegUse(u, HRmWrite, i->Pin.DfpShift.dst);
   2676       return;
   2677    case Pin_Dfp128Unary:
   2678       addHRegUse(u, HRmWrite, i->Pin.Dfp128Unary.dst_hi);
   2679       addHRegUse(u, HRmWrite, i->Pin.Dfp128Unary.dst_lo);
   2680       addHRegUse(u, HRmRead,  i->Pin.Dfp128Unary.src_hi);
   2681       addHRegUse(u, HRmRead,  i->Pin.Dfp128Unary.src_lo);
   2682       return;
   2683    case Pin_Dfp128Binary:
   2684       addHRegUse(u, HRmWrite, i->Pin.Dfp128Binary.dst_hi);
   2685       addHRegUse(u, HRmWrite, i->Pin.Dfp128Binary.dst_lo);
   2686       addHRegUse(u, HRmRead, i->Pin.Dfp128Binary.srcR_hi);
   2687       addHRegUse(u, HRmRead, i->Pin.Dfp128Binary.srcR_lo);
   2688       return;
   2689    case Pin_DfpRound:
   2690       addHRegUse(u, HRmWrite, i->Pin.DfpRound.dst);
   2691       addHRegUse(u, HRmRead,  i->Pin.DfpRound.src);
   2692       return;
   2693    case Pin_DfpRound128:
   2694       addHRegUse(u, HRmWrite, i->Pin.DfpRound128.dst_hi);
   2695       addHRegUse(u, HRmWrite, i->Pin.DfpRound128.dst_lo);
   2696       addHRegUse(u, HRmRead,  i->Pin.DfpRound128.src_hi);
   2697       addHRegUse(u, HRmRead,  i->Pin.DfpRound128.src_lo);
   2698       return;
   2699    case Pin_DfpQuantize:
   2700       addRegUsage_PPCRI(u,  i->Pin.DfpQuantize.rmc);
   2701       addHRegUse(u, HRmWrite, i->Pin.DfpQuantize.dst);
   2702       addHRegUse(u, HRmRead,  i->Pin.DfpQuantize.srcL);
   2703       addHRegUse(u, HRmRead,  i->Pin.DfpQuantize.srcR);
   2704       return;
   2705    case Pin_DfpQuantize128:
   2706       addHRegUse(u, HRmWrite, i->Pin.DfpQuantize128.dst_hi);
   2707       addHRegUse(u, HRmWrite, i->Pin.DfpQuantize128.dst_lo);
   2708       addHRegUse(u, HRmRead,  i->Pin.DfpQuantize128.src_hi);
   2709       addHRegUse(u, HRmRead,  i->Pin.DfpQuantize128.src_lo);
   2710       return;
   2711    case Pin_DfpShift128:
   2712       addRegUsage_PPCRI(u,    i->Pin.DfpShift128.shift);
   2713       addHRegUse(u, HRmWrite, i->Pin.DfpShift128.src_hi);
   2714       addHRegUse(u, HRmWrite, i->Pin.DfpShift128.src_lo);
   2715       addHRegUse(u, HRmWrite, i->Pin.DfpShift128.dst_hi);
   2716       addHRegUse(u, HRmWrite, i->Pin.DfpShift128.dst_lo);
   2717       return;
   2718    case Pin_DfpD128toD64:
   2719       addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.src_hi);
   2720       addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.src_lo);
   2721       addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.dst);
   2722       return;
   2723    case Pin_DfpI64StoD128:
   2724       addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.src);
   2725       addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.dst_hi);
   2726       addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.dst_lo);
   2727       return;
   2728    case Pin_ExtractExpD128:
   2729       addHRegUse(u, HRmWrite, i->Pin.ExtractExpD128.dst);
   2730       addHRegUse(u, HRmRead,  i->Pin.ExtractExpD128.src_hi);
   2731       addHRegUse(u, HRmRead,  i->Pin.ExtractExpD128.src_lo);
   2732       return;
   2733    case Pin_InsertExpD128:
   2734       addHRegUse(u, HRmWrite, i->Pin.InsertExpD128.dst_hi);
   2735       addHRegUse(u, HRmWrite, i->Pin.InsertExpD128.dst_lo);
   2736       addHRegUse(u, HRmRead,  i->Pin.InsertExpD128.srcL);
   2737       addHRegUse(u, HRmRead,  i->Pin.InsertExpD128.srcR_hi);
   2738       addHRegUse(u, HRmRead,  i->Pin.InsertExpD128.srcR_lo);
   2739       return;
   2740    case Pin_Dfp64Cmp:
   2741       addHRegUse(u, HRmWrite, i->Pin.Dfp64Cmp.dst);
   2742       addHRegUse(u, HRmRead,  i->Pin.Dfp64Cmp.srcL);
   2743       addHRegUse(u, HRmRead,  i->Pin.Dfp64Cmp.srcR);
   2744       return;
   2745    case Pin_Dfp128Cmp:
   2746       addHRegUse(u, HRmWrite, i->Pin.Dfp128Cmp.dst);
   2747       addHRegUse(u, HRmRead,  i->Pin.Dfp128Cmp.srcL_hi);
   2748       addHRegUse(u, HRmRead,  i->Pin.Dfp128Cmp.srcL_lo);
   2749       addHRegUse(u, HRmRead,  i->Pin.Dfp128Cmp.srcR_hi);
   2750       addHRegUse(u, HRmRead,  i->Pin.Dfp128Cmp.srcR_lo);
   2751       return;
   2752    case Pin_EvCheck:
   2753       /* We expect both amodes only to mention the GSP (r31), so this
   2754          is in fact pointless, since GSP isn't allocatable, but
   2755          anyway.. */
   2756       addRegUsage_PPCAMode(u, i->Pin.EvCheck.amCounter);
   2757       addRegUsage_PPCAMode(u, i->Pin.EvCheck.amFailAddr);
   2758       addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); /* also unavail to RA */
   2759       return;
   2760    case Pin_ProfInc:
   2761       addHRegUse(u, HRmWrite, hregPPC_GPR29(mode64));
   2762       addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64));
   2763       return;
   2764    default:
   2765       ppPPCInstr(i, mode64);
   2766       vpanic("getRegUsage_PPCInstr");
   2767    }
   2768 }
   2769 
   2770 /* local helper */
   2771 static void mapReg( HRegRemap* m, HReg* r )
   2772 {
   2773    *r = lookupHRegRemap(m, *r);
   2774 }
   2775 
   2776 void mapRegs_PPCInstr ( HRegRemap* m, PPCInstr* i, Bool mode64 )
   2777 {
   2778    switch (i->tag) {
   2779    case Pin_LI:
   2780       mapReg(m, &i->Pin.LI.dst);
   2781       return;
   2782    case Pin_Alu:
   2783       mapReg(m, &i->Pin.Alu.dst);
   2784       mapReg(m, &i->Pin.Alu.srcL);
   2785       mapRegs_PPCRH(m, i->Pin.Alu.srcR);
   2786       return;
   2787    case Pin_Shft:
   2788       mapReg(m, &i->Pin.Shft.dst);
   2789       mapReg(m, &i->Pin.Shft.srcL);
   2790       mapRegs_PPCRH(m, i->Pin.Shft.srcR);
   2791       return;
   2792    case Pin_AddSubC:
   2793       mapReg(m, &i->Pin.AddSubC.dst);
   2794       mapReg(m, &i->Pin.AddSubC.srcL);
   2795       mapReg(m, &i->Pin.AddSubC.srcR);
   2796       return;
   2797    case Pin_Cmp:
   2798       mapReg(m, &i->Pin.Cmp.srcL);
   2799       mapRegs_PPCRH(m, i->Pin.Cmp.srcR);
   2800       return;
   2801    case Pin_Unary:
   2802       mapReg(m, &i->Pin.Unary.dst);
   2803       mapReg(m, &i->Pin.Unary.src);
   2804       return;
   2805    case Pin_MulL:
   2806       mapReg(m, &i->Pin.MulL.dst);
   2807       mapReg(m, &i->Pin.MulL.srcL);
   2808       mapReg(m, &i->Pin.MulL.srcR);
   2809       return;
   2810    case Pin_Div:
   2811       mapReg(m, &i->Pin.Div.dst);
   2812       mapReg(m, &i->Pin.Div.srcL);
   2813       mapReg(m, &i->Pin.Div.srcR);
   2814       return;
   2815    case Pin_Call:
   2816       return;
   2817    case Pin_XDirect:
   2818       mapRegs_PPCAMode(m, i->Pin.XDirect.amCIA);
   2819       return;
   2820    case Pin_XIndir:
   2821       mapReg(m, &i->Pin.XIndir.dstGA);
   2822       mapRegs_PPCAMode(m, i->Pin.XIndir.amCIA);
   2823       return;
   2824    case Pin_XAssisted:
   2825       mapReg(m, &i->Pin.XAssisted.dstGA);
   2826       mapRegs_PPCAMode(m, i->Pin.XAssisted.amCIA);
   2827       return;
   2828    case Pin_CMov:
   2829       mapRegs_PPCRI(m, i->Pin.CMov.src);
   2830       mapReg(m, &i->Pin.CMov.dst);
   2831       return;
   2832    case Pin_Load:
   2833       mapRegs_PPCAMode(m, i->Pin.Load.src);
   2834       mapReg(m, &i->Pin.Load.dst);
   2835       return;
   2836    case Pin_LoadL:
   2837       mapReg(m, &i->Pin.LoadL.src);
   2838       mapReg(m, &i->Pin.LoadL.dst);
   2839       return;
   2840    case Pin_Store:
   2841       mapReg(m, &i->Pin.Store.src);
   2842       mapRegs_PPCAMode(m, i->Pin.Store.dst);
   2843       return;
   2844    case Pin_StoreC:
   2845       mapReg(m, &i->Pin.StoreC.src);
   2846       mapReg(m, &i->Pin.StoreC.dst);
   2847       return;
   2848    case Pin_Set:
   2849       mapReg(m, &i->Pin.Set.dst);
   2850       return;
   2851    case Pin_MfCR:
   2852       mapReg(m, &i->Pin.MfCR.dst);
   2853       return;
   2854    case Pin_MFence:
   2855       return;
   2856    case Pin_FpUnary:
   2857       mapReg(m, &i->Pin.FpUnary.dst);
   2858       mapReg(m, &i->Pin.FpUnary.src);
   2859       return;
   2860    case Pin_FpBinary:
   2861       mapReg(m, &i->Pin.FpBinary.dst);
   2862       mapReg(m, &i->Pin.FpBinary.srcL);
   2863       mapReg(m, &i->Pin.FpBinary.srcR);
   2864       return;
   2865    case Pin_Fp128Unary:
   2866       mapReg(m, &i->Pin.Fp128Unary.dst);
   2867       mapReg(m, &i->Pin.Fp128Unary.src);
   2868       return;
   2869    case Pin_Fp128Binary:
   2870       mapReg(m, &i->Pin.Fp128Binary.dst);
   2871       mapReg(m, &i->Pin.Fp128Binary.srcL);
   2872       mapReg(m, &i->Pin.Fp128Binary.srcR);
   2873       return;
   2874    case Pin_Fp128Trinary:
   2875       mapReg(m, &i->Pin.Fp128Trinary.dst);
   2876       mapReg(m, &i->Pin.Fp128Trinary.srcL);
   2877       mapReg(m, &i->Pin.Fp128Trinary.srcR);
   2878       return;
   2879    case Pin_FpMulAcc:
   2880       mapReg(m, &i->Pin.FpMulAcc.dst);
   2881       mapReg(m, &i->Pin.FpMulAcc.srcML);
   2882       mapReg(m, &i->Pin.FpMulAcc.srcMR);
   2883       mapReg(m, &i->Pin.FpMulAcc.srcAcc);
   2884       return;
   2885    case Pin_FpLdSt:
   2886       mapReg(m, &i->Pin.FpLdSt.reg);
   2887       mapRegs_PPCAMode(m, i->Pin.FpLdSt.addr);
   2888       return;
   2889    case Pin_FpSTFIW:
   2890       mapReg(m, &i->Pin.FpSTFIW.addr);
   2891       mapReg(m, &i->Pin.FpSTFIW.data);
   2892       return;
   2893    case Pin_FpRSP:
   2894       mapReg(m, &i->Pin.FpRSP.dst);
   2895       mapReg(m, &i->Pin.FpRSP.src);
   2896       return;
   2897    case Pin_FpCftI:
   2898       mapReg(m, &i->Pin.FpCftI.dst);
   2899       mapReg(m, &i->Pin.FpCftI.src);
   2900       return;
   2901    case Pin_FpCMov:
   2902       mapReg(m, &i->Pin.FpCMov.dst);
   2903       mapReg(m, &i->Pin.FpCMov.src);
   2904       return;
   2905    case Pin_FpLdFPSCR:
   2906       mapReg(m, &i->Pin.FpLdFPSCR.src);
   2907       return;
   2908    case Pin_FpCmp:
   2909       mapReg(m, &i->Pin.FpCmp.dst);
   2910       mapReg(m, &i->Pin.FpCmp.srcL);
   2911       mapReg(m, &i->Pin.FpCmp.srcR);
   2912       return;
   2913    case Pin_RdWrLR:
   2914       mapReg(m, &i->Pin.RdWrLR.gpr);
   2915       return;
   2916    case Pin_AvLdSt:
   2917       mapReg(m, &i->Pin.AvLdSt.reg);
   2918       mapRegs_PPCAMode(m, i->Pin.AvLdSt.addr);
   2919       return;
   2920    case Pin_AvUnary:
   2921       mapReg(m, &i->Pin.AvUnary.dst);
   2922       mapReg(m, &i->Pin.AvUnary.src);
   2923       return;
   2924    case Pin_AvBinary:
   2925       mapReg(m, &i->Pin.AvBinary.dst);
   2926       mapReg(m, &i->Pin.AvBinary.srcL);
   2927       mapReg(m, &i->Pin.AvBinary.srcR);
   2928       return;
   2929    case Pin_AvBinaryInt:
   2930       mapReg(m, &i->Pin.AvBinaryInt.dst);
   2931       mapReg(m, &i->Pin.AvBinaryInt.src);
   2932       return;
   2933    case Pin_AvBin8x16:
   2934       mapReg(m, &i->Pin.AvBin8x16.dst);
   2935       mapReg(m, &i->Pin.AvBin8x16.srcL);
   2936       mapReg(m, &i->Pin.AvBin8x16.srcR);
   2937       return;
   2938    case Pin_AvBin16x8:
   2939       mapReg(m, &i->Pin.AvBin16x8.dst);
   2940       mapReg(m, &i->Pin.AvBin16x8.srcL);
   2941       mapReg(m, &i->Pin.AvBin16x8.srcR);
   2942       return;
   2943    case Pin_AvBin32x4:
   2944       mapReg(m, &i->Pin.AvBin32x4.dst);
   2945       mapReg(m, &i->Pin.AvBin32x4.srcL);
   2946       mapReg(m, &i->Pin.AvBin32x4.srcR);
   2947       return;
   2948    case Pin_AvBin64x2:
   2949       mapReg(m, &i->Pin.AvBin64x2.dst);
   2950       mapReg(m, &i->Pin.AvBin64x2.srcL);
   2951       mapReg(m, &i->Pin.AvBin64x2.srcR);
   2952       return;
   2953    case Pin_AvBin32Fx4:
   2954       mapReg(m, &i->Pin.AvBin32Fx4.dst);
   2955       mapReg(m, &i->Pin.AvBin32Fx4.srcL);
   2956       mapReg(m, &i->Pin.AvBin32Fx4.srcR);
   2957       return;
   2958    case Pin_AvUn32Fx4:
   2959       mapReg(m, &i->Pin.AvUn32Fx4.dst);
   2960       mapReg(m, &i->Pin.AvUn32Fx4.src);
   2961       return;
   2962    case Pin_AvPerm:
   2963       mapReg(m, &i->Pin.AvPerm.dst);
   2964       mapReg(m, &i->Pin.AvPerm.srcL);
   2965       mapReg(m, &i->Pin.AvPerm.srcR);
   2966       mapReg(m, &i->Pin.AvPerm.ctl);
   2967       return;
   2968    case Pin_AvSel:
   2969       mapReg(m, &i->Pin.AvSel.dst);
   2970       mapReg(m, &i->Pin.AvSel.srcL);
   2971       mapReg(m, &i->Pin.AvSel.srcR);
   2972       mapReg(m, &i->Pin.AvSel.ctl);
   2973       return;
   2974    case Pin_AvSh:
   2975       mapReg(m, &i->Pin.AvSh.dst);
   2976       mapRegs_PPCAMode(m, i->Pin.AvSh.addr);
   2977       return;
   2978    case Pin_AvShlDbl:
   2979       mapReg(m, &i->Pin.AvShlDbl.dst);
   2980       mapReg(m, &i->Pin.AvShlDbl.srcL);
   2981       mapReg(m, &i->Pin.AvShlDbl.srcR);
   2982       return;
   2983    case Pin_AvSplat:
   2984       mapReg(m, &i->Pin.AvSplat.dst);
   2985       mapRegs_PPCVI5s(m, i->Pin.AvSplat.src);
   2986       return;
   2987    case Pin_AvCMov:
   2988      mapReg(m, &i->Pin.AvCMov.dst);
   2989      mapReg(m, &i->Pin.AvCMov.src);
   2990      return;
   2991    case Pin_AvLdVSCR:
   2992       mapReg(m, &i->Pin.AvLdVSCR.src);
   2993       return;
   2994    case Pin_AvCipherV128Unary:
   2995       mapReg(m, &i->Pin.AvCipherV128Unary.dst);
   2996       mapReg(m, &i->Pin.AvCipherV128Unary.src);
   2997       return;
   2998    case Pin_AvCipherV128Binary:
   2999       mapReg(m, &i->Pin.AvCipherV128Binary.dst);
   3000       mapReg(m, &i->Pin.AvCipherV128Binary.srcL);
   3001       mapReg(m, &i->Pin.AvCipherV128Binary.srcR);
   3002       return;
   3003    case Pin_AvHashV128Binary:
   3004       mapRegs_PPCRI(m, i->Pin.AvHashV128Binary.s_field);
   3005       mapReg(m, &i->Pin.AvHashV128Binary.dst);
   3006       mapReg(m, &i->Pin.AvHashV128Binary.src);
   3007       return;
   3008    case Pin_AvBCDV128Binary:
   3009       mapReg(m, &i->Pin.AvBCDV128Binary.dst);
   3010       mapReg(m, &i->Pin.AvBCDV128Binary.src1);
   3011       mapReg(m, &i->Pin.AvBCDV128Binary.src2);
   3012       return;
   3013    case Pin_Dfp64Unary:
   3014       mapReg(m, &i->Pin.Dfp64Unary.dst);
   3015       mapReg(m, &i->Pin.Dfp64Unary.src);
   3016       return;
   3017    case Pin_Dfp64Binary:
   3018       mapReg(m, &i->Pin.Dfp64Binary.dst);
   3019       mapReg(m, &i->Pin.Dfp64Binary.srcL);
   3020       mapReg(m, &i->Pin.Dfp64Binary.srcR);
   3021       return;
   3022    case Pin_DfpShift:
   3023       mapRegs_PPCRI(m, i->Pin.DfpShift.shift);
   3024       mapReg(m, &i->Pin.DfpShift.src);
   3025       mapReg(m, &i->Pin.DfpShift.dst);
   3026       return;
   3027    case Pin_Dfp128Unary:
   3028       mapReg(m, &i->Pin.Dfp128Unary.dst_hi);
   3029       mapReg(m, &i->Pin.Dfp128Unary.dst_lo);
   3030       mapReg(m, &i->Pin.Dfp128Unary.src_hi);
   3031       mapReg(m, &i->Pin.Dfp128Unary.src_lo);
   3032      return;
   3033    case Pin_Dfp128Binary:
   3034       mapReg(m, &i->Pin.Dfp128Binary.dst_hi);
   3035       mapReg(m, &i->Pin.Dfp128Binary.dst_lo);
   3036       mapReg(m, &i->Pin.Dfp128Binary.srcR_hi);
   3037       mapReg(m, &i->Pin.Dfp128Binary.srcR_lo);
   3038       return;
   3039    case Pin_DfpShift128:
   3040       mapRegs_PPCRI(m, i->Pin.DfpShift128.shift);
   3041       mapReg(m, &i->Pin.DfpShift128.src_hi);
   3042       mapReg(m, &i->Pin.DfpShift128.src_lo);
   3043       mapReg(m, &i->Pin.DfpShift128.dst_hi);
   3044       mapReg(m, &i->Pin.DfpShift128.dst_lo);
   3045       return;
   3046    case Pin_DfpRound:
   3047       mapReg(m, &i->Pin.DfpRound.dst);
   3048       mapReg(m, &i->Pin.DfpRound.src);
   3049       return;
   3050    case Pin_DfpRound128:
   3051       mapReg(m, &i->Pin.DfpRound128.dst_hi);
   3052       mapReg(m, &i->Pin.DfpRound128.dst_lo);
   3053       mapReg(m, &i->Pin.DfpRound128.src_hi);
   3054       mapReg(m, &i->Pin.DfpRound128.src_lo);
   3055       return;
   3056    case Pin_DfpQuantize:
   3057       mapRegs_PPCRI(m, i->Pin.DfpQuantize.rmc);
   3058       mapReg(m, &i->Pin.DfpQuantize.dst);
   3059       mapReg(m, &i->Pin.DfpQuantize.srcL);
   3060       mapReg(m, &i->Pin.DfpQuantize.srcR);
   3061       return;
   3062    case Pin_DfpQuantize128:
   3063       mapRegs_PPCRI(m, i->Pin.DfpQuantize128.rmc);
   3064       mapReg(m, &i->Pin.DfpQuantize128.dst_hi);
   3065       mapReg(m, &i->Pin.DfpQuantize128.dst_lo);
   3066       mapReg(m, &i->Pin.DfpQuantize128.src_hi);
   3067       mapReg(m, &i->Pin.DfpQuantize128.src_lo);
   3068       return;
   3069    case Pin_DfpD128toD64:
   3070       mapReg(m, &i->Pin.DfpD128toD64.src_hi);
   3071       mapReg(m, &i->Pin.DfpD128toD64.src_lo);
   3072       mapReg(m, &i->Pin.DfpD128toD64.dst);
   3073       return;
   3074    case Pin_DfpI64StoD128:
   3075       mapReg(m, &i->Pin.DfpI64StoD128.src);
   3076       mapReg(m, &i->Pin.DfpI64StoD128.dst_hi);
   3077       mapReg(m, &i->Pin.DfpI64StoD128.dst_lo);
   3078       return;
   3079    case Pin_ExtractExpD128:
   3080       mapReg(m, &i->Pin.ExtractExpD128.dst);
   3081       mapReg(m, &i->Pin.ExtractExpD128.src_hi);
   3082       mapReg(m, &i->Pin.ExtractExpD128.src_lo);
   3083       return;
   3084    case Pin_InsertExpD128:
   3085       mapReg(m, &i->Pin.InsertExpD128.dst_hi);
   3086       mapReg(m, &i->Pin.InsertExpD128.dst_lo);
   3087       mapReg(m, &i->Pin.InsertExpD128.srcL);
   3088       mapReg(m, &i->Pin.InsertExpD128.srcR_hi);
   3089       mapReg(m, &i->Pin.InsertExpD128.srcR_lo);
   3090       return;
   3091    case Pin_Dfp64Cmp:
   3092       mapReg(m, &i->Pin.Dfp64Cmp.dst);
   3093       mapReg(m, &i->Pin.Dfp64Cmp.srcL);
   3094       mapReg(m, &i->Pin.Dfp64Cmp.srcR);
   3095       return;
   3096    case Pin_Dfp128Cmp:
   3097       mapReg(m, &i->Pin.Dfp128Cmp.dst);
   3098       mapReg(m, &i->Pin.Dfp128Cmp.srcL_hi);
   3099       mapReg(m, &i->Pin.Dfp128Cmp.srcL_lo);
   3100       mapReg(m, &i->Pin.Dfp128Cmp.srcR_hi);
   3101       mapReg(m, &i->Pin.Dfp128Cmp.srcR_lo);
   3102       return;
   3103    case Pin_EvCheck:
   3104       /* We expect both amodes only to mention the GSP (r31), so this
   3105          is in fact pointless, since GSP isn't allocatable, but
   3106          anyway.. */
   3107       mapRegs_PPCAMode(m, i->Pin.EvCheck.amCounter);
   3108       mapRegs_PPCAMode(m, i->Pin.EvCheck.amFailAddr);
   3109       return;
   3110    case Pin_ProfInc:
   3111       /* hardwires r29 and r30 -- nothing to modify. */
   3112       return;
   3113    default:
   3114       ppPPCInstr(i, mode64);
   3115       vpanic("mapRegs_PPCInstr");
   3116    }
   3117 }
   3118 
   3119 /* Figure out if i represents a reg-reg move, and if so assign the
   3120    source and destination to *src and *dst.  If in doubt say No.  Used
   3121    by the register allocator to do move coalescing.
   3122 */
   3123 Bool isMove_PPCInstr ( const PPCInstr* i, HReg* src, HReg* dst )
   3124 {
   3125    /* Moves between integer regs */
   3126    if (i->tag == Pin_Alu) {
   3127       // or Rd,Rs,Rs == mr Rd,Rs
   3128       if (i->Pin.Alu.op != Palu_OR)
   3129          return False;
   3130       if (i->Pin.Alu.srcR->tag != Prh_Reg)
   3131          return False;
   3132       if (! sameHReg(i->Pin.Alu.srcR->Prh.Reg.reg, i->Pin.Alu.srcL))
   3133          return False;
   3134       *src = i->Pin.Alu.srcL;
   3135       *dst = i->Pin.Alu.dst;
   3136       return True;
   3137    }
   3138    /* Moves between FP regs */
   3139    if (i->tag == Pin_FpUnary) {
   3140       if (i->Pin.FpUnary.op != Pfp_MOV)
   3141          return False;
   3142       *src = i->Pin.FpUnary.src;
   3143       *dst = i->Pin.FpUnary.dst;
   3144       return True;
   3145    }
   3146    return False;
   3147 }
   3148 
   3149 
   3150 /* Generate ppc spill/reload instructions under the direction of the
   3151    register allocator.  Note it's critical these don't write the
   3152    condition codes. */
   3153 
   3154 void genSpill_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
   3155                     HReg rreg, Int offsetB, Bool mode64 )
   3156 {
   3157    PPCAMode* am;
   3158    vassert(!hregIsVirtual(rreg));
   3159    *i1 = *i2 = NULL;
   3160    am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) );
   3161    switch (hregClass(rreg)) {
   3162       case HRcInt64:
   3163          vassert(mode64);
   3164          *i1 = PPCInstr_Store( 8, am, rreg, mode64 );
   3165          return;
   3166       case HRcInt32:
   3167          vassert(!mode64);
   3168          *i1 = PPCInstr_Store( 4, am, rreg, mode64 );
   3169          return;
   3170       case HRcFlt64:
   3171          *i1 = PPCInstr_FpLdSt ( False/*store*/, 8, rreg, am );
   3172          return;
   3173       case HRcVec128:
   3174          // XXX: GPR30 used as spill register to kludge AltiVec
   3175          // AMode_IR
   3176          *i1 = PPCInstr_AvLdSt ( False/*store*/, 16, rreg, am );
   3177          return;
   3178       default:
   3179          ppHRegClass(hregClass(rreg));
   3180          vpanic("genSpill_PPC: unimplemented regclass");
   3181    }
   3182 }
   3183 
   3184 void genReload_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
   3185                      HReg rreg, Int offsetB, Bool mode64 )
   3186 {
   3187    PPCAMode* am;
   3188    vassert(!hregIsVirtual(rreg));
   3189    *i1 = *i2 = NULL;
   3190    am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) );
   3191    switch (hregClass(rreg)) {
   3192       case HRcInt64:
   3193          vassert(mode64);
   3194          *i1 = PPCInstr_Load( 8, rreg, am, mode64 );
   3195          return;
   3196       case HRcInt32:
   3197          vassert(!mode64);
   3198          *i1 = PPCInstr_Load( 4, rreg, am, mode64 );
   3199          return;
   3200       case HRcFlt64:
   3201          *i1 = PPCInstr_FpLdSt ( True/*load*/, 8, rreg, am );
   3202          return;
   3203       case HRcVec128:
   3204          // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR
   3205          *i1 = PPCInstr_AvLdSt ( True/*load*/, 16, rreg, am );
   3206          return;
   3207       default:
   3208          ppHRegClass(hregClass(rreg));
   3209          vpanic("genReload_PPC: unimplemented regclass");
   3210    }
   3211 }
   3212 
   3213 
   3214 /* --------- The ppc assembler (bleh.) --------- */
   3215 
   3216 inline static UInt iregEnc ( HReg r, Bool mode64 )
   3217 {
   3218    UInt n;
   3219    vassert(hregClass(r) == (mode64 ? HRcInt64 : HRcInt32));
   3220    vassert(!hregIsVirtual(r));
   3221    n = hregEncoding(r);
   3222    vassert(n <= 32);
   3223    return n;
   3224 }
   3225 
   3226 inline static UInt fregEnc ( HReg fr )
   3227 {
   3228    UInt n;
   3229    vassert(hregClass(fr) == HRcFlt64);
   3230    vassert(!hregIsVirtual(fr));
   3231    n = hregEncoding(fr);
   3232    vassert(n <= 32);
   3233    return n;
   3234 }
   3235 
   3236 inline static UInt vregEnc ( HReg v )
   3237 {
   3238    UInt n;
   3239    vassert(hregClass(v) == HRcVec128);
   3240    vassert(!hregIsVirtual(v));
   3241    n = hregEncoding(v);
   3242    vassert(n <= 32);
   3243    return n;
   3244 }
   3245 
   3246 /* Emit an instruction ppc-endianly */
   3247 static UChar* emit32 ( UChar* p, UInt w32, VexEndness endness_host )
   3248 {
   3249   if (endness_host == VexEndnessBE) {
   3250     *p++ = toUChar((w32 >> 24) & 0x000000FF);
   3251     *p++ = toUChar((w32 >> 16) & 0x000000FF);
   3252     *p++ = toUChar((w32 >>  8) & 0x000000FF);
   3253     *p++ = toUChar((w32)       & 0x000000FF);
   3254   } else {
   3255     *p++ = toUChar((w32)       & 0x000000FF);
   3256     *p++ = toUChar((w32 >>  8) & 0x000000FF);
   3257     *p++ = toUChar((w32 >> 16) & 0x000000FF);
   3258     *p++ = toUChar((w32 >> 24) & 0x000000FF);
   3259   }
   3260    return p;
   3261 }
   3262 
   3263 /* Fetch an instruction ppc-endianly */
   3264 static UInt fetch32 ( UChar* p, VexEndness endness_host )
   3265 {
   3266    UInt w32 = 0;
   3267    if (endness_host == VexEndnessBE) {
   3268       w32 |= ((0xFF & (UInt)p[0]) << 24);
   3269       w32 |= ((0xFF & (UInt)p[1]) << 16);
   3270       w32 |= ((0xFF & (UInt)p[2]) <<  8);
   3271       w32 |= ((0xFF & (UInt)p[3]) <<  0);
   3272   } else {
   3273       w32 |= ((0xFF & (UInt)p[3]) << 24);
   3274       w32 |= ((0xFF & (UInt)p[2]) << 16);
   3275       w32 |= ((0xFF & (UInt)p[1]) <<  8);
   3276       w32 |= ((0xFF & (UInt)p[0]) <<  0);
   3277   }
   3278    return w32;
   3279 }
   3280 
   3281 /* The following mkForm[...] functions refer to ppc instruction forms
   3282    as per PPC32 p576
   3283  */
   3284 
   3285 static UChar* mkFormD ( UChar* p, UInt opc1,
   3286                         UInt r1, UInt r2, UInt imm, VexEndness endness_host )
   3287 {
   3288    UInt theInstr;
   3289    vassert(opc1 < 0x40);
   3290    vassert(r1   < 0x20);
   3291    vassert(r2   < 0x20);
   3292    imm = imm & 0xFFFF;
   3293    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (imm));
   3294    return emit32(p, theInstr, endness_host);
   3295 }
   3296 
   3297 static UChar* mkFormMD ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3298                          UInt imm1, UInt imm2, UInt opc2,
   3299                          VexEndness endness_host )
   3300 {
   3301    UInt theInstr;
   3302    vassert(opc1 < 0x40);
   3303    vassert(r1   < 0x20);
   3304    vassert(r2   < 0x20);
   3305    vassert(imm1 < 0x40);
   3306    vassert(imm2 < 0x40);
   3307    vassert(opc2 < 0x08);
   3308    imm2 = ((imm2 & 0x1F) << 1) | (imm2 >> 5);
   3309    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3310                ((imm1 & 0x1F)<<11) | (imm2<<5) |
   3311                (opc2<<2) | ((imm1 >> 5)<<1));
   3312    return emit32(p, theInstr, endness_host);
   3313 }
   3314 
   3315 static UChar* mkFormX ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3316                         UInt r3, UInt opc2, UInt b0, VexEndness endness_host )
   3317 {
   3318    UInt theInstr;
   3319    vassert(opc1 < 0x40);
   3320    vassert(r1   < 0x20);
   3321    vassert(r2   < 0x20);
   3322    vassert(r3   < 0x20);
   3323    vassert(opc2 < 0x400);
   3324    vassert(b0   < 0x2);
   3325    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3326                (r3<<11) | (opc2<<1) | (b0));
   3327    return emit32(p, theInstr, endness_host);
   3328 }
   3329 
   3330 static UChar* mkFormXO ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3331                          UInt r3, UInt b10, UInt opc2, UInt b0,
   3332                          VexEndness endness_host )
   3333 {
   3334    UInt theInstr;
   3335    vassert(opc1 < 0x40);
   3336    vassert(r1   < 0x20);
   3337    vassert(r2   < 0x20);
   3338    vassert(r3   < 0x20);
   3339    vassert(b10  < 0x2);
   3340    vassert(opc2 < 0x200);
   3341    vassert(b0   < 0x2);
   3342    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3343                (r3<<11) | (b10 << 10) | (opc2<<1) | (b0));
   3344    return emit32(p, theInstr, endness_host);
   3345 }
   3346 
   3347 static UChar* mkFormXL ( UChar* p, UInt opc1, UInt f1, UInt f2,
   3348                          UInt f3, UInt opc2, UInt b0, VexEndness endness_host )
   3349 {
   3350    UInt theInstr;
   3351    vassert(opc1 < 0x40);
   3352    vassert(f1   < 0x20);
   3353    vassert(f2   < 0x20);
   3354    vassert(f3   < 0x20);
   3355    vassert(opc2 < 0x400);
   3356    vassert(b0   < 0x2);
   3357    theInstr = ((opc1<<26) | (f1<<21) | (f2<<16) |
   3358                (f3<<11) | (opc2<<1) | (b0));
   3359    return emit32(p, theInstr, endness_host);
   3360 }
   3361 
   3362 // Note: for split field ops, give mnemonic arg
   3363 static UChar* mkFormXFX ( UChar* p, UInt r1, UInt f2, UInt opc2,
   3364                           VexEndness endness_host )
   3365 {
   3366    UInt theInstr;
   3367    vassert(r1   < 0x20);
   3368    vassert(f2   < 0x20);
   3369    vassert(opc2 < 0x400);
   3370    switch (opc2) {
   3371    case 144:  // mtcrf
   3372       vassert(f2 < 0x100);
   3373       f2 = f2 << 1;
   3374       break;
   3375    case 339:  // mfspr
   3376    case 371:  // mftb
   3377    case 467:  // mtspr
   3378       vassert(f2 < 0x400);
   3379       // re-arrange split field
   3380       f2 = ((f2>>5) & 0x1F) | ((f2 & 0x1F)<<5);
   3381       break;
   3382    default: vpanic("mkFormXFX(ppch)");
   3383    }
   3384    theInstr = ((31<<26) | (r1<<21) | (f2<<11) | (opc2<<1));
   3385    return emit32(p, theInstr, endness_host);
   3386 }
   3387 
   3388 // Only used by mtfsf
   3389 static UChar* mkFormXFL ( UChar* p, UInt FM, UInt freg, UInt dfp_rm,
   3390                           VexEndness endness_host )
   3391 {
   3392    UInt theInstr;
   3393    vassert(FM   < 0x100);
   3394    vassert(freg < 0x20);
   3395    theInstr = ((63<<26) | (FM<<17) | (dfp_rm<<16) | (freg<<11) | (711<<1));
   3396    return emit32(p, theInstr, endness_host);
   3397 }
   3398 
   3399 static UChar* mkFormXS ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3400                          UInt imm, UInt opc2, UInt b0,
   3401                          VexEndness endness_host )
   3402 {
   3403    UInt theInstr;
   3404    vassert(opc1 < 0x40);
   3405    vassert(r1   < 0x20);
   3406    vassert(r2   < 0x20);
   3407    vassert(imm  < 0x40);
   3408    vassert(opc2 < 0x400);
   3409    vassert(b0   < 0x2);
   3410    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3411                ((imm & 0x1F)<<11) | (opc2<<2) | ((imm>>5)<<1) | (b0));
   3412    return emit32(p, theInstr, endness_host);
   3413 }
   3414 
   3415 
   3416 #if 0
   3417 // 'b'
   3418 static UChar* mkFormI ( UChar* p, UInt LI, UInt AA, UInt LK,
   3419                         VexEndness endness_host )
   3420 {
   3421    UInt theInstr;
   3422    vassert(LI  < 0x1000000);
   3423    vassert(AA  < 0x2);
   3424    vassert(LK  < 0x2);
   3425    theInstr = ((18<<26) | (LI<<2) | (AA<<1) | (LK));
   3426    return emit32(p, theInstr, endness_host);
   3427 }
   3428 #endif
   3429 
   3430 // 'bc'
   3431 static UChar* mkFormB ( UChar* p, UInt BO, UInt BI,
   3432                         UInt BD, UInt AA, UInt LK, VexEndness endness_host )
   3433 {
   3434    UInt theInstr;
   3435    vassert(BO  < 0x20);
   3436    vassert(BI  < 0x20);
   3437    vassert(BD  < 0x4000);
   3438    vassert(AA  < 0x2);
   3439    vassert(LK  < 0x2);
   3440    theInstr = ((16<<26) | (BO<<21) | (BI<<16) |
   3441                (BD<<2) | (AA<<1) | (LK));
   3442    return emit32(p, theInstr, endness_host);
   3443 }
   3444 
   3445 // rotates
   3446 static UChar* mkFormM ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3447                         UInt f3, UInt MB, UInt ME, UInt Rc,
   3448                         VexEndness endness_host )
   3449 {
   3450    UInt theInstr;
   3451    vassert(opc1 < 0x40);
   3452    vassert(r1   < 0x20);
   3453    vassert(r2   < 0x20);
   3454    vassert(f3   < 0x20);
   3455    vassert(MB   < 0x20);
   3456    vassert(ME   < 0x20);
   3457    vassert(Rc   < 0x2);
   3458    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3459                (f3<<11) | (MB<<6) | (ME<<1) | (Rc));
   3460    return emit32(p, theInstr, endness_host);
   3461 }
   3462 
   3463 static UChar* mkFormA ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3464                         UInt r3, UInt r4, UInt opc2, UInt b0,
   3465                         VexEndness endness_host )
   3466 {
   3467    UInt theInstr;
   3468    vassert(opc1 < 0x40);
   3469    vassert(r1   < 0x20);
   3470    vassert(r2   < 0x20);
   3471    vassert(r3   < 0x20);
   3472    vassert(r4   < 0x20);
   3473    vassert(opc2 < 0x20);
   3474    vassert(b0   < 0x2 );
   3475    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) |
   3476                (r4<<6) | (opc2<<1) | (b0));
   3477    return emit32(p, theInstr, endness_host);
   3478 }
   3479 
   3480 static UChar* mkFormZ22 ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3481                           UInt constant, UInt opc2, UInt b0,
   3482                           VexEndness endness_host)
   3483 {
   3484    UInt theInstr;
   3485    vassert(opc1     < 0x40);
   3486    vassert(r1       < 0x20);
   3487    vassert(r2       < 0x20);
   3488    vassert(constant < 0x40);   /* 6 bit constant */
   3489    vassert(opc2     < 0x200);  /* 9 bit field */
   3490    vassert(b0       < 0x2);
   3491    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3492                (constant<<10) | (opc2<<1) | (b0));
   3493    return emit32(p, theInstr, endness_host);
   3494 }
   3495 
   3496 static UChar* mkFormZ23 ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3497                           UInt r3, UInt rmc, UInt opc2, UInt b0,
   3498                           VexEndness endness_host)
   3499 {
   3500    UInt theInstr;
   3501    vassert(opc1 < 0x40);
   3502    vassert(r1   < 0x20);
   3503    vassert(r2   < 0x20);
   3504    vassert(r3   < 0x20);
   3505    vassert(rmc  < 0x4);
   3506    vassert(opc2 < 0x100);
   3507    vassert(b0   < 0x2);
   3508    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3509                (r3<<11) | (rmc<<9) | (opc2<<1) | (b0));
   3510    return emit32(p, theInstr, endness_host);
   3511 }
   3512 
   3513 static UChar* doAMode_IR ( UChar* p, UInt opc1, UInt rSD,
   3514                            PPCAMode* am, Bool mode64, VexEndness endness_host )
   3515 {
   3516    UInt rA, idx;
   3517    vassert(am->tag == Pam_IR);
   3518    vassert(am->Pam.IR.index < 0x10000);
   3519 
   3520    rA  = iregEnc(am->Pam.IR.base, mode64);
   3521    idx = am->Pam.IR.index;
   3522 
   3523    if (opc1 == 58 || opc1 == 62) { // ld/std: mode64 only
   3524       vassert(mode64);
   3525       /* stay sane with DS form: lowest 2 bits must be 00.  This
   3526          should be guaranteed to us by iselWordExpr_AMode. */
   3527       vassert(0 == (idx & 3));
   3528    }
   3529    p = mkFormD(p, opc1, rSD, rA, idx, endness_host);
   3530    return p;
   3531 }
   3532 
   3533 static UChar* doAMode_RR ( UChar* p, UInt opc1, UInt opc2,
   3534                            UInt rSD, PPCAMode* am, Bool mode64,
   3535                            VexEndness endness_host )
   3536 {
   3537    UInt rA, rB;
   3538    vassert(am->tag == Pam_RR);
   3539 
   3540    rA  = iregEnc(am->Pam.RR.base, mode64);
   3541    rB  = iregEnc(am->Pam.RR.index, mode64);
   3542 
   3543    p = mkFormX(p, opc1, rSD, rA, rB, opc2, 0, endness_host);
   3544    return p;
   3545 }
   3546 
   3547 
   3548 /* Load imm to r_dst */
   3549 static UChar* mkLoadImm ( UChar* p, UInt r_dst, ULong imm, Bool mode64,
   3550                           VexEndness endness_host )
   3551 {
   3552    vassert(r_dst < 0x20);
   3553 
   3554    if (!mode64) {
   3555       /* In 32-bit mode, make sure the top 32 bits of imm are a sign
   3556          extension of the bottom 32 bits, so that the range tests
   3557          below work correctly. */
   3558       UInt u32 = (UInt)imm;
   3559       Int  s32 = (Int)u32;
   3560       Long s64 = (Long)s32;
   3561       imm = (ULong)s64;
   3562    }
   3563 
   3564    if (imm >= 0xFFFFFFFFFFFF8000ULL || imm < 0x8000) {
   3565       // sign-extendable from 16 bits
   3566 
   3567       // addi r_dst,0,imm  => li r_dst,imm
   3568       p = mkFormD(p, 14, r_dst, 0, imm & 0xFFFF, endness_host);
   3569    } else {
   3570       if (imm >= 0xFFFFFFFF80000000ULL || imm < 0x80000000ULL) {
   3571          // sign-extendable from 32 bits
   3572 
   3573          // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
   3574          p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF, endness_host);
   3575          // ori r_dst, r_dst, (imm & 0xFFFF)
   3576          p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host);
   3577       } else {
   3578          // full 64bit immediate load: 5 (five!) insns.
   3579          vassert(mode64);
   3580 
   3581          // load high word
   3582 
   3583          // lis r_dst, (imm>>48) & 0xFFFF
   3584          p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF, endness_host);
   3585 
   3586          // ori r_dst, r_dst, (imm>>32) & 0xFFFF
   3587          if ((imm>>32) & 0xFFFF)
   3588 	   p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF, endness_host);
   3589 
   3590          // shift r_dst low word to high word => rldicr
   3591          p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1, endness_host);
   3592 
   3593          // load low word
   3594 
   3595          // oris r_dst, r_dst, (imm>>16) & 0xFFFF
   3596          if ((imm>>16) & 0xFFFF)
   3597             p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF, endness_host);
   3598 
   3599          // ori r_dst, r_dst, (imm) & 0xFFFF
   3600          if (imm & 0xFFFF)
   3601             p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host);
   3602       }
   3603    }
   3604    return p;
   3605 }
   3606 
   3607 /* A simplified version of mkLoadImm that always generates 2 or 5
   3608    instructions (32 or 64 bits respectively) even if it could generate
   3609    fewer.  This is needed for generating fixed sized patchable
   3610    sequences. */
   3611 static UChar* mkLoadImm_EXACTLY2or5 ( UChar* p,
   3612                                       UInt r_dst, ULong imm, Bool mode64,
   3613                                       VexEndness endness_host )
   3614 {
   3615    vassert(r_dst < 0x20);
   3616 
   3617    if (!mode64) {
   3618       /* In 32-bit mode, make sure the top 32 bits of imm are a sign
   3619          extension of the bottom 32 bits.  (Probably unnecessary.) */
   3620       UInt u32 = (UInt)imm;
   3621       Int  s32 = (Int)u32;
   3622       Long s64 = (Long)s32;
   3623       imm = (ULong)s64;
   3624    }
   3625 
   3626    if (!mode64) {
   3627       // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
   3628       p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF, endness_host);
   3629       // ori r_dst, r_dst, (imm & 0xFFFF)
   3630       p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host);
   3631 
   3632    } else {
   3633       // full 64bit immediate load: 5 (five!) insns.
   3634 
   3635       // load high word
   3636       // lis r_dst, (imm>>48) & 0xFFFF
   3637       p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF, endness_host);
   3638 
   3639       // ori r_dst, r_dst, (imm>>32) & 0xFFFF
   3640       p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF, endness_host);
   3641 
   3642       // shift r_dst low word to high word => rldicr
   3643       p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1, endness_host);
   3644 
   3645       // load low word
   3646       // oris r_dst, r_dst, (imm>>16) & 0xFFFF
   3647       p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF, endness_host);
   3648 
   3649       // ori r_dst, r_dst, (imm) & 0xFFFF
   3650       p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host);
   3651    }
   3652    return p;
   3653 }
   3654 
   3655 /* Checks whether the sequence of bytes at p was indeed created
   3656    by mkLoadImm_EXACTLY2or5 with the given parameters. */
   3657 static Bool isLoadImm_EXACTLY2or5 ( UChar* p_to_check,
   3658                                     UInt r_dst, ULong imm, Bool mode64,
   3659                                     VexEndness endness_host )
   3660 {
   3661    vassert(r_dst < 0x20);
   3662 
   3663    if (!mode64) {
   3664       /* In 32-bit mode, make sure the top 32 bits of imm are a sign
   3665          extension of the bottom 32 bits.  (Probably unnecessary.) */
   3666       UInt u32 = (UInt)imm;
   3667       Int  s32 = (Int)u32;
   3668       Long s64 = (Long)s32;
   3669       imm = (ULong)s64;
   3670    }
   3671 
   3672    if (!mode64) {
   3673       UInt   expect[2] = { 0, 0 };
   3674       UChar* p         = (UChar*)&expect[0];
   3675       // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
   3676       p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF, endness_host);
   3677       // ori r_dst, r_dst, (imm & 0xFFFF)
   3678       p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host);
   3679       vassert(p == (UChar*)&expect[2]);
   3680 
   3681       return fetch32(p_to_check + 0, endness_host) == expect[0]
   3682              && fetch32(p_to_check + 4, endness_host) == expect[1];
   3683 
   3684    } else {
   3685       UInt   expect[5] = { 0, 0, 0, 0, 0 };
   3686       UChar* p         = (UChar*)&expect[0];
   3687       // full 64bit immediate load: 5 (five!) insns.
   3688 
   3689       // load high word
   3690       // lis r_dst, (imm>>48) & 0xFFFF
   3691       p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF, endness_host);
   3692 
   3693       // ori r_dst, r_dst, (imm>>32) & 0xFFFF
   3694       p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF, endness_host);
   3695 
   3696       // shift r_dst low word to high word => rldicr
   3697       p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1, endness_host);
   3698 
   3699       // load low word
   3700       // oris r_dst, r_dst, (imm>>16) & 0xFFFF
   3701       p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF, endness_host);
   3702 
   3703       // ori r_dst, r_dst, (imm) & 0xFFFF
   3704       p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host);
   3705 
   3706       vassert(p == (UChar*)&expect[5]);
   3707 
   3708       return fetch32(p_to_check + 0, endness_host) == expect[0]
   3709              && fetch32(p_to_check + 4,  endness_host) == expect[1]
   3710              && fetch32(p_to_check + 8,  endness_host) == expect[2]
   3711              && fetch32(p_to_check + 12, endness_host) == expect[3]
   3712              && fetch32(p_to_check + 16, endness_host) == expect[4];
   3713    }
   3714 }
   3715 
   3716 
   3717 /* Generate a machine-word sized load or store.  Simplified version of
   3718    the Pin_Load and Pin_Store cases below. */
   3719 static UChar* do_load_or_store_machine_word (
   3720                  UChar* p, Bool isLoad,
   3721                  UInt reg, PPCAMode* am, Bool mode64, VexEndness endness_host )
   3722 {
   3723    if (isLoad) {
   3724       UInt opc1, sz = mode64 ? 8 : 4;
   3725       switch (am->tag) {
   3726          case Pam_IR:
   3727             if (mode64) {
   3728                vassert(0 == (am->Pam.IR.index & 3));
   3729             }
   3730             switch (sz) {
   3731                case 4:  opc1 = 32; vassert(!mode64); break;
   3732                case 8:  opc1 = 58; vassert(mode64);  break;
   3733                default: vassert(0);
   3734             }
   3735             p = doAMode_IR(p, opc1, reg, am, mode64, endness_host);
   3736             break;
   3737          case Pam_RR:
   3738             /* we could handle this case, but we don't expect to ever
   3739                need to. */
   3740             vassert(0);
   3741          default:
   3742             vassert(0);
   3743       }
   3744    } else /*store*/ {
   3745       UInt opc1, sz = mode64 ? 8 : 4;
   3746       switch (am->tag) {
   3747          case Pam_IR:
   3748             if (mode64) {
   3749                vassert(0 == (am->Pam.IR.index & 3));
   3750             }
   3751             switch (sz) {
   3752                case 4:  opc1 = 36; vassert(!mode64); break;
   3753                case 8:  opc1 = 62; vassert(mode64);  break;
   3754                default: vassert(0);
   3755             }
   3756             p = doAMode_IR(p, opc1, reg, am, mode64, endness_host);
   3757             break;
   3758          case Pam_RR:
   3759             /* we could handle this case, but we don't expect to ever
   3760                need to. */
   3761             vassert(0);
   3762          default:
   3763             vassert(0);
   3764       }
   3765    }
   3766    return p;
   3767 }
   3768 
   3769 /* Generate a 32-bit sized load or store.  Simplified version of
   3770    do_load_or_store_machine_word above. */
   3771 static UChar* do_load_or_store_word32 (
   3772                  UChar* p, Bool isLoad,
   3773                  UInt reg, PPCAMode* am, Bool mode64, VexEndness endness_host )
   3774 {
   3775    if (isLoad) {
   3776       UInt opc1;
   3777       switch (am->tag) {
   3778          case Pam_IR:
   3779             if (mode64) {
   3780                vassert(0 == (am->Pam.IR.index & 3));
   3781             }
   3782             opc1 = 32;
   3783             p = doAMode_IR(p, opc1, reg, am, mode64, endness_host);
   3784             break;
   3785          case Pam_RR:
   3786             /* we could handle this case, but we don't expect to ever
   3787                need to. */
   3788             vassert(0);
   3789          default:
   3790             vassert(0);
   3791       }
   3792    } else /*store*/ {
   3793       UInt opc1;
   3794       switch (am->tag) {
   3795          case Pam_IR:
   3796             if (mode64) {
   3797                vassert(0 == (am->Pam.IR.index & 3));
   3798             }
   3799             opc1 = 36;
   3800             p = doAMode_IR(p, opc1, reg, am, mode64, endness_host);
   3801             break;
   3802          case Pam_RR:
   3803             /* we could handle this case, but we don't expect to ever
   3804                need to. */
   3805             vassert(0);
   3806          default:
   3807             vassert(0);
   3808       }
   3809    }
   3810    return p;
   3811 }
   3812 
   3813 /* Move r_dst to r_src */
   3814 static UChar* mkMoveReg ( UChar* p, UInt r_dst, UInt r_src,
   3815                           VexEndness endness_host )
   3816 {
   3817    vassert(r_dst < 0x20);
   3818    vassert(r_src < 0x20);
   3819 
   3820    if (r_dst != r_src) {
   3821       /* or r_dst, r_src, r_src */
   3822       p = mkFormX(p, 31, r_src, r_dst, r_src, 444, 0, endness_host );
   3823    }
   3824    return p;
   3825 }
   3826 
   3827 static UChar* mkFormVX ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3828                          UInt r3, UInt opc2, VexEndness endness_host )
   3829 {
   3830    UInt theInstr;
   3831    vassert(opc1 < 0x40);
   3832    vassert(r1   < 0x20);
   3833    vassert(r2   < 0x20);
   3834    vassert(r3   < 0x20);
   3835    vassert(opc2 < 0x800);
   3836    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | opc2);
   3837    return emit32(p, theInstr, endness_host);
   3838 }
   3839 
   3840 static UChar* mkFormVSXRND ( UChar* p, UInt opc1, UInt R, UInt r1,
   3841                              UInt r2, UInt RMC, UInt opc2, UChar EX,
   3842                              VexEndness endness_host )
   3843 {
   3844    /* The register mapping is all done using VR register numbers for the
   3845     * V128 support.  This means that the operands for this instruction have
   3846     * been loaded into a VR register. The 32 VR registers map to VSR registers
   3847     * 32 to 63. For these instructions, the hardware adds 32 to the source
   3848     * and destination register numbers.  Do not need to adjust the register
   3849     * numbers for these instructions.
   3850     */
   3851 
   3852    UInt theInstr;
   3853 
   3854    vassert(opc1 < 0x40);
   3855    vassert(r1   < 0x20);
   3856    vassert(r2   < 0x20);
   3857    vassert(opc2 < 0x100);
   3858    vassert(EX  < 0x2);
   3859    vassert(R   < 0x2);
   3860    vassert(RMC < 0x4);
   3861 
   3862    theInstr = ((opc1<<26)  | (r1<<21) | (R<<16) | (r2<<11) | (RMC<<9) |
   3863                (opc2 << 1) | EX);
   3864    return emit32(p, theInstr, endness_host);
   3865 }
   3866 
   3867 static UChar* mkFormVX_BX_TX ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3868                                UInt r3, UInt opc2, VexEndness endness_host )
   3869 {
   3870    /* The register mapping is all done using VR register numbers for the
   3871     * V128 support.  This means that the operands for this instruction have
   3872     * been loaded into a VR register. The 32 VR registers map to VSR registers
   3873     * 32 to 63. So to make the issued instruction reference the
   3874     * corresponding VR register we have to add 32 to the source and
   3875     * destination operand numbers, then load the new operand number into the
   3876     * correct bit fields.
   3877     *
   3878     * r1 = 32xTX + T; r3 = 32xBX + B;
   3879     * TX is bit 0, BX is bit 1, T is in bits [25:21], B is in bit [14:11]
   3880     * opc2 is in bits [10:2]
   3881     */
   3882    UInt T, TX, B, BX;
   3883 
   3884    UInt theInstr;
   3885 
   3886    r1 += 32;   // adjust the VSR register number to map to the VR number
   3887    r3 += 32;
   3888 
   3889    vassert(opc1 < 0x40);
   3890    vassert(r1   < 0x40);
   3891    vassert(r2   < 0x20);
   3892    vassert(r3   < 0x40);
   3893    vassert(opc2 < 0x800);
   3894 
   3895    T  = r1 & 0x1F;
   3896    TX = r1 >> 5;
   3897    B  = r3 & 0x1F;
   3898    BX = r3 >> 5;
   3899    theInstr = ((opc1<<26) | (T<<21) | (r2<<16) | (B<<11) | (opc2<<2)
   3900                | (BX<<1) | TX);
   3901    return emit32(p, theInstr, endness_host);
   3902 }
   3903 
   3904 static UChar* mkFormVXR0 ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3905                            UInt r3, UInt opc2, UChar R0,
   3906                            VexEndness endness_host )
   3907 {
   3908    /* The register mapping is all done using VR register numbers for the
   3909     * V128 support.  This means that the operands for this instruction have
   3910     * been loaded into a VR register. The 32 VR registers map to VSR registers
   3911     * 32 to 63.  For these instructions, the hardware adds 32 to the source
   3912     * and destination register numbers.  Do not need to adjust the register
   3913     * numbers for these instructions.
   3914     */
   3915 
   3916    UInt theInstr;
   3917 
   3918    vassert(opc1 < 0x40);
   3919    vassert(r1   < 0x20);  // register numbers are between 0 and 31 (5-bits)
   3920    vassert(r2   < 0x20);
   3921    vassert(r3   < 0x20);
   3922    vassert(opc2 < 0x800);
   3923    vassert(R0 < 0x2);
   3924 
   3925    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | (opc2<<1) | R0);
   3926    return emit32(p, theInstr, endness_host);
   3927 }
   3928 
   3929 static UChar* mkFormVXI ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3930                           UInt r3, UInt opc2, VexEndness endness_host )
   3931 {
   3932    UInt theInstr;
   3933    vassert(opc1 < 0x40);
   3934    vassert(r1   < 0x20);
   3935    vassert(r2   < 0x20);
   3936    vassert(r3   < 0x20);
   3937    vassert(opc2 < 0x27);
   3938    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | opc2<<1);
   3939    return emit32(p, theInstr, endness_host);
   3940 }
   3941 
   3942 static UChar* mkFormVXR ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3943                           UInt r3, UInt Rc, UInt opc2,
   3944                           VexEndness endness_host )
   3945 {
   3946    UInt theInstr;
   3947    vassert(opc1 < 0x40);
   3948    vassert(r1   < 0x20);
   3949    vassert(r2   < 0x20);
   3950    vassert(r3   < 0x20);
   3951    vassert(Rc   < 0x2);
   3952    vassert(opc2 < 0x400);
   3953    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3954                (r3<<11) | (Rc<<10) | opc2);
   3955    return emit32(p, theInstr, endness_host);
   3956 }
   3957 
   3958 static UChar* mkFormVA ( UChar* p, UInt opc1, UInt r1, UInt r2,
   3959                          UInt r3, UInt r4, UInt opc2, VexEndness endness_host )
   3960 {
   3961    UInt theInstr;
   3962    vassert(opc1 < 0x40);
   3963    vassert(r1   < 0x20);
   3964    vassert(r2   < 0x20);
   3965    vassert(r3   < 0x20);
   3966    vassert(r4   < 0x20);
   3967    vassert(opc2 < 0x40);
   3968    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   3969                (r3<<11) | (r4<<6) | opc2);
   3970    return emit32(p, theInstr, endness_host);
   3971 }
   3972 
   3973 
   3974 
   3975 /* Emit an instruction into buf and return the number of bytes used.
   3976    Note that buf is not the insn's final place, and therefore it is
   3977    imperative to emit position-independent code.  If the emitted
   3978    instruction was a profiler inc, set *is_profInc to True, else leave
   3979    it unchanged.
   3980 */
   3981 Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc,
   3982                     UChar* buf, Int nbuf, const PPCInstr* i,
   3983                     Bool mode64, VexEndness endness_host,
   3984                     const void* disp_cp_chain_me_to_slowEP,
   3985                     const void* disp_cp_chain_me_to_fastEP,
   3986                     const void* disp_cp_xindir,
   3987                     const void* disp_cp_xassisted)
   3988 {
   3989    UChar* p = &buf[0];
   3990    vassert(nbuf >= 32);
   3991 
   3992    if (0) {
   3993       vex_printf("asm  ");ppPPCInstr(i, mode64); vex_printf("\n");
   3994    }
   3995 
   3996    switch (i->tag) {
   3997 
   3998    case Pin_LI:
   3999       p = mkLoadImm(p, iregEnc(i->Pin.LI.dst, mode64),
   4000                     i->Pin.LI.imm64, mode64, endness_host);
   4001       goto done;
   4002 
   4003    case Pin_Alu: {
   4004       PPCRH* srcR   = i->Pin.Alu.srcR;
   4005       Bool   immR   = toBool(srcR->tag == Prh_Imm);
   4006       UInt   r_dst  = iregEnc(i->Pin.Alu.dst, mode64);
   4007       UInt   r_srcL = iregEnc(i->Pin.Alu.srcL, mode64);
   4008       UInt   r_srcR = immR ? (-1)/*bogus*/ :
   4009                              iregEnc(srcR->Prh.Reg.reg, mode64);
   4010 
   4011       switch (i->Pin.Alu.op) {
   4012       case Palu_ADD:
   4013          if (immR) {
   4014             /* addi (PPC32 p350) */
   4015             vassert(srcR->Prh.Imm.syned);
   4016             vassert(srcR->Prh.Imm.imm16 != 0x8000);
   4017             p = mkFormD(p, 14, r_dst, r_srcL, srcR->Prh.Imm.imm16, endness_host);
   4018          } else {
   4019             /* add (PPC32 p347) */
   4020             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 266, 0, endness_host);
   4021          }
   4022          break;
   4023 
   4024       case Palu_SUB:
   4025          if (immR) {
   4026             /* addi (PPC32 p350), but with negated imm */
   4027             vassert(srcR->Prh.Imm.syned);
   4028             vassert(srcR->Prh.Imm.imm16 != 0x8000);
   4029             p = mkFormD(p, 14, r_dst, r_srcL, (- srcR->Prh.Imm.imm16),
   4030                         endness_host);
   4031          } else {
   4032             /* subf (PPC32 p537), with args the "wrong" way round */
   4033             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 40, 0, endness_host);
   4034          }
   4035          break;
   4036 
   4037       case Palu_AND:
   4038          if (immR) {
   4039             /* andi. (PPC32 p358) */
   4040             vassert(!srcR->Prh.Imm.syned);
   4041             p = mkFormD(p, 28, r_srcL, r_dst, srcR->Prh.Imm.imm16, endness_host);
   4042          } else {
   4043             /* and (PPC32 p356) */
   4044             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 28, 0, endness_host);
   4045          }
   4046          break;
   4047 
   4048       case Palu_OR:
   4049          if (immR) {
   4050             /* ori (PPC32 p497) */
   4051             vassert(!srcR->Prh.Imm.syned);
   4052             p = mkFormD(p, 24, r_srcL, r_dst, srcR->Prh.Imm.imm16, endness_host);
   4053          } else {
   4054             /* or (PPC32 p495) */
   4055             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 444, 0, endness_host);
   4056          }
   4057          break;
   4058 
   4059       case Palu_XOR:
   4060          if (immR) {
   4061             /* xori (PPC32 p550) */
   4062             vassert(!srcR->Prh.Imm.syned);
   4063             p = mkFormD(p, 26, r_srcL, r_dst, srcR->Prh.Imm.imm16, endness_host);
   4064          } else {
   4065             /* xor (PPC32 p549) */
   4066             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 316, 0, endness_host);
   4067          }
   4068          break;
   4069 
   4070       default:
   4071          goto bad;
   4072       }
   4073       goto done;
   4074    }
   4075 
   4076    case Pin_Shft: {
   4077       PPCRH* srcR   = i->Pin.Shft.srcR;
   4078       Bool   sz32   = i->Pin.Shft.sz32;
   4079       Bool   immR   = toBool(srcR->tag == Prh_Imm);
   4080       UInt   r_dst  = iregEnc(i->Pin.Shft.dst, mode64);
   4081       UInt   r_srcL = iregEnc(i->Pin.Shft.srcL, mode64);
   4082       UInt   r_srcR = immR ? (-1)/*bogus*/ :
   4083                              iregEnc(srcR->Prh.Reg.reg, mode64);
   4084       if (!mode64)
   4085          vassert(sz32);
   4086 
   4087       switch (i->Pin.Shft.op) {
   4088       case Pshft_SHL:
   4089          if (sz32) {
   4090             if (immR) {
   4091                /* rd = rs << n, 1 <= n <= 31
   4092                   is
   4093                   rlwinm rd,rs,n,0,31-n  (PPC32 p501)
   4094                */
   4095                UInt n = srcR->Prh.Imm.imm16;
   4096                vassert(!srcR->Prh.Imm.syned);
   4097                vassert(n > 0 && n < 32);
   4098                p = mkFormM(p, 21, r_srcL, r_dst, n, 0, 31-n, 0, endness_host);
   4099             } else {
   4100                /* slw (PPC32 p505) */
   4101                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 24, 0, endness_host);
   4102             }
   4103          } else {
   4104             if (immR) {
   4105                /* rd = rs << n, 1 <= n <= 63
   4106                   is
   4107                   rldicr rd,rs,n,63-n  (PPC64 p559)
   4108                */
   4109                UInt n = srcR->Prh.Imm.imm16;
   4110                vassert(!srcR->Prh.Imm.syned);
   4111                vassert(n > 0 && n < 64);
   4112                p = mkFormMD(p, 30, r_srcL, r_dst, n, 63-n, 1, endness_host);
   4113             } else {
   4114                /* sld (PPC64 p568) */
   4115                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 27, 0, endness_host);
   4116             }
   4117          }
   4118          break;
   4119 
   4120       case Pshft_SHR:
   4121          if (sz32) {
   4122              if (immR) {
   4123                /* rd = rs >>u n, 1 <= n <= 31
   4124                   is
   4125                   rlwinm rd,rs,32-n,n,31  (PPC32 p501)
   4126                */
   4127                UInt n = srcR->Prh.Imm.imm16;
   4128                vassert(!srcR->Prh.Imm.syned);
   4129                vassert(n > 0 && n < 32);
   4130                p = mkFormM(p, 21, r_srcL, r_dst, 32-n, n, 31, 0, endness_host);
   4131             } else {
   4132                /* srw (PPC32 p508) */
   4133                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 536, 0, endness_host);
   4134             }
   4135          } else {
   4136             if (immR) {
   4137                /* rd = rs >>u n, 1 <= n <= 63
   4138                   is
   4139                   rldicl rd,rs,64-n,n  (PPC64 p558)
   4140                */
   4141                UInt n = srcR->Prh.Imm.imm16;
   4142                vassert(!srcR->Prh.Imm.syned);
   4143                vassert(n > 0 && n < 64);
   4144                p = mkFormMD(p, 30, r_srcL, r_dst, 64-n, n, 0, endness_host);
   4145             } else {
   4146                /* srd (PPC64 p574) */
   4147                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 539, 0, endness_host);
   4148             }
   4149          }
   4150          break;
   4151 
   4152       case Pshft_SAR:
   4153          if (sz32) {
   4154             if (immR) {
   4155                /* srawi (PPC32 p507) */
   4156                UInt n = srcR->Prh.Imm.imm16;
   4157                vassert(!srcR->Prh.Imm.syned);
   4158                /* In 64-bit mode, we allow right shifts by zero bits
   4159                   as that is a handy way to sign extend the lower 32
   4160                   bits into the upper 32 bits. */
   4161                if (mode64)
   4162                   vassert(n >= 0 && n < 32);
   4163                else
   4164                   vassert(n > 0 && n < 32);
   4165                p = mkFormX(p, 31, r_srcL, r_dst, n, 824, 0, endness_host);
   4166             } else {
   4167                /* sraw (PPC32 p506) */
   4168                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 792, 0, endness_host);
   4169             }
   4170          } else {
   4171             if (immR) {
   4172                /* sradi (PPC64 p571) */
   4173                UInt n = srcR->Prh.Imm.imm16;
   4174                vassert(!srcR->Prh.Imm.syned);
   4175                vassert(n > 0 && n < 64);
   4176                p = mkFormXS(p, 31, r_srcL, r_dst, n, 413, 0, endness_host);
   4177             } else {
   4178                /* srad (PPC32 p570) */
   4179                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 794, 0, endness_host);
   4180             }
   4181          }
   4182          break;
   4183 
   4184       default:
   4185          goto bad;
   4186       }
   4187       goto done;
   4188    }
   4189 
   4190    case Pin_AddSubC: {
   4191       Bool isAdd  = i->Pin.AddSubC.isAdd;
   4192       Bool setC   = i->Pin.AddSubC.setC;
   4193       UInt r_srcL = iregEnc(i->Pin.AddSubC.srcL, mode64);
   4194       UInt r_srcR = iregEnc(i->Pin.AddSubC.srcR, mode64);
   4195       UInt r_dst  = iregEnc(i->Pin.AddSubC.dst, mode64);
   4196 
   4197       if (isAdd) {
   4198          if (setC) /* addc (PPC32 p348) */
   4199             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 10, 0, endness_host);
   4200          else          /* adde (PPC32 p349) */
   4201             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 138, 0, endness_host);
   4202       } else {
   4203          /* subfX, with args the "wrong" way round */
   4204          if (setC) /* subfc (PPC32 p538) */
   4205             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 8, 0, endness_host);
   4206          else          /* subfe (PPC32 p539) */
   4207             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 136, 0, endness_host);
   4208       }
   4209       goto done;
   4210    }
   4211 
   4212    case Pin_Cmp: {
   4213       Bool syned  = i->Pin.Cmp.syned;
   4214       Bool sz32   = i->Pin.Cmp.sz32;
   4215       UInt fld1   = i->Pin.Cmp.crfD << 2;
   4216       UInt r_srcL = iregEnc(i->Pin.Cmp.srcL, mode64);
   4217       UInt r_srcR, imm_srcR;
   4218       PPCRH* srcR = i->Pin.Cmp.srcR;
   4219 
   4220       if (!mode64)        // cmp double word invalid for mode32
   4221          vassert(sz32);
   4222       else if (!sz32)     // mode64 && cmp64: set L=1
   4223          fld1 |= 1;
   4224 
   4225       switch (srcR->tag) {
   4226       case Prh_Imm:
   4227          vassert(syned == srcR->Prh.Imm.syned);
   4228          imm_srcR = srcR->Prh.Imm.imm16;
   4229          if (syned) {  // cmpw/di  (signed)   (PPC32 p368)
   4230             vassert(imm_srcR != 0x8000);
   4231             p = mkFormD(p, 11, fld1, r_srcL, imm_srcR, endness_host);
   4232          } else {      // cmplw/di (unsigned) (PPC32 p370)
   4233             p = mkFormD(p, 10, fld1, r_srcL, imm_srcR, endness_host);
   4234          }
   4235          break;
   4236       case Prh_Reg:
   4237          r_srcR = iregEnc(srcR->Prh.Reg.reg, mode64);
   4238          if (syned)  // cmpwi  (signed)   (PPC32 p367)
   4239             p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 0, 0, endness_host);
   4240          else        // cmplwi (unsigned) (PPC32 p379)
   4241             p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 32, 0, endness_host);
   4242          break;
   4243       default:
   4244          goto bad;
   4245       }
   4246       goto done;
   4247    }
   4248 
   4249    case Pin_Unary: {
   4250       UInt r_dst = iregEnc(i->Pin.Unary.dst, mode64);
   4251       UInt r_src = iregEnc(i->Pin.Unary.src, mode64);
   4252 
   4253       switch (i->Pin.Unary.op) {
   4254       case Pun_NOT:  // nor r_dst,r_src,r_src
   4255          p = mkFormX(p, 31, r_src, r_dst, r_src, 124, 0, endness_host);
   4256          break;
   4257       case Pun_NEG:  // neg r_dst,r_src
   4258          p = mkFormXO(p, 31, r_dst, r_src, 0, 0, 104, 0, endness_host);
   4259          break;
   4260       case Pun_CLZ32:  // cntlzw r_dst, r_src
   4261          p = mkFormX(p, 31, r_src, r_dst, 0, 26, 0, endness_host);
   4262          break;
   4263       case Pun_CLZ64:  // cntlzd r_dst, r_src
   4264          vassert(mode64);
   4265          p = mkFormX(p, 31, r_src, r_dst, 0, 58, 0, endness_host);
   4266          break;
   4267       case Pun_CTZ32:  // cnttzw r_dst, r_src
   4268          /* Note oder of src and dst is backwards from normal */
   4269          p = mkFormX(p, 31, r_src, r_dst, 0, 538, 0, endness_host);
   4270          break;
   4271       case Pun_CTZ64:  // cnttzd r_dst, r_src
   4272          /* Note oder of src and dst is backwards from normal */
   4273          vassert(mode64);
   4274          p = mkFormX(p, 31, r_src, r_dst, 0, 570, 0, endness_host);
   4275          break;
   4276       case Pun_EXTSW:  // extsw r_dst, r_src
   4277          vassert(mode64);
   4278          p = mkFormX(p, 31, r_src, r_dst, 0, 986, 0, endness_host);
   4279          break;
   4280       default: goto bad;
   4281       }
   4282       goto done;
   4283    }
   4284 
   4285    case Pin_MulL: {
   4286       Bool syned  = i->Pin.MulL.syned;
   4287       Bool sz32   = i->Pin.MulL.sz32;
   4288       UInt r_dst  = iregEnc(i->Pin.MulL.dst, mode64);
   4289       UInt r_srcL = iregEnc(i->Pin.MulL.srcL, mode64);
   4290       UInt r_srcR = iregEnc(i->Pin.MulL.srcR, mode64);
   4291 
   4292       if (!mode64)
   4293          vassert(sz32);
   4294 
   4295       if (i->Pin.MulL.hi) {
   4296          // mul hi words, must consider sign
   4297          if (sz32) {
   4298             if (syned)  // mulhw r_dst,r_srcL,r_srcR
   4299                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 75, 0,
   4300                             endness_host);
   4301             else        // mulhwu r_dst,r_srcL,r_srcR
   4302                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 11, 0,
   4303                             endness_host);
   4304          } else {
   4305             if (syned)  // mulhd r_dst,r_srcL,r_srcR
   4306                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 73, 0,
   4307                             endness_host);
   4308             else        // mulhdu r_dst,r_srcL,r_srcR
   4309                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 9, 0, endness_host);
   4310          }
   4311       } else {
   4312          // mul low word, sign is irrelevant
   4313          vassert(!i->Pin.MulL.syned);
   4314          if (sz32)      // mullw r_dst,r_srcL,r_srcR
   4315             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 235, 0, endness_host);
   4316          else           // mulld r_dst,r_srcL,r_srcR
   4317             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 233, 0, endness_host);
   4318       }
   4319       goto done;
   4320    }
   4321 
   4322    case Pin_Div: {
   4323       Bool syned  = i->Pin.Div.syned;
   4324       Bool sz32   = i->Pin.Div.sz32;
   4325       UInt r_dst  = iregEnc(i->Pin.Div.dst, mode64);
   4326       UInt r_srcL = iregEnc(i->Pin.Div.srcL, mode64);
   4327       UInt r_srcR = iregEnc(i->Pin.Div.srcR, mode64);
   4328 
   4329       if (!mode64)
   4330          vassert(sz32);
   4331 
   4332       if (i->Pin.Div.extended) {
   4333          if (sz32) {
   4334             if (syned)
   4335                // divwe r_dst,r_srcL,r_srcR
   4336                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 427, 0,
   4337                             endness_host);
   4338             else
   4339                // divweu r_dst,r_srcL,r_srcR
   4340                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 395, 0,
   4341                             endness_host);
   4342          } else {
   4343             if (syned)
   4344                // divde r_dst,r_srcL,r_srcR
   4345                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 425, 0,
   4346                             endness_host);
   4347             else
   4348                // divdeu r_dst,r_srcL,r_srcR
   4349                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 393, 0,
   4350                             endness_host);
   4351          }
   4352       } else if (sz32) {
   4353          if (syned)  // divw r_dst,r_srcL,r_srcR
   4354             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 491, 0, endness_host);
   4355          else        // divwu r_dst,r_srcL,r_srcR
   4356             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 459, 0, endness_host);
   4357       } else {
   4358          if (syned)  // divd r_dst,r_srcL,r_srcR
   4359             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 489, 0, endness_host);
   4360          else        // divdu r_dst,r_srcL,r_srcR
   4361             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 457, 0, endness_host);
   4362       }
   4363       goto done;
   4364    }
   4365 
   4366    case Pin_Call: {
   4367       if (i->Pin.Call.cond.test != Pct_ALWAYS
   4368           && i->Pin.Call.rloc.pri != RLPri_None) {
   4369          /* The call might not happen (it isn't unconditional) and it
   4370             returns a result.  In this case we will need to generate a
   4371             control flow diamond to put 0x555..555 in the return
   4372             register(s) in the case where the call doesn't happen.  If
   4373             this ever becomes necessary, maybe copy code from the ARM
   4374             equivalent.  Until that day, just give up. */
   4375          goto bad;
   4376       }
   4377       PPCCondCode cond  = i->Pin.Call.cond;
   4378       UInt        r_dst = 10;
   4379       /* As per detailed comment for Pin_Call in
   4380          getRegUsage_PPCInstr above, %r10 is used as an address temp */
   4381 
   4382       /* jump over the following insns if condition does not hold */
   4383       UChar* ptmp = NULL;
   4384       if (cond.test != Pct_ALWAYS) {
   4385          /* jmp fwds if !condition */
   4386          /* don't know how many bytes to jump over yet...
   4387             make space for a jump instruction and fill in later. */
   4388          ptmp = p; /* fill in this bit later */
   4389          p += 4;                                          // p += 4
   4390       }
   4391 
   4392       /* load target to r_dst */                          // p += 4|8|20
   4393       p = mkLoadImm(p, r_dst, i->Pin.Call.target, mode64, endness_host);
   4394 
   4395       /* mtspr 9,r_dst => move r_dst to count register */
   4396       p = mkFormXFX(p, r_dst, 9, 467, endness_host);               // p += 4
   4397 
   4398       /* bctrl => branch to count register (and save to lr) */
   4399       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 1, endness_host); // p += 4
   4400 
   4401       /* Fix up the conditional jump, if there was one. */
   4402       if (cond.test != Pct_ALWAYS) {
   4403          Int delta = p - ptmp;
   4404          vassert(delta >= 16 && delta <= 32);
   4405          /* bc !ct,cf,delta */
   4406          mkFormB(ptmp, invertCondTest(cond.test),
   4407                  cond.flag, (delta>>2), 0, 0, endness_host);
   4408       }
   4409       goto done;
   4410    }
   4411 
   4412    case Pin_XDirect: {
   4413       /* NB: what goes on here has to be very closely coordinated
   4414          with the chainXDirect_PPC and unchainXDirect_PPC below. */
   4415       /* We're generating chain-me requests here, so we need to be
   4416             sure this is actually allowed -- no-redir translations
   4417             can't use chain-me's.  Hence: */
   4418       vassert(disp_cp_chain_me_to_slowEP != NULL);
   4419       vassert(disp_cp_chain_me_to_fastEP != NULL);
   4420 
   4421       /* First off, if this is conditional, create a conditional jump
   4422          over the rest of it.  Or at least, leave a space for it that
   4423          we will shortly fill in. */
   4424       UChar* ptmp = NULL;
   4425       if (i->Pin.XDirect.cond.test != Pct_ALWAYS) {
   4426          vassert(i->Pin.XDirect.cond.flag != Pcf_NONE);
   4427          ptmp = p;
   4428          p += 4;
   4429       } else {
   4430          vassert(i->Pin.XDirect.cond.flag == Pcf_NONE);
   4431       }
   4432 
   4433       /* Update the guest CIA. */
   4434       /* imm32/64 r30, dstGA */
   4435       if (!mode64) vassert(0 == (((ULong)i->Pin.XDirect.dstGA) >> 32));
   4436       p = mkLoadImm(p, /*r*/30, (ULong)i->Pin.XDirect.dstGA, mode64,
   4437                     endness_host);
   4438       /* stw/std r30, amCIA */
   4439       p = do_load_or_store_machine_word(
   4440              p, False/*!isLoad*/,
   4441              /*r*/30, i->Pin.XDirect.amCIA, mode64, endness_host
   4442           );
   4443 
   4444       /* --- FIRST PATCHABLE BYTE follows --- */
   4445       /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're calling
   4446          to) backs up the return address, so as to find the address of
   4447          the first patchable byte.  So: don't change the number of
   4448          instructions (32-bit: 4, 64-bit: 7) below. */
   4449       /* imm32/64-fixed r30, VG_(disp_cp_chain_me_to_{slowEP,fastEP} */
   4450       const void* disp_cp_chain_me
   4451                = i->Pin.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP
   4452                                          : disp_cp_chain_me_to_slowEP;
   4453       p = mkLoadImm_EXACTLY2or5(
   4454              p, /*r*/30, (Addr)disp_cp_chain_me, mode64, endness_host);
   4455       /* mtctr r30 */
   4456       p = mkFormXFX(p, /*r*/30, 9, 467, endness_host);
   4457       /* bctrl */
   4458       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 1, endness_host);
   4459       /* --- END of PATCHABLE BYTES --- */
   4460 
   4461       /* Fix up the conditional jump, if there was one. */
   4462       if (i->Pin.XDirect.cond.test != Pct_ALWAYS) {
   4463          Int delta = p - ptmp;
   4464          vassert(delta >= 16 && delta <= 64 && 0 == (delta & 3));
   4465          /* bc !ct,cf,delta */
   4466          mkFormB(ptmp, invertCondTest(i->Pin.XDirect.cond.test),
   4467                  i->Pin.XDirect.cond.flag, (delta>>2), 0, 0, endness_host);
   4468       }
   4469       goto done;
   4470    }
   4471 
   4472    case Pin_XIndir: {
   4473       /* We're generating transfers that could lead indirectly to a
   4474          chain-me, so we need to be sure this is actually allowed --
   4475          no-redir translations are not allowed to reach normal
   4476          translations without going through the scheduler.  That means
   4477          no XDirects or XIndirs out from no-redir translations.
   4478          Hence: */
   4479       vassert(disp_cp_xindir != NULL);
   4480 
   4481       /* First off, if this is conditional, create a conditional jump
   4482          over the rest of it.  Or at least, leave a space for it that
   4483          we will shortly fill in. */
   4484       UChar* ptmp = NULL;
   4485       if (i->Pin.XIndir.cond.test != Pct_ALWAYS) {
   4486          vassert(i->Pin.XIndir.cond.flag != Pcf_NONE);
   4487          ptmp = p;
   4488          p += 4;
   4489       } else {
   4490          vassert(i->Pin.XIndir.cond.flag == Pcf_NONE);
   4491       }
   4492 
   4493       /* Update the guest CIA. */
   4494       /* stw/std r-dstGA, amCIA */
   4495       p = do_load_or_store_machine_word(
   4496              p, False/*!isLoad*/,
   4497              iregEnc(i->Pin.XIndir.dstGA, mode64),
   4498              i->Pin.XIndir.amCIA, mode64, endness_host
   4499           );
   4500 
   4501       /* imm32/64 r30, VG_(disp_cp_xindir) */
   4502       p = mkLoadImm(p, /*r*/30, (ULong)(Addr)disp_cp_xindir, mode64,
   4503                     endness_host);
   4504       /* mtctr r30 */
   4505       p = mkFormXFX(p, /*r*/30, 9, 467, endness_host);
   4506       /* bctr */
   4507       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 0, endness_host);
   4508 
   4509       /* Fix up the conditional jump, if there was one. */
   4510       if (i->Pin.XIndir.cond.test != Pct_ALWAYS) {
   4511          Int delta = p - ptmp;
   4512          vassert(delta >= 16 && delta <= 32 && 0 == (delta & 3));
   4513          /* bc !ct,cf,delta */
   4514          mkFormB(ptmp, invertCondTest(i->Pin.XIndir.cond.test),
   4515                  i->Pin.XIndir.cond.flag, (delta>>2), 0, 0, endness_host);
   4516       }
   4517       goto done;
   4518    }
   4519 
   4520    case Pin_XAssisted: {
   4521       /* First off, if this is conditional, create a conditional jump
   4522          over the rest of it.  Or at least, leave a space for it that
   4523          we will shortly fill in. */
   4524       UChar* ptmp = NULL;
   4525       if (i->Pin.XAssisted.cond.test != Pct_ALWAYS) {
   4526          vassert(i->Pin.XAssisted.cond.flag != Pcf_NONE);
   4527          ptmp = p;
   4528          p += 4;
   4529       } else {
   4530          vassert(i->Pin.XAssisted.cond.flag == Pcf_NONE);
   4531       }
   4532 
   4533       /* Update the guest CIA. */
   4534       /* stw/std r-dstGA, amCIA */
   4535       p = do_load_or_store_machine_word(
   4536              p, False/*!isLoad*/,
   4537              iregEnc(i->Pin.XIndir.dstGA, mode64),
   4538              i->Pin.XIndir.amCIA, mode64, endness_host
   4539           );
   4540 
   4541       /* imm32/64 r31, $magic_number */
   4542       UInt trcval = 0;
   4543       switch (i->Pin.XAssisted.jk) {
   4544          case Ijk_ClientReq:   trcval = VEX_TRC_JMP_CLIENTREQ;   break;
   4545          case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break;
   4546          //case Ijk_Sys_int128:  trcval = VEX_TRC_JMP_SYS_INT128;  break;
   4547          //case Ijk_Yield:       trcval = VEX_TRC_JMP_YIELD;       break;
   4548          case Ijk_EmWarn:      trcval = VEX_TRC_JMP_EMWARN;      break;
   4549          case Ijk_EmFail:      trcval = VEX_TRC_JMP_EMFAIL;      break;
   4550          //case Ijk_MapFail:     trcval = VEX_TRC_JMP_MAPFAIL;     break;
   4551          case Ijk_NoDecode:    trcval = VEX_TRC_JMP_NODECODE;    break;
   4552          case Ijk_InvalICache: trcval = VEX_TRC_JMP_INVALICACHE; break;
   4553          case Ijk_NoRedir:     trcval = VEX_TRC_JMP_NOREDIR;     break;
   4554          case Ijk_SigTRAP:     trcval = VEX_TRC_JMP_SIGTRAP;     break;
   4555          //case Ijk_SigSEGV:     trcval = VEX_TRC_JMP_SIGSEGV;     break;
   4556          case Ijk_SigBUS:        trcval = VEX_TRC_JMP_SIGBUS;    break;
   4557          case Ijk_Boring:      trcval = VEX_TRC_JMP_BORING;      break;
   4558          /* We don't expect to see the following being assisted. */
   4559          //case Ijk_Ret:
   4560          //case Ijk_Call:
   4561          /* fallthrough */
   4562          default:
   4563             ppIRJumpKind(i->Pin.XAssisted.jk);
   4564             vpanic("emit_ARMInstr.Pin_XAssisted: unexpected jump kind");
   4565       }
   4566       vassert(trcval != 0);
   4567       p = mkLoadImm(p, /*r*/31, trcval, mode64, endness_host);
   4568 
   4569       /* imm32/64 r30, VG_(disp_cp_xassisted) */
   4570       p = mkLoadImm(p, /*r*/30,
   4571                     (ULong)(Addr)disp_cp_xassisted, mode64,
   4572                      endness_host);
   4573       /* mtctr r30 */
   4574       p = mkFormXFX(p, /*r*/30, 9, 467, endness_host);
   4575       /* bctr */
   4576       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 0, endness_host);
   4577 
   4578       /* Fix up the conditional jump, if there was one. */
   4579       if (i->Pin.XAssisted.cond.test != Pct_ALWAYS) {
   4580          Int delta = p - ptmp;
   4581          vassert(delta >= 16 && delta <= 32 && 0 == (delta & 3));
   4582          /* bc !ct,cf,delta */
   4583          mkFormB(ptmp, invertCondTest(i->Pin.XAssisted.cond.test),
   4584                  i->Pin.XAssisted.cond.flag, (delta>>2), 0, 0, endness_host);
   4585       }
   4586       goto done;
   4587    }
   4588 
   4589    case Pin_CMov: {
   4590       UInt  r_dst, r_src;
   4591       ULong imm_src;
   4592       PPCCondCode cond;
   4593       vassert(i->Pin.CMov.cond.test != Pct_ALWAYS);
   4594 
   4595       r_dst = iregEnc(i->Pin.CMov.dst, mode64);
   4596       cond = i->Pin.CMov.cond;
   4597 
   4598       /* branch (if cond fails) over move instrs */
   4599       UChar* ptmp = NULL;
   4600       if (cond.test != Pct_ALWAYS) {
   4601          /* don't know how many bytes to jump over yet...
   4602             make space for a jump instruction and fill in later. */
   4603          ptmp = p; /* fill in this bit later */
   4604          p += 4;
   4605       }
   4606 
   4607       // cond true: move src => dst
   4608       switch (i->Pin.CMov.src->tag) {
   4609       case Pri_Imm:
   4610          imm_src = i->Pin.CMov.src->Pri.Imm;
   4611          p = mkLoadImm(p, r_dst, imm_src, mode64, endness_host);  // p += 4|8|20
   4612          break;
   4613       case Pri_Reg:
   4614          r_src = iregEnc(i->Pin.CMov.src->Pri.Reg, mode64);
   4615          p = mkMoveReg(p, r_dst, r_src, endness_host);            // p += 4
   4616          break;
   4617       default: goto bad;
   4618       }
   4619 
   4620       /* Fix up the conditional jump, if there was one. */
   4621       if (cond.test != Pct_ALWAYS) {
   4622          Int delta = p - ptmp;
   4623          vassert(delta >= 8 && delta <= 24);
   4624          /* bc !ct,cf,delta */
   4625          mkFormB(ptmp, invertCondTest(cond.test),
   4626                  cond.flag, (delta>>2), 0, 0, endness_host);
   4627       }
   4628       goto done;
   4629    }
   4630 
   4631    case Pin_Load: {
   4632       PPCAMode* am_addr = i->Pin.Load.src;
   4633       UInt r_dst = iregEnc(i->Pin.Load.dst, mode64);
   4634       UInt opc1, opc2, sz = i->Pin.Load.sz;
   4635       switch (am_addr->tag) {
   4636       case Pam_IR:
   4637          if (mode64 && (sz == 4 || sz == 8)) {
   4638             /* should be guaranteed to us by iselWordExpr_AMode */
   4639             vassert(0 == (am_addr->Pam.IR.index & 3));
   4640          }
   4641          switch(sz) {
   4642             case 1:  opc1 = 34; break;
   4643             case 2:  opc1 = 40; break;
   4644             case 4:  opc1 = 32; break;
   4645             case 8:  opc1 = 58; vassert(mode64); break;
   4646             default: goto bad;
   4647          }
   4648          p = doAMode_IR(p, opc1, r_dst, am_addr, mode64, endness_host);
   4649          goto done;
   4650       case Pam_RR:
   4651          switch(sz) {
   4652             case 1:  opc2 = 87;  break;
   4653             case 2:  opc2 = 279; break;
   4654             case 4:  opc2 = 23;  break;
   4655             case 8:  opc2 = 21; vassert(mode64); break;
   4656             default: goto bad;
   4657          }
   4658          p = doAMode_RR(p, 31, opc2, r_dst, am_addr, mode64, endness_host);
   4659          goto done;
   4660       default:
   4661          goto bad;
   4662       }
   4663    }
   4664 
   4665    case Pin_LoadL: {
   4666       if (i->Pin.LoadL.sz == 1) {
   4667          p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64),
   4668                      0, iregEnc(i->Pin.LoadL.src, mode64), 52, 0, endness_host);
   4669          goto done;
   4670       }
   4671       if (i->Pin.LoadL.sz == 2) {
   4672          p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64),
   4673                      0, iregEnc(i->Pin.LoadL.src, mode64), 116, 0, endness_host);
   4674          goto done;
   4675       }
   4676       if (i->Pin.LoadL.sz == 4) {
   4677          p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64),
   4678                      0, iregEnc(i->Pin.LoadL.src, mode64), 20, 0, endness_host);
   4679          goto done;
   4680       }
   4681       if (i->Pin.LoadL.sz == 8 && mode64) {
   4682          p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64),
   4683                      0, iregEnc(i->Pin.LoadL.src, mode64), 84, 0, endness_host);
   4684          goto done;
   4685       }
   4686       goto bad;
   4687    }
   4688 
   4689    case Pin_Set: {
   4690       /* Make the destination register be 1 or 0, depending on whether
   4691          the relevant condition holds. */
   4692       UInt        r_dst = iregEnc(i->Pin.Set.dst, mode64);
   4693       PPCCondCode cond  = i->Pin.Set.cond;
   4694       UInt rot_imm, r_tmp;
   4695 
   4696       if (cond.test == Pct_ALWAYS) {
   4697          // Just load 1 to dst => li dst,1
   4698          p = mkFormD(p, 14, r_dst, 0, 1, endness_host);
   4699       } else {
   4700          vassert(cond.flag != Pcf_NONE);
   4701          rot_imm = 1 + cond.flag;
   4702          r_tmp = 0;  // Not set in getAllocable, so no need to declare.
   4703 
   4704          // r_tmp = CR  => mfcr r_tmp
   4705          p = mkFormX(p, 31, r_tmp, 0, 0, 19, 0, endness_host);
   4706 
   4707          // r_dst = flag (rotate left and mask)
   4708          //  => rlwinm r_dst,r_tmp,rot_imm,31,31
   4709          p = mkFormM(p, 21, r_tmp, r_dst, rot_imm, 31, 31, 0, endness_host);
   4710 
   4711          if (cond.test == Pct_FALSE) {
   4712             // flip bit  => xori r_dst,r_dst,1
   4713             p = mkFormD(p, 26, r_dst, r_dst, 1, endness_host);
   4714          }
   4715       }
   4716       goto done;
   4717    }
   4718 
   4719    case Pin_MfCR:
   4720       // mfcr dst
   4721       p = mkFormX(p, 31, iregEnc(i->Pin.MfCR.dst, mode64), 0, 0, 19, 0,
   4722                   endness_host);
   4723       goto done;
   4724 
   4725    case Pin_MFence: {
   4726       p = mkFormX(p, 31, 0, 0, 0, 598, 0, endness_host);   // sync, PPC32 p616
   4727       // CAB: Should this be isync?
   4728       //    p = mkFormXL(p, 19, 0, 0, 0, 150, 0);  // isync, PPC32 p467
   4729       goto done;
   4730    }
   4731 
   4732    case Pin_Store: {
   4733       PPCAMode* am_addr = i->Pin.Store.dst;
   4734       UInt r_src = iregEnc(i->Pin.Store.src, mode64);
   4735       UInt opc1, opc2, sz = i->Pin.Store.sz;
   4736       switch (i->Pin.Store.dst->tag) {
   4737       case Pam_IR:
   4738          if (mode64 && (sz == 4 || sz == 8)) {
   4739             /* should be guaranteed to us by iselWordExpr_AMode */
   4740             vassert(0 == (am_addr->Pam.IR.index & 3));
   4741          }
   4742          switch(sz) {
   4743          case 1: opc1 = 38; break;
   4744          case 2: opc1 = 44; break;
   4745          case 4: opc1 = 36; break;
   4746          case 8: vassert(mode64);
   4747                  opc1 = 62; break;
   4748          default:
   4749             goto bad;
   4750          }
   4751          p = doAMode_IR(p, opc1, r_src, am_addr, mode64, endness_host);
   4752          goto done;
   4753       case Pam_RR:
   4754          switch(sz) {
   4755          case 1: opc2 = 215; break;
   4756          case 2: opc2 = 407; break;
   4757          case 4: opc2 = 151; break;
   4758          case 8: vassert(mode64);
   4759                  opc2 = 149; break;
   4760          default:
   4761             goto bad;
   4762          }
   4763          p = doAMode_RR(p, 31, opc2, r_src, am_addr, mode64, endness_host);
   4764          goto done;
   4765       default:
   4766          goto bad;
   4767       }
   4768       goto done;
   4769    }
   4770 
   4771    case Pin_StoreC: {
   4772       if (i->Pin.StoreC.sz == 1) {
   4773          p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64),
   4774                      0, iregEnc(i->Pin.StoreC.dst, mode64), 694, 1, endness_host);
   4775          goto done;
   4776       }
   4777       if (i->Pin.StoreC.sz == 2) {
   4778          p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64),
   4779                      0, iregEnc(i->Pin.StoreC.dst, mode64), 726, 1, endness_host);
   4780          goto done;
   4781       }
   4782 
   4783       if (i->Pin.StoreC.sz == 4) {
   4784          p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64),
   4785                      0, iregEnc(i->Pin.StoreC.dst, mode64), 150, 1, endness_host);
   4786          goto done;
   4787       }
   4788       if (i->Pin.StoreC.sz == 8 && mode64) {
   4789          p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64),
   4790                      0, iregEnc(i->Pin.StoreC.dst, mode64), 214, 1, endness_host);
   4791          goto done;
   4792       }
   4793       goto bad;
   4794    }
   4795 
   4796    case Pin_FpUnary: {
   4797       UInt fr_dst = fregEnc(i->Pin.FpUnary.dst);
   4798       UInt fr_src = fregEnc(i->Pin.FpUnary.src);
   4799       switch (i->Pin.FpUnary.op) {
   4800       case Pfp_RSQRTE: // frsqrtre, PPC32 p424
   4801          p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 26, 0, endness_host );
   4802          break;
   4803       case Pfp_RES:   // fres, PPC32 p421
   4804          p = mkFormA( p, 59, fr_dst, 0, fr_src, 0, 24, 0, endness_host );
   4805          break;
   4806       case Pfp_SQRT:  // fsqrt, PPC32 p427
   4807          p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 22, 0, endness_host );
   4808          break;
   4809       case Pfp_ABS:   // fabs, PPC32 p399
   4810          p = mkFormX(p, 63, fr_dst, 0, fr_src, 264, 0, endness_host);
   4811          break;
   4812       case Pfp_NEG:   // fneg, PPC32 p416
   4813          p = mkFormX(p, 63, fr_dst, 0, fr_src, 40, 0, endness_host);
   4814          break;
   4815       case Pfp_MOV:   // fmr, PPC32 p410
   4816          p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0, endness_host);
   4817          break;
   4818       case Pfp_FRIM:  // frim, PPC ISA 2.05 p137
   4819          p = mkFormX(p, 63, fr_dst, 0, fr_src, 488, 0, endness_host);
   4820          break;
   4821       case Pfp_FRIP:  // frip, PPC ISA 2.05 p137
   4822          p = mkFormX(p, 63, fr_dst, 0, fr_src, 456, 0, endness_host);
   4823          break;
   4824       case Pfp_FRIN:  // frin, PPC ISA 2.05 p137
   4825          p = mkFormX(p, 63, fr_dst, 0, fr_src, 392, 0, endness_host);
   4826          break;
   4827       case Pfp_FRIZ:  // friz, PPC ISA 2.05 p137
   4828          p = mkFormX(p, 63, fr_dst, 0, fr_src, 424, 0, endness_host);
   4829          break;
   4830       default:
   4831          goto bad;
   4832       }
   4833       goto done;
   4834    }
   4835 
   4836    case Pin_FpBinary: {
   4837       UInt fr_dst  = fregEnc(i->Pin.FpBinary.dst);
   4838       UInt fr_srcL = fregEnc(i->Pin.FpBinary.srcL);
   4839       UInt fr_srcR = fregEnc(i->Pin.FpBinary.srcR);
   4840       switch (i->Pin.FpBinary.op) {
   4841       case Pfp_ADDD:   // fadd, PPC32 p400
   4842          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 21, 0, endness_host );
   4843          break;
   4844       case Pfp_ADDS:   // fadds, PPC32 p401
   4845          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 21, 0, endness_host );
   4846          break;
   4847       case Pfp_SUBD:   // fsub, PPC32 p429
   4848          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 20, 0, endness_host );
   4849          break;
   4850       case Pfp_SUBS:   // fsubs, PPC32 p430
   4851          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 20, 0, endness_host );
   4852          break;
   4853       case Pfp_MULD:   // fmul, PPC32 p413
   4854          p = mkFormA( p, 63, fr_dst, fr_srcL, 0, fr_srcR, 25, 0, endness_host );
   4855          break;
   4856       case Pfp_MULS:   // fmuls, PPC32 p414
   4857          p = mkFormA( p, 59, fr_dst, fr_srcL, 0, fr_srcR, 25, 0, endness_host );
   4858          break;
   4859       case Pfp_DIVD:   // fdiv, PPC32 p406
   4860          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 18, 0, endness_host );
   4861          break;
   4862       case Pfp_DIVS:   // fdivs, PPC32 p407
   4863          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 18, 0, endness_host );
   4864          break;
   4865       default:
   4866          goto bad;
   4867       }
   4868       goto done;
   4869    }
   4870 
   4871    case Pin_Fp128Unary: {
   4872       /* Note Fp128 instructions use the vector scalar registers.  The register
   4873        * mapping for the V128 type assumes the a vector instruction.  The
   4874        * PPC hardware has a single register file that the vector scalar
   4875        * registers and the vector registers map to.  The 32 vector
   4876        * registers instructions map to the same registers as the vector
   4877        * scalar registers 32 to 63.  mkFormVXR0 does the needed
   4878        * adjustment.
   4879       */
   4880       UInt fr_dst = vregEnc(i->Pin.Fp128Unary.dst);
   4881       UInt fr_src = vregEnc(i->Pin.Fp128Unary.src);
   4882 
   4883       switch (i->Pin.Fp128Unary.op) {
   4884       case Pfp_FPSQRTQ:         // xssqrtqp, use rounding specified by RN
   4885          p = mkFormVXR0( p, 63, fr_dst, 27, fr_src, 804, 0, endness_host );
   4886          break;
   4887       case Pfp_FPSQRTQRNDODD:   // xssqrtqpo, use rounding specified by RN
   4888          p = mkFormVXR0( p, 63, fr_dst, 27, fr_src, 804, 1, endness_host );
   4889          break;
   4890       case Pfp_FPQTOD:         // xscvqpdp, use rounding specified by RN
   4891          p = mkFormVXR0( p, 63, fr_dst, 20, fr_src, 836, 0, endness_host );
   4892          break;
   4893       case Pfp_FPQTODRNDODD:   // xscvqpdpo, use rounding specified by RN
   4894          p = mkFormVXR0( p, 63, fr_dst, 20, fr_src, 836, 1, endness_host );
   4895         break;
   4896       case Pfp_FPDTOQ:         // xscvdpqp
   4897          p = mkFormVXR0( p, 63, fr_dst, 22, fr_src, 836, 0, endness_host );
   4898          break;
   4899       case Pfp_IDSTOQ:         // xscvsdqp
   4900          p = mkFormVXR0( p, 63, fr_dst, 10, fr_src, 836, 0, endness_host );
   4901          break;
   4902       case Pfp_IDUTOQ:         // xscvudqp
   4903          p = mkFormVXR0( p, 63, fr_dst, 2, fr_src, 836, 0, endness_host );
   4904          break;
   4905       case Pfp_TRUNCFPQTOISD:   // xscvqpsdz
   4906          p = mkFormVXR0( p, 63, fr_dst, 25, fr_src, 836, 0, endness_host );
   4907          break;
   4908      case Pfp_TRUNCFPQTOISW:   // xscvqpswz
   4909          p = mkFormVXR0( p, 63, fr_dst, 9, fr_src, 836, 0, endness_host );
   4910          break;
   4911      case Pfp_TRUNCFPQTOIUD:   // xscvqpudz
   4912          p = mkFormVXR0( p, 63, fr_dst, 17, fr_src, 836, 0, endness_host );
   4913          break;
   4914       case Pfp_TRUNCFPQTOIUW:   // xscvqpuwz
   4915          p = mkFormVXR0( p, 63, fr_dst, 1, fr_src, 836, 0, endness_host );
   4916          break;
   4917       default:
   4918 	 goto bad;
   4919       }
   4920       goto done;
   4921    }
   4922 
   4923    case Pin_Fp128Binary: {
   4924       /* Note Fp128 instructions use the vector registers */
   4925       UInt fr_dst  = vregEnc(i->Pin.Fp128Binary.dst);
   4926       UInt fr_srcL = vregEnc(i->Pin.Fp128Binary.srcL);
   4927       UInt fr_srcR = vregEnc(i->Pin.Fp128Binary.srcR);
   4928 
   4929       /* Note this issues a Vector scalar instruction.  The register
   4930        * mapping for the V128 type assumes the a vector instruction.  The
   4931        * PPC hardware has a single register file that the vector scalar
   4932        * registers and the vector registers map to.  The 32 vector
   4933        * registers instructions map to the same registers as the vector
   4934        * scalar registers 32 to 63.  For these instructions the HW adds
   4935        * 32 to the register numbers to access the VSRR register.  No need
   4936        * to adjust the numbers to map to the VR register that contians the
   4937        * operands.
   4938        */
   4939 
   4940       switch (i->Pin.Fp128Binary.op) {
   4941       case Pfp_FPADDQ:         // xsaddqp, use rounding specified by RN
   4942          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 4, 0, endness_host );
   4943          break;
   4944       case Pfp_FPADDQRNDODD:   // xsaddqpo, round to odd
   4945          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 4, 1, endness_host );
   4946          break;
   4947       case Pfp_FPSUBQ:         // xssubqp, use rounding specified by RN
   4948          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 516, 0, endness_host );
   4949          break;
   4950       case Pfp_FPSUBQRNDODD:   // xssubqpo, round to odd
   4951          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 516, 1, endness_host );
   4952          break;
   4953       case Pfp_FPMULQ:         // xsmulqp, use rounding specified by RN
   4954          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 36, 0, endness_host );
   4955          break;
   4956       case Pfp_FPMULQRNDODD:   // xsmulqpo, round to odd
   4957          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 36, 1, endness_host );
   4958          break;
   4959       case Pfp_FPDIVQ:         // xsdivqp, use rounding specified by RN
   4960          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 548, 0, endness_host );
   4961          break;
   4962       case Pfp_FPDIVQRNDODD:   // xsdivqpo, round to odd
   4963          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 548, 1, endness_host );
   4964          break;
   4965       case Pfp_FPMULADDQ:      // xsmaddqp, use rounding specified by RN
   4966          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 388, 0, endness_host );
   4967          break;
   4968       case Pfp_FPMULADDQRNDODD:   // xsmaddqpo, round to odd
   4969          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 388, 1, endness_host );
   4970          break;
   4971       case Pfp_FPMULSUBQ:         // xsmsubqp, use rounding specified by RN
   4972          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 420, 0, endness_host );
   4973          break;
   4974       case Pfp_FPMULSUBQRNDODD:   // xsmsubsqpo, round to odd
   4975          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 420, 1, endness_host );
   4976          break;
   4977       case Pfp_FPNEGMULADDQ:      // xsnmaddqp, use rounding specified by RN
   4978          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 452, 0, endness_host );
   4979          break;
   4980       case Pfp_FPNEGMULADDQRNDODD:   // xsnmaddqpo, round to odd
   4981          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 452, 1, endness_host );
   4982          break;
   4983       case Pfp_FPNEGMULSUBQ:         // xsnmsubqp, use rounding specified by RN
   4984          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 484, 0, endness_host );
   4985          break;
   4986       case Pfp_FPNEGMULSUBQRNDODD:   // xsnmsubsqpo, round to odd
   4987          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 484, 1, endness_host );
   4988          break;
   4989      default:
   4990           goto bad;
   4991       }
   4992       goto done;
   4993    }
   4994 
   4995    case Pin_Fp128Trinary: {
   4996       /* Note Fp128 instructions use the vector registers */
   4997       UInt fr_dst  = vregEnc(i->Pin.Fp128Binary.dst);
   4998       UInt fr_srcL = vregEnc(i->Pin.Fp128Binary.srcL);
   4999       UInt fr_srcR = vregEnc(i->Pin.Fp128Binary.srcR);
   5000 
   5001       /* Note this issues a Vector scalar instruction.  The register
   5002        * mapping for the V128 type assumes the a vector instruction.  The
   5003        * PPC hardware has a single register file that the vector scalar
   5004        * registers and the vector registers map to.  The 32 vector
   5005        * registers instructions map to the same registers as the vector
   5006        * scalar registers 32 to 63.  For these instructions the HW adds
   5007        * 32 to the register numbers to access the VSRR register.  No need
   5008        * to adjust the numbers to map to the VR register that contians the
   5009        * operands.
   5010        */
   5011 
   5012       switch (i->Pin.Fp128Binary.op) {
   5013       case Pfp_FPMULADDQ:      // xsmaddqp, use rounding specified by RN
   5014          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 388, 0, endness_host );
   5015          break;
   5016       case Pfp_FPMULADDQRNDODD:   // xsmaddqpo, round to odd
   5017          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 388, 1, endness_host );
   5018          break;
   5019       case Pfp_FPMULSUBQ:         // xsmsubqp, use rounding specified by RN
   5020          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 420, 0, endness_host );
   5021          break;
   5022       case Pfp_FPMULSUBQRNDODD:   // xsmsubsqpo, round to odd
   5023          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 420, 1, endness_host );
   5024          break;
   5025       case Pfp_FPNEGMULADDQ:      // xsnmaddqp, use rounding specified by RN
   5026          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 452, 0, endness_host );
   5027          break;
   5028       case Pfp_FPNEGMULADDQRNDODD:   // xsnmaddqpo, round to odd
   5029          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 452, 1, endness_host );
   5030          break;
   5031       case Pfp_FPNEGMULSUBQ:         // xsnmsubqp, use rounding specified by RN
   5032         p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 484, 0, endness_host );
   5033          break;
   5034       case Pfp_FPNEGMULSUBQRNDODD:   // xsnmsubsqpo, round to odd
   5035          p = mkFormVXR0( p, 63, fr_dst, fr_srcL, fr_srcR, 484, 1, endness_host );
   5036          break;
   5037       default:
   5038           goto bad;
   5039       }
   5040       goto done;
   5041    }
   5042 
   5043    case Pin_FpMulAcc: {
   5044       UInt fr_dst    = fregEnc(i->Pin.FpMulAcc.dst);
   5045       UInt fr_srcML  = fregEnc(i->Pin.FpMulAcc.srcML);
   5046       UInt fr_srcMR  = fregEnc(i->Pin.FpMulAcc.srcMR);
   5047       UInt fr_srcAcc = fregEnc(i->Pin.FpMulAcc.srcAcc);
   5048       switch (i->Pin.FpMulAcc.op) {
   5049       case Pfp_MADDD:   // fmadd, PPC32 p408
   5050          p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0,
   5051                       endness_host );
   5052          break;
   5053       case Pfp_MADDS:   // fmadds, PPC32 p409
   5054          p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0,
   5055                       endness_host );
   5056          break;
   5057       case Pfp_MSUBD:   // fmsub, PPC32 p411
   5058          p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0,
   5059                       endness_host );
   5060          break;
   5061       case Pfp_MSUBS:   // fmsubs, PPC32 p412
   5062          p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0,
   5063                       endness_host );
   5064          break;
   5065       default:
   5066          goto bad;
   5067       }
   5068       goto done;
   5069    }
   5070 
   5071    case Pin_FpLdSt: {
   5072       PPCAMode* am_addr = i->Pin.FpLdSt.addr;
   5073       UInt f_reg = fregEnc(i->Pin.FpLdSt.reg);
   5074       Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR);
   5075       UChar sz = i->Pin.FpLdSt.sz;
   5076       UInt opc;
   5077       vassert(sz == 4 || sz == 8);
   5078 
   5079       if (i->Pin.FpLdSt.isLoad) {   // Load from memory
   5080          if (idxd) {  // lf[s|d]x, PPC32 p444|440
   5081             opc = (sz == 4) ? 535 : 599;
   5082             p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64, endness_host);
   5083          } else {     // lf[s|d], PPC32 p441|437
   5084             opc = (sz == 4) ? 48 : 50;
   5085             p = doAMode_IR(p, opc, f_reg, am_addr, mode64, endness_host);
   5086          }
   5087       } else {                      // Store to memory
   5088          if (idxd) { // stf[s|d]x, PPC32 p521|516
   5089             opc = (sz == 4) ? 663 : 727;
   5090             p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64, endness_host);
   5091          } else {    // stf[s|d], PPC32 p518|513
   5092             opc = (sz == 4) ? 52 : 54;
   5093             p = doAMode_IR(p, opc, f_reg, am_addr, mode64, endness_host);
   5094          }
   5095       }
   5096       goto done;
   5097    }
   5098 
   5099    case Pin_FpSTFIW: {
   5100       UInt ir_addr = iregEnc(i->Pin.FpSTFIW.addr, mode64);
   5101       UInt fr_data = fregEnc(i->Pin.FpSTFIW.data);
   5102       // stfiwx (store fp64[lo32] as int32), PPC32 p517
   5103       // Use rA==0, so that EA == rB == ir_addr
   5104       p = mkFormX(p, 31, fr_data, 0/*rA=0*/, ir_addr, 983, 0, endness_host);
   5105       goto done;
   5106    }
   5107 
   5108    case Pin_FpRSP: {
   5109       UInt fr_dst = fregEnc(i->Pin.FpRSP.dst);
   5110       UInt fr_src = fregEnc(i->Pin.FpRSP.src);
   5111       // frsp, PPC32 p423
   5112       p = mkFormX(p, 63, fr_dst, 0, fr_src, 12, 0, endness_host);
   5113       goto done;
   5114    }
   5115 
   5116    case Pin_FpCftI: {
   5117       UInt fr_dst = fregEnc(i->Pin.FpCftI.dst);
   5118       UInt fr_src = fregEnc(i->Pin.FpCftI.src);
   5119       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True) {
   5120          if (i->Pin.FpCftI.syned == True) {
   5121             // fctiw (conv f64 to i32), PPC32 p404
   5122             p = mkFormX(p, 63, fr_dst, 0, fr_src, 14, 0, endness_host);
   5123             goto done;
   5124          } else {
   5125             // fctiwu (conv f64 to u32)
   5126             p = mkFormX(p, 63, fr_dst, 0, fr_src, 142, 0, endness_host);
   5127             goto done;
   5128          }
   5129       }
   5130       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False) {
   5131          if (i->Pin.FpCftI.syned == True) {
   5132             // fctid (conv f64 to i64), PPC64 p437
   5133             p = mkFormX(p, 63, fr_dst, 0, fr_src, 814, 0, endness_host);
   5134             goto done;
   5135          } else {
   5136             // fctidu (conv f64 to u64)
   5137             p = mkFormX(p, 63, fr_dst, 0, fr_src, 942, 0, endness_host);
   5138             goto done;
   5139          }
   5140       }
   5141       if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
   5142          if (i->Pin.FpCftI.syned == True) {
   5143             // fcfid (conv i64 to f64), PPC64 p434
   5144             p = mkFormX(p, 63, fr_dst, 0, fr_src, 846, 0, endness_host);
   5145             goto done;
   5146          } else if (i->Pin.FpCftI.flt64 == True) {
   5147             // fcfidu (conv u64 to f64)
   5148             p = mkFormX(p, 63, fr_dst, 0, fr_src, 974, 0, endness_host);
   5149             goto done;
   5150          } else {
   5151             // fcfidus (conv u64 to f32)
   5152             p = mkFormX(p, 59, fr_dst, 0, fr_src, 974, 0, endness_host);
   5153             goto done;
   5154          }
   5155       }
   5156       goto bad;
   5157    }
   5158 
   5159    case Pin_FpCMov: {
   5160       UInt        fr_dst = fregEnc(i->Pin.FpCMov.dst);
   5161       UInt        fr_src = fregEnc(i->Pin.FpCMov.src);
   5162       PPCCondCode cc     = i->Pin.FpCMov.cond;
   5163 
   5164       if (fr_dst == fr_src) goto done;
   5165 
   5166       vassert(cc.test != Pct_ALWAYS);
   5167 
   5168       /* jmp fwds if !condition */
   5169       if (cc.test != Pct_ALWAYS) {
   5170          /* bc !ct,cf,n_bytes>>2 */
   5171          p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0,
   5172                      endness_host);
   5173       }
   5174 
   5175       // fmr, PPC32 p410
   5176       p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0, endness_host);
   5177       goto done;
   5178    }
   5179 
   5180    case Pin_FpLdFPSCR: {
   5181       UInt fr_src = fregEnc(i->Pin.FpLdFPSCR.src);
   5182       p = mkFormXFL(p, 0xFF, fr_src, i->Pin.FpLdFPSCR.dfp_rm, endness_host); // mtfsf, PPC32 p480
   5183       goto done;
   5184    }
   5185 
   5186    case Pin_FpCmp: {
   5187       UChar crfD    = 1;
   5188       UInt  r_dst   = iregEnc(i->Pin.FpCmp.dst, mode64);
   5189       UInt  fr_srcL = fregEnc(i->Pin.FpCmp.srcL);
   5190       UInt  fr_srcR = fregEnc(i->Pin.FpCmp.srcR);
   5191       vassert(crfD < 8);
   5192       // fcmpo, PPC32 p402
   5193       p = mkFormX(p, 63, crfD<<2, fr_srcL, fr_srcR, 32, 0, endness_host);
   5194 
   5195       // mfcr (mv CR to r_dst), PPC32 p467
   5196       p = mkFormX(p, 31, r_dst, 0, 0, 19, 0, endness_host);
   5197 
   5198       // rlwinm r_dst,r_dst,8,28,31, PPC32 p501
   5199       //  => rotate field 1 to bottomw of word, masking out upper 28
   5200       p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0, endness_host);
   5201       goto done;
   5202    }
   5203 
   5204    case Pin_RdWrLR: {
   5205       UInt reg = iregEnc(i->Pin.RdWrLR.gpr, mode64);
   5206       /* wrLR==True ? mtlr r4 : mflr r4 */
   5207       p = mkFormXFX(p, reg, 8, (i->Pin.RdWrLR.wrLR==True) ? 467 : 339,
   5208                     endness_host);
   5209       goto done;
   5210    }
   5211 
   5212 
   5213    /* AltiVec */
   5214    case Pin_AvLdSt: {
   5215       UInt opc2, v_reg, r_idx, r_base;
   5216       UChar sz   = i->Pin.AvLdSt.sz;
   5217       Bool  idxd = toBool(i->Pin.AvLdSt.addr->tag == Pam_RR);
   5218       vassert(sz == 1 || sz == 2 || sz == 4 || sz == 16);
   5219 
   5220       v_reg  = vregEnc(i->Pin.AvLdSt.reg);
   5221       r_base = iregEnc(i->Pin.AvLdSt.addr->Pam.RR.base, mode64);
   5222 
   5223       // Only have AltiVec AMode_RR: kludge AMode_IR
   5224       if (!idxd) {
   5225          r_idx = 30;                       // XXX: Using r30 as temp
   5226          p = mkLoadImm(p, r_idx,
   5227                        i->Pin.AvLdSt.addr->Pam.IR.index, mode64, endness_host);
   5228       } else {
   5229          r_idx  = iregEnc(i->Pin.AvLdSt.addr->Pam.RR.index, mode64);
   5230       }
   5231 
   5232       if (i->Pin.FpLdSt.isLoad) {  // Load from memory (1,2,4,16)
   5233          opc2 = (sz==1) ?   7 : (sz==2) ?  39 : (sz==4) ?  71 : 103;
   5234          p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0, endness_host);
   5235       } else {                      // Store to memory (1,2,4,16)
   5236          opc2 = (sz==1) ? 135 : (sz==2) ? 167 : (sz==4) ? 199 : 231;
   5237          p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0, endness_host);
   5238       }
   5239       goto done;
   5240    }
   5241 
   5242    case Pin_AvUnary: {
   5243       UInt v_dst = vregEnc(i->Pin.AvUnary.dst);
   5244       UInt v_src = vregEnc(i->Pin.AvUnary.src);
   5245       UInt opc2 = 0xFFFFFFFF, opc3 = 0xFFFFFFFF; /* invalid */
   5246 
   5247       switch (i->Pin.AvUnary.op) {
   5248       case Pav_MOV:       opc2 = 1156; break; // vor vD,vS,vS
   5249       case Pav_NOT:       opc2 = 1284; break; // vnor vD,vS,vS
   5250       case Pav_UNPCKH8S:  opc2 =  526; break; // vupkhsb
   5251       case Pav_UNPCKH16S: opc2 =  590; break; // vupkhsh
   5252       case Pav_UNPCKL8S:  opc2 =  654; break; // vupklsb
   5253       case Pav_UNPCKL16S: opc2 =  718; break; // vupklsh
   5254       case Pav_UNPCKHPIX: opc2 =  846; break; // vupkhpx
   5255       case Pav_UNPCKLPIX: opc2 =  974; break; // vupklpx
   5256 
   5257       case Pav_ZEROCNTBYTE: opc2 = 1794; break; // vclzb
   5258       case Pav_ZEROCNTHALF: opc2 = 1858; break; // vclzh
   5259       case Pav_ZEROCNTWORD: opc2 = 1922; break; // vclzw
   5260       case Pav_ZEROCNTDBL:  opc2 = 1986; break; // vclzd
   5261       case Pav_TRAILINGZEROCNTBYTE: opc2 = 1538; break; // vctzb
   5262       case Pav_TRAILINGZEROCNTHALF: opc2 = 1538; break; // vctzh
   5263       case Pav_TRAILINGZEROCNTWORD: opc2 = 1538; break; // vctzw
   5264       case Pav_TRAILINGZEROCNTDBL:  opc2 = 1538; break; // vctzd
   5265       case Pav_BITMTXXPOSE: opc2 = 1292; break; // vgbbd
   5266       case Pav_BCD128toI128S: opc2 = 385; break; //bcdctsq.
   5267       case Pav_MulI128by10:      opc2 = 513; break; // vmul10uq
   5268       case Pav_MulI128by10Carry: opc2 =   1; break; // vmul10cuq
   5269       case Pav_F16toF64x2: opc2 = 347; opc3 = 16; break; // xvcvhpdp
   5270       case Pav_F64toF16x2: opc2 = 347; opc3 = 17; break; // xvcvdphp
   5271       case Pav_F16toF32x4: opc2 = 475; opc3 = 24; break; // xvcvhpsp
   5272       case Pav_F32toF16x4: opc2 = 475; opc3 = 25; break; // xvcvsphp
   5273 
   5274       default:
   5275          goto bad;
   5276       }
   5277       switch (i->Pin.AvUnary.op) {
   5278       case Pav_MOV:
   5279       case Pav_NOT:
   5280          p = mkFormVX( p, 4, v_dst, v_src, v_src, opc2, endness_host );
   5281          break;
   5282       case Pav_F16toF32x4:
   5283          {
   5284             /* I64 source has four 16-bit float values in the upper 64-bit
   5285              * of the source vector register, lower 64-bits are undefined.
   5286              */
   5287             /* Scatter the four F16 values in the Vector register */
   5288             p = mkFormVX( p, 4, v_dst, 0, v_src, 590, endness_host );// vupkhsh
   5289 
   5290             /* The layout of the vector register is now: S0F0 S1F1 S2F2 S3F3
   5291              * where S is the sign extension of the 16-bit F value.  We don't
   5292              * care about the extended signs.
   5293              */
   5294 
   5295             /* Input, in v_dst, is now correct for the xvcvhpsp instruction */
   5296             p = mkFormVX_BX_TX( p, 60, v_dst, opc3, v_dst, opc2,
   5297                                 endness_host );
   5298          }
   5299          break;
   5300       case Pav_F64toF16x2:
   5301       case Pav_F16toF64x2:
   5302       case Pav_F32toF16x4:
   5303          /* Note this issues a Vector scalar instruction.  The register
   5304           * mapping for the V128 type assumes the a vector instruction.  The
   5305           * PPC hardware has a single register file that the vector scalar
   5306           * registers and the vector registers map to.  The 32 vector registers
   5307           * instructions map to the same registers as the vector scalar
   5308           * registers 32 to 63.  mkFormVX_BX_TX does the needed adjustment.
   5309           */
   5310          p = mkFormVX_BX_TX( p, 60, v_dst, opc3, v_src, opc2, endness_host );
   5311          break;
   5312       case Pav_BCD128toI128S:  // bcdctsq
   5313          p = mkFormVX( p, 4, v_dst, 0, v_src, (1<<10 | 385), endness_host );
   5314          break;
   5315       case Pav_MulI128by10:
   5316       case Pav_MulI128by10Carry:
   5317          p = mkFormVX( p, 4, v_dst, v_src, 0, opc2, endness_host );
   5318          break;
   5319       case Pav_TRAILINGZEROCNTBYTE:
   5320          p = mkFormVX( p, 4, v_dst, 28, v_src, opc2, endness_host );
   5321          break;
   5322       case Pav_TRAILINGZEROCNTHALF:
   5323          p = mkFormVX( p, 4, v_dst, 29, v_src, opc2, endness_host );
   5324          break;
   5325       case Pav_TRAILINGZEROCNTWORD:
   5326          p = mkFormVX( p, 4, v_dst, 30, v_src, opc2, endness_host );
   5327          break;
   5328       case Pav_TRAILINGZEROCNTDBL:
   5329          p = mkFormVX( p, 4, v_dst, 31, v_src, opc2, endness_host );
   5330          break;
   5331       default:
   5332          p = mkFormVX( p, 4, v_dst, 0, v_src, opc2, endness_host );
   5333          break;
   5334       }
   5335       goto done;
   5336    }
   5337 
   5338    case Pin_AvBinary: {
   5339       UInt v_dst  = vregEnc(i->Pin.AvBinary.dst);
   5340       UInt v_srcL = vregEnc(i->Pin.AvBinary.srcL);
   5341       UInt v_srcR = vregEnc(i->Pin.AvBinary.srcR);
   5342       UInt opc2;
   5343       if (i->Pin.AvBinary.op == Pav_SHL) {
   5344          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1036, endness_host ); // vslo
   5345          p = mkFormVX( p, 4, v_dst, v_dst,  v_srcR, 452, endness_host );  // vsl
   5346          goto done;
   5347       }
   5348       if (i->Pin.AvBinary.op == Pav_SHR) {
   5349          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1100, endness_host ); // vsro
   5350          p = mkFormVX( p, 4, v_dst, v_dst,  v_srcR, 708, endness_host );  // vsr
   5351          goto done;
   5352       }
   5353       switch (i->Pin.AvBinary.op) {
   5354       /* Bitwise */
   5355       case Pav_AND:       opc2 = 1028; break; // vand
   5356       case Pav_OR:        opc2 = 1156; break; // vor
   5357       case Pav_XOR:       opc2 = 1220; break; // vxor
   5358       /* Mult by 10 */
   5359       case Pav_MulI128by10E:      opc2 = 577; break; // vmul10euq
   5360       case Pav_MulI128by10ECarry: opc2 =  65; break; // vmul10ecuq
   5361       default:
   5362          goto bad;
   5363       }
   5364       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host );
   5365       goto done;
   5366    }
   5367 
   5368    case Pin_AvBinaryInt: {
   5369        UInt   ps = i->Pin.AvBinaryInt.val->Pri.Imm;
   5370        UInt   dst = vregEnc(i->Pin.AvBinaryInt.dst);
   5371        UInt   src = vregEnc(i->Pin.AvBinaryInt.src);
   5372 
   5373        switch (i->Pin.AvBinaryInt.op) {
   5374        /* BCD */
   5375        case Pav_I128StoBCD128:   // bcdcfsq
   5376           {
   5377               /* v_srcR actually contains the value of the one-bit ps field */
   5378               int opc2 = 385;
   5379               p = mkFormVX( p, 4, dst, 2, src,
   5380                             (1 << 10 | (ps << 9) | opc2), endness_host );
   5381            }
   5382        break;
   5383 
   5384        case Pav_F128toI128S:  // xsrqpi, xsrqpix
   5385            {
   5386               int opc2 = 5;
   5387               UInt EX  = ps & 0x1;
   5388               UInt R   = (ps >> 3) & 0x1;
   5389               UInt RMC = (ps >> 1) & 0x3;
   5390               /* Note this issues a Vector scalar instruction.  The register
   5391                * mapping for the V128 type assumes the a vector instruction.  The
   5392                * PPC hardware has a single register file that the vector scalar
   5393                * registers and the vector registers map to.  The 32 vector
   5394                * registers instructions map to the same registers as the vector
   5395                * scalar registers 32 to 63.  For these instructions the HW adds
   5396                * 32 to the register numbers to access the VSRR register.  No need
   5397                * to adjust the numbers to map to the VR register that contians
   5398                * the operands.
   5399                */
   5400               p = mkFormVSXRND( p, 63, R, dst, src, RMC, opc2, EX,
   5401                                 endness_host );
   5402            }
   5403 	break;
   5404 
   5405         case Pav_ROUNDFPQ:   // xsrqpxp
   5406            {
   5407               int opc2 = 37;
   5408               UInt EX  = ps & 0x1;
   5409               UInt RMC = (ps >> 1) & 0x3;
   5410               UInt R   = (ps >> 3) & 0x1;
   5411               p = mkFormVSXRND( p, 63, R, dst, src, RMC, opc2, EX,
   5412                                 endness_host );
   5413            }
   5414 	break;
   5415 
   5416         default:
   5417            goto bad;
   5418 
   5419       }
   5420       goto done;
   5421    }
   5422 
   5423    case Pin_AvBin8x16: {
   5424       UInt v_dst  = vregEnc(i->Pin.AvBin8x16.dst);
   5425       UInt v_srcL = vregEnc(i->Pin.AvBin8x16.srcL);
   5426       UInt v_srcR = vregEnc(i->Pin.AvBin8x16.srcR);
   5427       UInt opc2;
   5428       switch (i->Pin.AvBin8x16.op) {
   5429 
   5430       case Pav_ADDU:     opc2 =    0; break; // vaddubm
   5431       case Pav_QADDU:    opc2 =  512; break; // vaddubs
   5432       case Pav_QADDS:    opc2 =  768; break; // vaddsbs
   5433 
   5434       case Pav_SUBU:     opc2 = 1024; break; // vsububm
   5435       case Pav_QSUBU:    opc2 = 1536; break; // vsububs
   5436       case Pav_QSUBS:    opc2 = 1792; break; // vsubsbs
   5437 
   5438       case Pav_OMULU:   opc2 =    8; break; // vmuloub
   5439       case Pav_OMULS:   opc2 =  264; break; // vmulosb
   5440       case Pav_EMULU:   opc2 =  520; break; // vmuleub
   5441       case Pav_EMULS:   opc2 =  776; break; // vmulesb
   5442 
   5443       case Pav_AVGU:     opc2 = 1026; break; // vavgub
   5444       case Pav_AVGS:     opc2 = 1282; break; // vavgsb
   5445       case Pav_MAXU:     opc2 =    2; break; // vmaxub
   5446       case Pav_MAXS:     opc2 =  258; break; // vmaxsb
   5447       case Pav_MINU:     opc2 =  514; break; // vminub
   5448       case Pav_MINS:     opc2 =  770; break; // vminsb
   5449 
   5450       case Pav_CMPEQU:   opc2 =    6; break; // vcmpequb
   5451       case Pav_CMPGTU:   opc2 =  518; break; // vcmpgtub
   5452       case Pav_CMPGTS:   opc2 =  774; break; // vcmpgtsb
   5453 
   5454       case Pav_SHL:      opc2 =  260; break; // vslb
   5455       case Pav_SHR:      opc2 =  516; break; // vsrb
   5456       case Pav_SAR:      opc2 =  772; break; // vsrab
   5457       case Pav_ROTL:     opc2 =    4; break; // vrlb
   5458 
   5459       case Pav_MRGHI:    opc2 =   12; break; // vmrghb
   5460       case Pav_MRGLO:    opc2 =  268; break; // vmrglb
   5461 
   5462       case Pav_POLYMULADD: opc2 = 1032; break; // vpmsumb
   5463 
   5464       default:
   5465          goto bad;
   5466       }
   5467       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host );
   5468       goto done;
   5469    }
   5470 
   5471    case Pin_AvBin16x8: {
   5472       UInt v_dst  = vregEnc(i->Pin.AvBin16x8.dst);
   5473       UInt v_srcL = vregEnc(i->Pin.AvBin16x8.srcL);
   5474       UInt v_srcR = vregEnc(i->Pin.AvBin16x8.srcR);
   5475       UInt opc2;
   5476       switch (i->Pin.AvBin16x8.op) {
   5477 
   5478       case Pav_ADDU:    opc2 =   64; break; // vadduhm
   5479       case Pav_QADDU:   opc2 =  576; break; // vadduhs
   5480       case Pav_QADDS:   opc2 =  832; break; // vaddshs
   5481 
   5482       case Pav_SUBU:    opc2 = 1088; break; // vsubuhm
   5483       case Pav_QSUBU:   opc2 = 1600; break; // vsubuhs
   5484       case Pav_QSUBS:   opc2 = 1856; break; // vsubshs
   5485 
   5486       case Pav_OMULU:   opc2 =   72; break; // vmulouh
   5487       case Pav_OMULS:   opc2 =  328; break; // vmulosh
   5488       case Pav_EMULU:   opc2 =  584; break; // vmuleuh
   5489       case Pav_EMULS:   opc2 =  840; break; // vmulesh
   5490 
   5491       case Pav_AVGU:    opc2 = 1090; break; // vavguh
   5492       case Pav_AVGS:    opc2 = 1346; break; // vavgsh
   5493       case Pav_MAXU:    opc2 =   66; break; // vmaxuh
   5494       case Pav_MAXS:    opc2 =  322; break; // vmaxsh
   5495       case Pav_MINS:    opc2 =  834; break; // vminsh
   5496       case Pav_MINU:    opc2 =  578; break; // vminuh
   5497 
   5498       case Pav_CMPEQU:  opc2 =   70; break; // vcmpequh
   5499       case Pav_CMPGTU:  opc2 =  582; break; // vcmpgtuh
   5500       case Pav_CMPGTS:  opc2 =  838; break; // vcmpgtsh
   5501 
   5502       case Pav_SHL:     opc2 =  324; break; // vslh
   5503       case Pav_SHR:     opc2 =  580; break; // vsrh
   5504       case Pav_SAR:     opc2 =  836; break; // vsrah
   5505       case Pav_ROTL:    opc2 =   68; break; // vrlh
   5506 
   5507       case Pav_PACKUU:  opc2 =   14; break; // vpkuhum
   5508       case Pav_QPACKUU: opc2 =  142; break; // vpkuhus
   5509       case Pav_QPACKSU: opc2 =  270; break; // vpkshus
   5510       case Pav_QPACKSS: opc2 =  398; break; // vpkshss
   5511       case Pav_PACKPXL: opc2 =  782; break; // vpkpx
   5512 
   5513       case Pav_MRGHI:   opc2 =   76; break; // vmrghh
   5514       case Pav_MRGLO:   opc2 =  332; break; // vmrglh
   5515 
   5516       case Pav_POLYMULADD: opc2 = 1224; break; // vpmsumh
   5517 
   5518       default:
   5519          goto bad;
   5520       }
   5521       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host );
   5522       goto done;
   5523    }
   5524 
   5525    case Pin_AvBin32x4: {
   5526       UInt v_dst  = vregEnc(i->Pin.AvBin32x4.dst);
   5527       UInt v_srcL = vregEnc(i->Pin.AvBin32x4.srcL);
   5528       UInt v_srcR = vregEnc(i->Pin.AvBin32x4.srcR);
   5529       UInt opc2;
   5530       switch (i->Pin.AvBin32x4.op) {
   5531 
   5532       case Pav_ADDU:    opc2 =  128; break; // vadduwm
   5533       case Pav_QADDU:   opc2 =  640; break; // vadduws
   5534       case Pav_QADDS:   opc2 =  896; break; // vaddsws
   5535 
   5536       case Pav_SUBU:    opc2 = 1152; break; // vsubuwm
   5537       case Pav_QSUBU:   opc2 = 1664; break; // vsubuws
   5538       case Pav_QSUBS:   opc2 = 1920; break; // vsubsws
   5539 
   5540       case Pav_MULU:    opc2 =  137; break; // vmuluwm
   5541       case Pav_OMULU:   opc2 =  136; break; // vmulouw
   5542       case Pav_OMULS:   opc2 =  392; break; // vmulosw
   5543       case Pav_EMULU:   opc2 =  648; break; // vmuleuw
   5544       case Pav_EMULS:   opc2 =  904; break; // vmulesw
   5545 
   5546       case Pav_AVGU:    opc2 = 1154; break; // vavguw
   5547       case Pav_AVGS:    opc2 = 1410; break; // vavgsw
   5548 
   5549       case Pav_MAXU:    opc2 =  130; break; // vmaxuw
   5550       case Pav_MAXS:    opc2 =  386; break; // vmaxsw
   5551 
   5552       case Pav_MINS:    opc2 =  898; break; // vminsw
   5553       case Pav_MINU:    opc2 =  642; break; // vminuw
   5554 
   5555       case Pav_CMPEQU:  opc2 =  134; break; // vcmpequw
   5556       case Pav_CMPGTS:  opc2 =  902; break; // vcmpgtsw
   5557       case Pav_CMPGTU:  opc2 =  646; break; // vcmpgtuw
   5558 
   5559       case Pav_SHL:     opc2 =  388; break; // vslw
   5560       case Pav_SHR:     opc2 =  644; break; // vsrw
   5561       case Pav_SAR:     opc2 =  900; break; // vsraw
   5562       case Pav_ROTL:    opc2 =  132; break; // vrlw
   5563 
   5564       case Pav_PACKUU:  opc2 =   78; break; // vpkuwum
   5565       case Pav_QPACKUU: opc2 =  206; break; // vpkuwus
   5566       case Pav_QPACKSU: opc2 =  334; break; // vpkswus
   5567       case Pav_QPACKSS: opc2 =  462; break; // vpkswss
   5568 
   5569       case Pav_MRGHI:   opc2 =  140; break; // vmrghw
   5570       case Pav_MRGLO:   opc2 =  396; break; // vmrglw
   5571 
   5572       case Pav_CATODD:  opc2 = 1676; break; // vmrgow
   5573       case Pav_CATEVEN: opc2 = 1932; break; // vmrgew
   5574 
   5575       case Pav_POLYMULADD: opc2 = 1160; break; // vpmsumw
   5576 
   5577       default:
   5578          goto bad;
   5579       }
   5580       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host );
   5581       goto done;
   5582    }
   5583 
   5584    case Pin_AvBin64x2: {
   5585       UInt v_dst  = vregEnc(i->Pin.AvBin64x2.dst);
   5586       UInt v_srcL = vregEnc(i->Pin.AvBin64x2.srcL);
   5587       UInt v_srcR = vregEnc(i->Pin.AvBin64x2.srcR);
   5588       UInt opc2;
   5589       switch (i->Pin.AvBin64x2.op) {
   5590       case Pav_ADDU:    opc2 =  192; break; // vaddudm  vector double add
   5591       case Pav_SUBU:    opc2 = 1216; break; // vsubudm  vector double add
   5592       case Pav_MAXU:    opc2 =  194; break; // vmaxud   vector double max
   5593       case Pav_MAXS:    opc2 =  450; break; // vmaxsd   vector double max
   5594       case Pav_MINU:    opc2 =  706; break; // vminud   vector double min
   5595       case Pav_MINS:    opc2 =  962; break; // vminsd   vector double min
   5596       case Pav_CMPEQU:  opc2 =  199; break; // vcmpequd vector double compare
   5597       case Pav_CMPGTU:  opc2 =  711; break; // vcmpgtud vector double compare
   5598       case Pav_CMPGTS:  opc2 =  967; break; // vcmpgtsd vector double compare
   5599       case Pav_SHL:     opc2 = 1476; break; // vsld
   5600       case Pav_SHR:     opc2 = 1732; break; // vsrd
   5601       case Pav_SAR:     opc2 =  964; break; // vsrad
   5602       case Pav_ROTL:    opc2 =  196; break; // vrld
   5603       case Pav_PACKUU:  opc2 = 1102; break; // vpkudum
   5604       case Pav_QPACKUU: opc2 = 1230; break; // vpkudus, vpksdus (emulated)
   5605       case Pav_QPACKSS: opc2 = 1486; break; // vpksdsm
   5606       case Pav_MRGHI:   opc2 = 1614; break; // vmrghw
   5607       case Pav_MRGLO:   opc2 = 1742; break; // vmrglw
   5608       case Pav_POLYMULADD: opc2 = 1096; break; // vpmsumd
   5609       default:
   5610          goto bad;
   5611       }
   5612       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host );
   5613       goto done;
   5614    }
   5615    case Pin_AvCipherV128Unary: {
   5616       UInt v_dst = vregEnc(i->Pin.AvCipherV128Unary.dst);
   5617       UInt v_src = vregEnc(i->Pin.AvCipherV128Unary.src);
   5618       UInt opc2;
   5619       switch (i->Pin.AvCipherV128Unary.op) {
   5620       case Pav_CIPHERSUBV128:   opc2 =  1480; break; // vsbox
   5621       default:
   5622          goto bad;
   5623       }
   5624       p = mkFormVX( p, 4, v_dst, v_src, 0, opc2, endness_host );
   5625       goto done;
   5626    }
   5627    case Pin_AvCipherV128Binary: {
   5628       UInt v_dst  = vregEnc(i->Pin.AvCipherV128Binary.dst);
   5629       UInt v_srcL = vregEnc(i->Pin.AvCipherV128Binary.srcL);
   5630       UInt v_srcR = vregEnc(i->Pin.AvCipherV128Binary.srcR);
   5631       UInt opc2;
   5632       switch (i->Pin.AvCipherV128Binary.op) {
   5633       case Pav_CIPHERV128:     opc2 =  1288; break; // vcipher
   5634       case Pav_CIPHERLV128:    opc2 =  1289; break; // vcipherlast
   5635       case Pav_NCIPHERV128:    opc2 =  1352; break; // vncipher
   5636       case Pav_NCIPHERLV128:   opc2 =  1353; break; // vncipherlast
   5637       default:
   5638          goto bad;
   5639       }
   5640       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host );
   5641       goto done;
   5642    }
   5643    case Pin_AvHashV128Binary: {
   5644       UInt v_dst = vregEnc(i->Pin.AvHashV128Binary.dst);
   5645       UInt v_src = vregEnc(i->Pin.AvHashV128Binary.src);
   5646       PPCRI* s_field = i->Pin.AvHashV128Binary.s_field;
   5647       UInt opc2;
   5648       switch (i->Pin.AvHashV128Binary.op) {
   5649       case Pav_SHA256:   opc2 =  1666; break; // vshasigmaw
   5650       case Pav_SHA512:   opc2 =  1730; break; // vshasigmad
   5651       default:
   5652          goto bad;
   5653       }
   5654       p = mkFormVX( p, 4, v_dst, v_src, s_field->Pri.Imm, opc2, endness_host );
   5655       goto done;
   5656    }
   5657    case Pin_AvBCDV128Binary: {
   5658       UInt v_dst  = vregEnc(i->Pin.AvBCDV128Binary.dst);
   5659       UInt v_src1 = vregEnc(i->Pin.AvBCDV128Binary.src1);
   5660       UInt v_src2 = vregEnc(i->Pin.AvBCDV128Binary.src2);
   5661       UInt ps = 0;    /* Issue the instruction with ps=0.  The IR code will
   5662                        * fix up the result if ps=1.
   5663                        */
   5664       UInt opc2;
   5665       switch (i->Pin.AvBCDV128Binary.op) {
   5666       case Pav_BCDAdd:   opc2 =  1; break; // bcdadd
   5667       case Pav_BCDSub:   opc2 = 65; break; // bcdsub
   5668       default:
   5669          goto bad;
   5670       }
   5671       p = mkFormVXR( p, 4, v_dst, v_src1, v_src2,
   5672                      0x1, ps | opc2, endness_host );
   5673       goto done;
   5674    }
   5675    case Pin_AvBin32Fx4: {
   5676       UInt v_dst  = vregEnc(i->Pin.AvBin32Fx4.dst);
   5677       UInt v_srcL = vregEnc(i->Pin.AvBin32Fx4.srcL);
   5678       UInt v_srcR = vregEnc(i->Pin.AvBin32Fx4.srcR);
   5679       switch (i->Pin.AvBin32Fx4.op) {
   5680 
   5681       case Pavfp_ADDF:
   5682          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 10, endness_host );   // vaddfp
   5683          break;
   5684       case Pavfp_SUBF:
   5685          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 74, endness_host );   // vsubfp
   5686          break;
   5687       case Pavfp_MAXF:
   5688          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1034, endness_host ); // vmaxfp
   5689          break;
   5690       case Pavfp_MINF:
   5691          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1098, endness_host ); // vminfp
   5692          break;
   5693 
   5694       case Pavfp_MULF: {
   5695          /* Make a vmulfp from a vmaddfp:
   5696             load -0.0 (0x8000_0000) to each 32-bit word of vB
   5697             this makes the add a noop.
   5698          */
   5699          UInt vB = 29;  // XXX: Using v29 for temp do not change
   5700                         // without also changing
   5701                         // getRegUsage_PPCInstr
   5702          UInt konst = 0x1F;
   5703 
   5704          // Better way to load -0.0 (0x80000000) ?
   5705          // vspltisw vB,0x1F   (0x1F => each word of vB)
   5706          p = mkFormVX( p, 4, vB, konst, 0, 908, endness_host );
   5707 
   5708          // vslw vB,vB,vB (each word of vB = (0x1F << 0x1F) = 0x80000000
   5709          p = mkFormVX( p, 4, vB, vB, vB, 388, endness_host );
   5710 
   5711          // Finally, do the multiply:
   5712          p = mkFormVA( p, 4, v_dst, v_srcL, vB, v_srcR, 46, endness_host );
   5713          break;
   5714       }
   5715       case Pavfp_CMPEQF:  // vcmpeqfp
   5716          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 198, endness_host);
   5717          break;
   5718       case Pavfp_CMPGTF:  // vcmpgtfp
   5719          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 710, endness_host );
   5720          break;
   5721       case Pavfp_CMPGEF:  // vcmpgefp
   5722          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 454, endness_host );
   5723          break;
   5724 
   5725       default:
   5726          goto bad;
   5727       }
   5728       goto done;
   5729    }
   5730 
   5731    case Pin_AvUn32Fx4: {
   5732       UInt v_dst = vregEnc(i->Pin.AvUn32Fx4.dst);
   5733       UInt v_src = vregEnc(i->Pin.AvUn32Fx4.src);
   5734       UInt opc2;
   5735       switch (i->Pin.AvUn32Fx4.op) {
   5736       case Pavfp_RCPF:    opc2 =  266; break; // vrefp
   5737       case Pavfp_RSQRTF:  opc2 =  330; break; // vrsqrtefp
   5738       case Pavfp_CVTU2F:  opc2 =  778; break; // vcfux
   5739       case Pavfp_CVTS2F:  opc2 =  842; break; // vcfsx
   5740       case Pavfp_QCVTF2U: opc2 =  906; break; // vctuxs
   5741       case Pavfp_QCVTF2S: opc2 =  970; break; // vctsxs
   5742       case Pavfp_ROUNDM:  opc2 =  714; break; // vrfim
   5743       case Pavfp_ROUNDP:  opc2 =  650; break; // vrfip
   5744       case Pavfp_ROUNDN:  opc2 =  522; break; // vrfin
   5745       case Pavfp_ROUNDZ:  opc2 =  586; break; // vrfiz
   5746       default:
   5747          goto bad;
   5748       }
   5749       p = mkFormVX( p, 4, v_dst, 0, v_src, opc2, endness_host );
   5750       goto done;
   5751    }
   5752 
   5753    case Pin_AvPerm: {  // vperm
   5754       UInt v_dst  = vregEnc(i->Pin.AvPerm.dst);
   5755       UInt v_srcL = vregEnc(i->Pin.AvPerm.srcL);
   5756       UInt v_srcR = vregEnc(i->Pin.AvPerm.srcR);
   5757       UInt v_ctl  = vregEnc(i->Pin.AvPerm.ctl);
   5758       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 43, endness_host );
   5759       goto done;
   5760    }
   5761 
   5762    case Pin_AvSel: {  // vsel
   5763       UInt v_ctl  = vregEnc(i->Pin.AvSel.ctl);
   5764       UInt v_dst  = vregEnc(i->Pin.AvSel.dst);
   5765       UInt v_srcL = vregEnc(i->Pin.AvSel.srcL);
   5766       UInt v_srcR = vregEnc(i->Pin.AvSel.srcR);
   5767       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 42, endness_host );
   5768       goto done;
   5769    }
   5770 
   5771    case Pin_AvSh: {  // vsl or vsr
   5772       UInt v_dst  = vregEnc(i->Pin.AvSh.dst);
   5773       Bool  idxd = toBool(i->Pin.AvSh.addr->tag == Pam_RR);
   5774       UInt r_idx, r_base;
   5775 
   5776       r_base = iregEnc(i->Pin.AvSh.addr->Pam.RR.base, mode64);
   5777 
   5778       if (!idxd) {
   5779          r_idx = 30; // XXX: Using r30 as temp
   5780          p = mkLoadImm(p, r_idx,
   5781                        i->Pin.AvSh.addr->Pam.IR.index, mode64, endness_host);
   5782       } else {
   5783          r_idx  = iregEnc(i->Pin.AvSh.addr->Pam.RR.index, mode64);
   5784       }
   5785 
   5786       if (i->Pin.AvSh.shLeft)
   5787          //vsl VRT,RA,RB
   5788          p = mkFormVXI( p, 31, v_dst, r_idx, r_base, 6, endness_host );
   5789       else
   5790          //vsr VRT,RA,RB
   5791          p = mkFormVXI( p, 31, v_dst, r_idx, r_base, 38, endness_host );
   5792       goto done;
   5793    }
   5794 
   5795    case Pin_AvShlDbl: {  // vsldoi
   5796       UInt shift  = i->Pin.AvShlDbl.shift;
   5797       UInt v_dst  = vregEnc(i->Pin.AvShlDbl.dst);
   5798       UInt v_srcL = vregEnc(i->Pin.AvShlDbl.srcL);
   5799       UInt v_srcR = vregEnc(i->Pin.AvShlDbl.srcR);
   5800       vassert(shift <= 0xF);
   5801       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, shift, 44, endness_host );
   5802       goto done;
   5803    }
   5804 
   5805    case Pin_AvSplat: { // vsplt(is)(b,h,w)
   5806       UInt v_dst = vregEnc(i->Pin.AvShlDbl.dst);
   5807       UChar sz   = i->Pin.AvSplat.sz;
   5808       UInt v_src, opc2;
   5809       vassert(sz == 8 || sz == 16 || sz == 32);
   5810 
   5811       if (i->Pin.AvSplat.src->tag == Pvi_Imm) {
   5812          Char simm5;
   5813          opc2 = (sz == 8) ? 780 : (sz == 16) ? 844 : 908;   // 8,16,32
   5814          /* expects 5-bit-signed-imm */
   5815          simm5 = i->Pin.AvSplat.src->Pvi.Imm5s;
   5816          vassert(simm5 >= -16 && simm5 <= 15);
   5817          simm5 = simm5 & 0x1F;
   5818          p = mkFormVX( p, 4, v_dst, (UInt)simm5, 0, opc2, endness_host );
   5819       }
   5820       else {  // Pri_Reg
   5821          UInt lowest_lane;
   5822          opc2 = (sz == 8) ? 524 : (sz == 16) ? 588 : 652;  // 8,16,32
   5823          vassert(hregClass(i->Pin.AvSplat.src->Pvi.Reg) == HRcVec128);
   5824          v_src = vregEnc(i->Pin.AvSplat.src->Pvi.Reg);
   5825          lowest_lane = (128/sz)-1;
   5826          p = mkFormVX( p, 4, v_dst, lowest_lane, v_src, opc2, endness_host );
   5827       }
   5828       goto done;
   5829    }
   5830 
   5831    case Pin_AvCMov: {
   5832       UInt v_dst     = vregEnc(i->Pin.AvCMov.dst);
   5833       UInt v_src     = vregEnc(i->Pin.AvCMov.src);
   5834       PPCCondCode cc = i->Pin.AvCMov.cond;
   5835 
   5836       if (v_dst == v_src) goto done;
   5837 
   5838       vassert(cc.test != Pct_ALWAYS);
   5839 
   5840       /* jmp fwds 2 insns if !condition */
   5841       if (cc.test != Pct_ALWAYS) {
   5842          /* bc !ct,cf,n_bytes>>2 */
   5843          p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0,
   5844                      endness_host);
   5845       }
   5846       /* vmr */
   5847       p = mkFormVX( p, 4, v_dst, v_src, v_src, 1156, endness_host );
   5848       goto done;
   5849    }
   5850 
   5851    case Pin_AvLdVSCR: {  // mtvscr
   5852       UInt v_src = vregEnc(i->Pin.AvLdVSCR.src);
   5853       p = mkFormVX( p, 4, 0, 0, v_src, 1604, endness_host );
   5854       goto done;
   5855    }
   5856 
   5857    case Pin_Dfp64Unary: {
   5858       UInt fr_dst = fregEnc( i->Pin.FpUnary.dst );
   5859       UInt fr_src = fregEnc( i->Pin.FpUnary.src );
   5860 
   5861       switch (i->Pin.Dfp64Unary.op) {
   5862       case Pfp_MOV: // fmr, PPC32 p410
   5863          p = mkFormX( p, 63, fr_dst, 0, fr_src, 72, 0, endness_host );
   5864          break;
   5865       case Pfp_DCTDP:   // D32 to D64
   5866          p = mkFormX( p, 59, fr_dst, 0, fr_src, 258, 0, endness_host );
   5867          break;
   5868       case Pfp_DRSP:    // D64 to D32
   5869          p = mkFormX( p, 59, fr_dst, 0, fr_src, 770, 0, endness_host );
   5870          break;
   5871       case Pfp_DCFFIX:   // I64 to D64 conversion
   5872          /* ONLY WORKS ON POWER7 */
   5873          p = mkFormX( p, 59, fr_dst, 0, fr_src, 802, 0, endness_host );
   5874          break;
   5875       case Pfp_DCTFIX:   // D64 to I64 conversion
   5876          p = mkFormX( p, 59, fr_dst, 0, fr_src, 290, 0, endness_host );
   5877          break;
   5878       case Pfp_DXEX:     // Extract exponent
   5879          p = mkFormX( p, 59, fr_dst, 0, fr_src, 354, 0, endness_host );
   5880          break;
   5881       default:
   5882          goto bad;
   5883       }
   5884       goto done;
   5885    }
   5886 
   5887    case Pin_Dfp64Binary: {
   5888       UInt fr_dst = fregEnc( i->Pin.Dfp64Binary.dst );
   5889       UInt fr_srcL = fregEnc( i->Pin.Dfp64Binary.srcL );
   5890       UInt fr_srcR = fregEnc( i->Pin.Dfp64Binary.srcR );
   5891       switch (i->Pin.Dfp64Binary.op) {
   5892       case Pfp_DFPADD: /* dadd, dfp add, use default RM from reg ignore mode
   5893                         * from the Iop instruction. */
   5894          p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 2, 0, endness_host );
   5895          break;
   5896       case Pfp_DFPSUB: /* dsub, dfp subtract, use default RM from reg ignore
   5897                         * mode from the Iop instruction. */
   5898          p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 514, 0, endness_host );
   5899          break;
   5900       case Pfp_DFPMUL: /* dmul, dfp multipy, use default RM from reg ignore
   5901                         * mode from the Iop instruction. */
   5902          p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 34, 0, endness_host );
   5903          break;
   5904       case Pfp_DFPDIV: /* ddiv, dfp divide, use default RM from reg ignore
   5905                         * mode from the Iop instruction. */
   5906          p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 546, 0, endness_host );
   5907          break;
   5908       case Pfp_DIEX:  /* diex, insert exponent */
   5909          p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 866, 0, endness_host );
   5910          break;
   5911       default:
   5912          goto bad;
   5913       }
   5914       goto done;
   5915    }
   5916 
   5917    case Pin_DfpShift: {
   5918       UInt fr_src = fregEnc(i->Pin.DfpShift.src);
   5919       UInt fr_dst = fregEnc(i->Pin.DfpShift.dst);
   5920       UInt shift;
   5921 
   5922       shift =  i->Pin.DfpShift.shift->Pri.Imm;
   5923 
   5924       switch (i->Pin.DfpShift.op) {
   5925       case Pfp_DSCLI:    /* dscli, DFP shift left by fr_srcR */
   5926          p = mkFormZ22( p, 59, fr_dst, fr_src, shift,  66, 0, endness_host );
   5927          break;
   5928       case Pfp_DSCRI:    /* dscri, DFP shift right by fr_srcR */
   5929          p = mkFormZ22( p, 59, fr_dst, fr_src, shift,  98, 0, endness_host );
   5930          break;
   5931       default:
   5932          vex_printf("ERROR: emit_PPCInstr default case\n");
   5933          goto bad;
   5934       }
   5935       goto done;
   5936    }
   5937 
   5938    case Pin_ExtractExpD128: {
   5939       UInt fr_dst   = fregEnc(i->Pin.ExtractExpD128.dst);
   5940       UInt fr_srcHi = fregEnc(i->Pin.ExtractExpD128.src_hi);
   5941       UInt fr_srcLo = fregEnc(i->Pin.ExtractExpD128.src_lo);
   5942 
   5943       switch (i->Pin.ExtractExpD128.op) {
   5944       case Pfp_DXEXQ:
   5945          /* Setup the upper and lower registers of the source operand
   5946           * register pair.
   5947           */
   5948          p = mkFormX( p, 63, 12, 0, fr_srcHi, 72, 0, endness_host );
   5949          p = mkFormX( p, 63, 13, 0, fr_srcLo, 72, 0, endness_host );
   5950          p = mkFormX( p, 63, 10, 0, 12, 354, 0, endness_host );
   5951 
   5952          /* The instruction will put the 64-bit result in
   5953           * register 10.
   5954           */
   5955          p = mkFormX(p, 63, fr_dst, 0, 10,  72, 0, endness_host);
   5956          break;
   5957       default:
   5958          vex_printf("Error: emit_PPCInstr case Pin_DfpExtractExp, case inst Default\n");
   5959          goto bad;
   5960       }
   5961       goto done;
   5962    }
   5963    case Pin_Dfp128Unary: {
   5964      UInt fr_dstHi = fregEnc(i->Pin.Dfp128Unary.dst_hi);
   5965      UInt fr_dstLo = fregEnc(i->Pin.Dfp128Unary.dst_lo);
   5966      UInt fr_srcLo = fregEnc(i->Pin.Dfp128Unary.src_lo);
   5967 
   5968      /* Do instruction with 128-bit source operands in registers (10,11)
   5969       * and (12,13).
   5970       */
   5971      switch (i->Pin.Dfp128Unary.op) {
   5972      case Pfp_DCTQPQ: // D64 to D128, srcLo holds 64 bit operand
   5973         p = mkFormX( p, 63, 12, 0, fr_srcLo, 72, 0, endness_host );
   5974 
   5975         p = mkFormX( p, 63, 10, 0, 12, 258, 0, endness_host );
   5976 
   5977         /* The instruction will put the 128-bit result in
   5978          * registers (10,11).  Note, the operand in the instruction only
   5979          * reference the first of the two registers in the pair.
   5980          */
   5981         p = mkFormX(p, 63, fr_dstHi, 0, 10,  72, 0, endness_host);
   5982         p = mkFormX(p, 63, fr_dstLo, 0, 11,  72, 0, endness_host);
   5983         break;
   5984      default:
   5985         vex_printf("Error: emit_PPCInstr case Pin_Dfp128Unary, case inst Default\
   5986 \n");
   5987         goto bad;
   5988      }
   5989      goto done;
   5990    }
   5991 
   5992    case Pin_Dfp128Binary: {
   5993       /* dst is used to supply the  left source operand and return
   5994        * the result.
   5995        */
   5996       UInt fr_dstHi = fregEnc( i->Pin.Dfp128Binary.dst_hi );
   5997       UInt fr_dstLo = fregEnc( i->Pin.Dfp128Binary.dst_lo );
   5998       UInt fr_srcRHi = fregEnc( i->Pin.Dfp128Binary.srcR_hi );
   5999       UInt fr_srcRLo = fregEnc( i->Pin.Dfp128Binary.srcR_lo );
   6000 
   6001       /* Setup the upper and lower registers of the source operand
   6002        * register pair.
   6003        */
   6004       p = mkFormX( p, 63, 10, 0, fr_dstHi, 72, 0, endness_host );
   6005       p = mkFormX( p, 63, 11, 0, fr_dstLo, 72, 0, endness_host );
   6006       p = mkFormX( p, 63, 12, 0, fr_srcRHi, 72, 0, endness_host );
   6007       p = mkFormX( p, 63, 13, 0, fr_srcRLo, 72, 0, endness_host );
   6008 
   6009       /* Do instruction with 128-bit source operands in registers (10,11)
   6010        * and (12,13).
   6011        */
   6012       switch (i->Pin.Dfp128Binary.op) {
   6013       case Pfp_DFPADDQ:
   6014          p = mkFormX( p, 63, 10, 10, 12, 2, 0, endness_host );
   6015          break;
   6016       case Pfp_DFPSUBQ:
   6017          p = mkFormX( p, 63, 10, 10, 12, 514, 0, endness_host );
   6018          break;
   6019       case Pfp_DFPMULQ:
   6020          p = mkFormX( p, 63, 10, 10, 12, 34, 0, endness_host );
   6021          break;
   6022       case Pfp_DFPDIVQ:
   6023          p = mkFormX( p, 63, 10, 10, 12, 546, 0, endness_host );
   6024          break;
   6025       default:
   6026          goto bad;
   6027       }
   6028 
   6029       /* The instruction will put the 128-bit result in
   6030        * registers (10,11).  Note, the operand in the instruction only
   6031        * reference the first of the two registers in the pair.
   6032        */
   6033       p = mkFormX(p, 63, fr_dstHi, 0, 10,  72, 0, endness_host);
   6034       p = mkFormX(p, 63, fr_dstLo, 0, 11,  72, 0, endness_host);
   6035       goto done;
   6036    }
   6037 
   6038    case Pin_DfpShift128: {
   6039       UInt fr_src_hi = fregEnc(i->Pin.DfpShift128.src_hi);
   6040       UInt fr_src_lo = fregEnc(i->Pin.DfpShift128.src_lo);
   6041       UInt fr_dst_hi = fregEnc(i->Pin.DfpShift128.dst_hi);
   6042       UInt fr_dst_lo = fregEnc(i->Pin.DfpShift128.dst_lo);
   6043       UInt shift;
   6044 
   6045       shift =  i->Pin.DfpShift128.shift->Pri.Imm;
   6046 
   6047       /* setup source operand in register 12, 13 pair */
   6048       p = mkFormX(p, 63, 12, 0, fr_src_hi, 72, 0, endness_host);
   6049       p = mkFormX(p, 63, 13, 0, fr_src_lo, 72, 0, endness_host);
   6050 
   6051       /* execute instruction putting result in register 10, 11 pair */
   6052       switch (i->Pin.DfpShift128.op) {
   6053       case Pfp_DSCLIQ:    /* dscliq, DFP shift left, fr_srcR is the integer
   6054                            * shift amount.
   6055                            */
   6056          p = mkFormZ22( p, 63, 10, 12, shift,  66, 0, endness_host );
   6057          break;
   6058       case Pfp_DSCRIQ:    /* dscriq, DFP shift right, fr_srcR is the integer
   6059                            * shift amount.
   6060                            */
   6061          p = mkFormZ22( p, 63, 10, 12, shift,  98, 0, endness_host );
   6062          break;
   6063       default:
   6064          vex_printf("ERROR: emit_PPCInstr quad default case %d \n",
   6065                     (Int)i->Pin.DfpShift128.op);
   6066          goto bad;
   6067       }
   6068 
   6069       /* The instruction put the 128-bit result in registers (10,11).
   6070        * Note, the operand in the instruction only reference the first of
   6071        * the two registers in the pair.
   6072        */
   6073       p = mkFormX(p, 63, fr_dst_hi, 0, 10,  72, 0, endness_host);
   6074       p = mkFormX(p, 63, fr_dst_lo, 0, 11,  72, 0, endness_host);
   6075       goto done;
   6076    }
   6077 
   6078    case Pin_DfpRound: {
   6079       UInt fr_dst = fregEnc(i->Pin.DfpRound.dst);
   6080       UInt fr_src = fregEnc(i->Pin.DfpRound.src);
   6081       UInt r_rmc, r, rmc;
   6082 
   6083       r_rmc =  i->Pin.DfpRound.r_rmc->Pri.Imm;
   6084       r = (r_rmc & 0x8) >> 3;
   6085       rmc = r_rmc & 0x3;
   6086 
   6087       // drintx
   6088       p = mkFormZ23(p, 59, fr_dst, r, fr_src, rmc, 99, 0, endness_host);
   6089       goto done;
   6090    }
   6091 
   6092    case Pin_DfpRound128: {
   6093       UInt fr_dstHi = fregEnc(i->Pin.DfpRound128.dst_hi);
   6094       UInt fr_dstLo = fregEnc(i->Pin.DfpRound128.dst_lo);
   6095       UInt fr_srcHi = fregEnc(i->Pin.DfpRound128.src_hi);
   6096       UInt fr_srcLo = fregEnc(i->Pin.DfpRound128.src_lo);
   6097       UInt r_rmc, r, rmc;
   6098 
   6099       r_rmc =  i->Pin.DfpRound128.r_rmc->Pri.Imm;
   6100       r = (r_rmc & 0x8) >> 3;
   6101       rmc = r_rmc & 0x3;
   6102 
   6103       /* Setup the upper and lower registers of the source operand
   6104        * register pair.
   6105        */
   6106       p = mkFormX(p, 63, 12, 0, fr_srcHi, 72, 0, endness_host);
   6107       p = mkFormX(p, 63, 13, 0, fr_srcLo, 72, 0, endness_host);
   6108 
   6109       /* Do drintx instruction with 128-bit source operands in
   6110        * registers (12,13).
   6111        */
   6112       p = mkFormZ23(p, 63, 10, r, 12, rmc, 99, 0, endness_host);
   6113 
   6114       /* The instruction will put the 128-bit result in
   6115        * registers (10,11).  Note, the operand in the instruction only
   6116        * reference the first of the two registers in the pair.
   6117        */
   6118       p = mkFormX(p, 63, fr_dstHi, 0, 10,  72, 0, endness_host);
   6119       p = mkFormX(p, 63, fr_dstLo, 0, 11,  72, 0, endness_host);
   6120       goto done;
   6121    }
   6122 
   6123    case Pin_DfpQuantize: {
   6124       UInt fr_dst  = fregEnc(i->Pin.DfpQuantize.dst);
   6125       UInt fr_srcL = fregEnc(i->Pin.DfpQuantize.srcL);
   6126       UInt fr_srcR = fregEnc(i->Pin.DfpQuantize.srcR);
   6127       UInt rmc;
   6128 
   6129       rmc =  i->Pin.DfpQuantize.rmc->Pri.Imm;
   6130 
   6131       switch (i->Pin.DfpQuantize.op) {
   6132       case Pfp_DQUA:
   6133          p = mkFormZ23(p, 59, fr_dst, fr_srcL, fr_srcR, rmc, 3, 0, endness_host);
   6134          break;
   6135       case Pfp_RRDTR:
   6136          p = mkFormZ23(p, 59, fr_dst, fr_srcL, fr_srcR, rmc, 35, 0, endness_host);
   6137          break;
   6138       default:
   6139          break;
   6140       }
   6141       goto done;
   6142    }
   6143 
   6144    case Pin_DfpQuantize128: {
   6145       UInt fr_dst_hi = fregEnc(i->Pin.DfpQuantize128.dst_hi);
   6146       UInt fr_dst_lo = fregEnc(i->Pin.DfpQuantize128.dst_lo);
   6147       UInt fr_src_hi = fregEnc(i->Pin.DfpQuantize128.src_hi);
   6148       UInt fr_src_lo = fregEnc(i->Pin.DfpQuantize128.src_lo);
   6149       UInt rmc;
   6150 
   6151       rmc =  i->Pin.DfpQuantize128.rmc->Pri.Imm;
   6152       /* Setup the upper and lower registers of the source operand
   6153        * register pairs.  Note, left source operand passed in via the
   6154        * dst register pair.
   6155        */
   6156       p = mkFormX(p, 63, 10, 0, fr_dst_hi, 72, 0, endness_host);
   6157       p = mkFormX(p, 63, 11, 0, fr_dst_lo, 72, 0, endness_host);
   6158       p = mkFormX(p, 63, 12, 0, fr_src_hi, 72, 0, endness_host);
   6159       p = mkFormX(p, 63, 13, 0, fr_src_lo, 72, 0, endness_host);
   6160 
   6161       /* Do dquaq instruction with 128-bit source operands in
   6162        * registers (12,13).
   6163        */
   6164       switch (i->Pin.DfpQuantize128.op) {
   6165       case Pfp_DQUAQ:
   6166          p = mkFormZ23(p, 63, 10, 10, 12, rmc, 3, 0, endness_host);
   6167          break;
   6168       case Pfp_DRRNDQ:
   6169          p = mkFormZ23(p, 63, 10, 10, 12, rmc, 35, 0, endness_host);
   6170          break;
   6171       default:
   6172          vpanic("Pin_DfpQuantize128: default case, couldn't find inst to issue \n");
   6173          break;
   6174       }
   6175 
   6176       /* The instruction will put the 128-bit result in
   6177        * registers (10,11).  Note, the operand in the instruction only
   6178        * reference the first of the two registers in the pair.
   6179        */
   6180       p = mkFormX(p, 63, fr_dst_hi, 0, 10,  72, 0, endness_host);
   6181       p = mkFormX(p, 63, fr_dst_lo, 0, 11,  72, 0, endness_host);
   6182       goto done;
   6183    }
   6184 
   6185    case Pin_DfpD128toD64: {
   6186       UInt fr_dst   = fregEnc( i->Pin.DfpD128toD64.dst );
   6187       UInt fr_srcHi = fregEnc( i->Pin.DfpD128toD64.src_hi );
   6188       UInt fr_srcLo = fregEnc( i->Pin.DfpD128toD64.src_lo );
   6189 
   6190       /* Setup the upper and lower registers of the source operand
   6191        * register pair.
   6192        */
   6193       p = mkFormX( p, 63, 10, 0, fr_dst, 72, 0, endness_host );
   6194       p = mkFormX( p, 63, 12, 0, fr_srcHi, 72, 0, endness_host );
   6195       p = mkFormX( p, 63, 13, 0, fr_srcLo, 72, 0, endness_host );
   6196 
   6197       /* Do instruction with 128-bit source operands in registers (10,11) */
   6198       switch (i->Pin.Dfp128Binary.op) {
   6199       case Pfp_DRDPQ:
   6200          p = mkFormX( p, 63, 10, 0, 12, 770, 0, endness_host );
   6201          break;
   6202       case Pfp_DCTFIXQ:
   6203          p = mkFormX( p, 63, 10, 0, 12, 290, 0, endness_host );
   6204          break;
   6205       default:
   6206          goto bad;
   6207       }
   6208 
   6209       /* The instruction will put the 64-bit result in registers 10. */
   6210       p = mkFormX(p, 63, fr_dst, 0, 10,  72, 0, endness_host);
   6211       goto done;
   6212    }
   6213 
   6214    case Pin_DfpI64StoD128: {
   6215       UInt fr_dstHi = fregEnc( i->Pin.DfpI64StoD128.dst_hi );
   6216       UInt fr_dstLo = fregEnc( i->Pin.DfpI64StoD128.dst_lo );
   6217       UInt fr_src   = fregEnc( i->Pin.DfpI64StoD128.src );
   6218 
   6219       switch (i->Pin.Dfp128Binary.op) {
   6220       case Pfp_DCFFIXQ:
   6221          p = mkFormX( p, 63, 10, 11, fr_src, 802, 0, endness_host );
   6222          break;
   6223       default:
   6224          goto bad;
   6225       }
   6226 
   6227       /* The instruction will put the 64-bit result in registers 10, 11. */
   6228       p = mkFormX(p, 63, fr_dstHi, 0, 10,  72, 0, endness_host);
   6229       p = mkFormX(p, 63, fr_dstLo, 0, 11,  72, 0, endness_host);
   6230       goto done;
   6231    }
   6232 
   6233    case Pin_InsertExpD128: {
   6234       UInt fr_dstHi  = fregEnc(i->Pin.InsertExpD128.dst_hi);
   6235       UInt fr_dstLo  = fregEnc(i->Pin.InsertExpD128.dst_lo);
   6236       UInt fr_srcL   = fregEnc(i->Pin.InsertExpD128.srcL);
   6237       UInt fr_srcRHi = fregEnc(i->Pin.InsertExpD128.srcR_hi);
   6238       UInt fr_srcRLo = fregEnc(i->Pin.InsertExpD128.srcR_lo);
   6239 
   6240       /* The left operand is a single F64 value, the right is an F128
   6241        * register pair.
   6242        */
   6243       p = mkFormX(p, 63, 10, 0, fr_srcL, 72, 0, endness_host);
   6244       p = mkFormX(p, 63, 12, 0, fr_srcRHi, 72, 0, endness_host);
   6245       p = mkFormX(p, 63, 13, 0, fr_srcRLo, 72, 0, endness_host);
   6246       p = mkFormX(p, 63, 10, 10, 12, 866, 0, endness_host );
   6247 
   6248       /* The instruction will put the 128-bit result into
   6249        * registers (10,11).  Note, the operand in the instruction only
   6250        * reference the first of the two registers in the pair.
   6251        */
   6252       p = mkFormX(p, 63, fr_dstHi, 0, 10,  72, 0, endness_host);
   6253       p = mkFormX(p, 63, fr_dstLo, 0, 11,  72, 0, endness_host);
   6254       goto done;
   6255    }
   6256 
   6257    case Pin_Dfp64Cmp:{
   6258       UChar crfD    = 1;
   6259       UInt  r_dst   = iregEnc(i->Pin.Dfp64Cmp.dst, mode64);
   6260       UInt  fr_srcL = fregEnc(i->Pin.Dfp64Cmp.srcL);
   6261       UInt  fr_srcR = fregEnc(i->Pin.Dfp64Cmp.srcR);
   6262       vassert(crfD < 8);
   6263       // dcmpo, dcmpu
   6264       p = mkFormX(p, 59, crfD<<2, fr_srcL, fr_srcR, 130, 0, endness_host);
   6265 
   6266       // mfcr (mv CR to r_dst)
   6267       p = mkFormX(p, 31, r_dst, 0, 0, 19, 0, endness_host);
   6268 
   6269       // rlwinm r_dst,r_dst,8,28,31
   6270       //  => rotate field 1 to bottomw of word, masking out upper 28
   6271       p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0, endness_host);
   6272       goto done;
   6273    }
   6274 
   6275    case Pin_Dfp128Cmp: {
   6276       UChar crfD       = 1;
   6277       UInt  r_dst      = iregEnc(i->Pin.Dfp128Cmp.dst, mode64);
   6278       UInt  fr_srcL_hi = fregEnc(i->Pin.Dfp128Cmp.srcL_hi);
   6279       UInt  fr_srcL_lo = fregEnc(i->Pin.Dfp128Cmp.srcL_lo);
   6280       UInt  fr_srcR_hi = fregEnc(i->Pin.Dfp128Cmp.srcR_hi);
   6281       UInt  fr_srcR_lo = fregEnc(i->Pin.Dfp128Cmp.srcR_lo);
   6282       vassert(crfD < 8);
   6283       // dcmpoq, dcmpuq
   6284       /* Setup the upper and lower registers of the source operand
   6285        * register pair.
   6286        */
   6287       p = mkFormX(p, 63, 10, 0, fr_srcL_hi, 72, 0, endness_host);
   6288       p = mkFormX(p, 63, 11, 0, fr_srcL_lo, 72, 0, endness_host);
   6289       p = mkFormX(p, 63, 12, 0, fr_srcR_hi, 72, 0, endness_host);
   6290       p = mkFormX(p, 63, 13, 0, fr_srcR_lo, 72, 0, endness_host);
   6291 
   6292       p = mkFormX(p, 63, crfD<<2, 10, 12, 130, 0, endness_host);
   6293 
   6294       // mfcr (mv CR to r_dst)
   6295       p = mkFormX(p, 31, r_dst, 0, 0, 19, 0, endness_host);
   6296 
   6297       // rlwinm r_dst,r_dst,8,28,31
   6298       //  => rotate field 1 to bottomw of word, masking out upper 28
   6299       p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0, endness_host);
   6300       goto done;
   6301    }
   6302 
   6303    case Pin_EvCheck: {
   6304       /* This requires a 32-bit dec/test in both 32- and 64-bit
   6305          modes. */
   6306       /* We generate:
   6307             lwz     r30, amCounter
   6308             addic.  r30, r30, -1
   6309             stw     r30, amCounter
   6310             bge     nofail
   6311             lwz/ld  r30, amFailAddr
   6312             mtctr   r30
   6313             bctr
   6314            nofail:
   6315       */
   6316       UChar* p0 = p;
   6317       /* lwz r30, amCounter */
   6318       p = do_load_or_store_word32(p, True/*isLoad*/, /*r*/30,
   6319                                   i->Pin.EvCheck.amCounter, mode64,
   6320                                   endness_host);
   6321       /* addic. r30,r30,-1 */
   6322       p = emit32(p, 0x37DEFFFF, endness_host);
   6323       /* stw r30, amCounter */
   6324       p = do_load_or_store_word32(p, False/*!isLoad*/, /*r*/30,
   6325                                   i->Pin.EvCheck.amCounter, mode64,
   6326                                   endness_host);
   6327       /* bge nofail */
   6328       p = emit32(p, 0x40800010, endness_host);
   6329       /* lwz/ld r30, amFailAddr */
   6330       p = do_load_or_store_machine_word(p, True/*isLoad*/, /*r*/30,
   6331                                         i->Pin.EvCheck.amFailAddr, mode64,
   6332                                         endness_host);
   6333       /* mtctr r30 */
   6334       p = mkFormXFX(p, /*r*/30, 9, 467, endness_host);
   6335       /* bctr */
   6336       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 0, endness_host);
   6337       /* nofail: */
   6338 
   6339       /* Crosscheck */
   6340       vassert(evCheckSzB_PPC() == (UChar*)p - (UChar*)p0);
   6341       goto done;
   6342    }
   6343 
   6344    case Pin_ProfInc: {
   6345       /* We generate:
   6346                (ctrP is unknown now, so use 0x65556555(65556555) in the
   6347                expectation that a later call to LibVEX_patchProfCtr
   6348                will be used to fill in the immediate fields once the
   6349                right value is known.)
   6350             32-bit:
   6351               imm32-exactly r30, 0x65556555
   6352               lwz     r29, 4(r30)
   6353               addic.  r29, r29, 1
   6354               stw     r29, 4(r30)
   6355               lwz     r29, 0(r30)
   6356               addze   r29, r29
   6357               stw     r29, 0(r30)
   6358             64-bit:
   6359               imm64-exactly r30, 0x6555655565556555
   6360               ld      r29, 0(r30)
   6361               addi    r29, r29, 1
   6362               std     r29, 0(r30)
   6363       */
   6364       if (mode64) {
   6365          p = mkLoadImm_EXACTLY2or5(
   6366                 p, /*r*/30, 0x6555655565556555ULL, True/*mode64*/, endness_host);
   6367          p = emit32(p, 0xEBBE0000, endness_host);
   6368          p = emit32(p, 0x3BBD0001, endness_host);
   6369          p = emit32(p, 0xFBBE0000, endness_host);
   6370       } else {
   6371          p = mkLoadImm_EXACTLY2or5(
   6372                 p, /*r*/30, 0x65556555ULL, False/*!mode64*/, endness_host);
   6373          p = emit32(p, 0x83BE0004, endness_host);
   6374          p = emit32(p, 0x37BD0001, endness_host);
   6375          p = emit32(p, 0x93BE0004, endness_host);
   6376          p = emit32(p, 0x83BE0000, endness_host);
   6377          p = emit32(p, 0x7FBD0194, endness_host);
   6378          p = emit32(p, 0x93BE0000, endness_host);
   6379       }
   6380       /* Tell the caller .. */
   6381       vassert(!(*is_profInc));
   6382       *is_profInc = True;
   6383       goto done;
   6384    }
   6385 
   6386    default:
   6387       goto bad;
   6388    }
   6389 
   6390   bad:
   6391    vex_printf("\n=> ");
   6392    ppPPCInstr(i, mode64);
   6393    vpanic("emit_PPCInstr");
   6394    /*NOTREACHED*/
   6395 
   6396   done:
   6397    vassert(p - &buf[0] <= 64);
   6398    return p - &buf[0];
   6399 }
   6400 
   6401 
   6402 /* How big is an event check?  See case for Pin_EvCheck in
   6403    emit_PPCInstr just above.  That crosschecks what this returns, so
   6404    we can tell if we're inconsistent. */
   6405 Int evCheckSzB_PPC (void)
   6406 {
   6407   return 28;
   6408 }
   6409 
   6410 
   6411 /* NB: what goes on here has to be very closely coordinated with the
   6412    emitInstr case for XDirect, above. */
   6413 VexInvalRange chainXDirect_PPC ( VexEndness endness_host,
   6414                                  void* place_to_chain,
   6415                                  const void* disp_cp_chain_me_EXPECTED,
   6416                                  const void* place_to_jump_to,
   6417                                  Bool  mode64 )
   6418 {
   6419    if (mode64) {
   6420       vassert((endness_host == VexEndnessBE) ||
   6421               (endness_host == VexEndnessLE));
   6422    } else {
   6423       vassert(endness_host == VexEndnessBE);
   6424    }
   6425 
   6426    /* What we're expecting to see is:
   6427         imm32/64-fixed r30, disp_cp_chain_me_to_EXPECTED
   6428         mtctr r30
   6429         bctrl
   6430       viz
   6431         <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
   6432         7F C9 03 A6
   6433         4E 80 04 21
   6434    */
   6435    UChar* p = (UChar*)place_to_chain;
   6436    vassert(0 == (3 & (HWord)p));
   6437    vassert(isLoadImm_EXACTLY2or5(p, /*r*/30,
   6438                                  (Addr)disp_cp_chain_me_EXPECTED,
   6439                                  mode64, endness_host));
   6440    vassert(fetch32(p + (mode64 ? 20 : 8) + 0, endness_host) == 0x7FC903A6);
   6441    vassert(fetch32(p + (mode64 ? 20 : 8) + 4, endness_host) == 0x4E800421);
   6442    /* And what we want to change it to is:
   6443         imm32/64-fixed r30, place_to_jump_to
   6444         mtctr r30
   6445         bctr
   6446       viz
   6447         <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
   6448         7F C9 03 A6
   6449         4E 80 04 20
   6450       The replacement has the same length as the original.
   6451    */
   6452    p = mkLoadImm_EXACTLY2or5(p, /*r*/30,
   6453                              (Addr)place_to_jump_to, mode64,
   6454                              endness_host);
   6455    p = emit32(p, 0x7FC903A6, endness_host);
   6456    p = emit32(p, 0x4E800420, endness_host);
   6457 
   6458    Int len = p - (UChar*)place_to_chain;
   6459    vassert(len == (mode64 ? 28 : 16)); /* stay sane */
   6460    VexInvalRange vir = {(HWord)place_to_chain, len};
   6461    return vir;
   6462 }
   6463 
   6464 
   6465 /* NB: what goes on here has to be very closely coordinated with the
   6466    emitInstr case for XDirect, above. */
   6467 VexInvalRange unchainXDirect_PPC ( VexEndness endness_host,
   6468                                    void* place_to_unchain,
   6469                                    const void* place_to_jump_to_EXPECTED,
   6470                                    const void* disp_cp_chain_me,
   6471                                    Bool  mode64 )
   6472 {
   6473    if (mode64) {
   6474       vassert((endness_host == VexEndnessBE) ||
   6475               (endness_host == VexEndnessLE));
   6476    } else {
   6477       vassert(endness_host == VexEndnessBE);
   6478    }
   6479 
   6480    /* What we're expecting to see is:
   6481         imm32/64-fixed r30, place_to_jump_to_EXPECTED
   6482         mtctr r30
   6483         bctr
   6484       viz
   6485         <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
   6486         7F C9 03 A6
   6487         4E 80 04 20
   6488    */
   6489    UChar* p = (UChar*)place_to_unchain;
   6490    vassert(0 == (3 & (HWord)p));
   6491    vassert(isLoadImm_EXACTLY2or5(p, /*r*/30,
   6492                                  (Addr)place_to_jump_to_EXPECTED,
   6493                                  mode64, endness_host));
   6494    vassert(fetch32(p + (mode64 ? 20 : 8) + 0, endness_host) == 0x7FC903A6);
   6495    vassert(fetch32(p + (mode64 ? 20 : 8) + 4, endness_host) == 0x4E800420);
   6496    /* And what we want to change it to is:
   6497         imm32/64-fixed r30, disp_cp_chain_me
   6498         mtctr r30
   6499         bctrl
   6500       viz
   6501         <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
   6502         7F C9 03 A6
   6503         4E 80 04 21
   6504       The replacement has the same length as the original.
   6505    */
   6506    p = mkLoadImm_EXACTLY2or5(p, /*r*/30,
   6507                              (Addr)disp_cp_chain_me, mode64,
   6508                              endness_host);
   6509    p = emit32(p, 0x7FC903A6, endness_host);
   6510    p = emit32(p, 0x4E800421, endness_host);
   6511 
   6512    Int len = p - (UChar*)place_to_unchain;
   6513    vassert(len == (mode64 ? 28 : 16)); /* stay sane */
   6514    VexInvalRange vir = {(HWord)place_to_unchain, len};
   6515    return vir;
   6516 }
   6517 
   6518 
   6519 /* Patch the counter address into a profile inc point, as previously
   6520    created by the Pin_ProfInc case for emit_PPCInstr. */
   6521 VexInvalRange patchProfInc_PPC ( VexEndness endness_host,
   6522                                  void*  place_to_patch,
   6523                                  const ULong* location_of_counter,
   6524                                  Bool   mode64 )
   6525 {
   6526    if (mode64) {
   6527       vassert((endness_host == VexEndnessBE) ||
   6528               (endness_host == VexEndnessLE));
   6529    } else {
   6530       vassert(endness_host == VexEndnessBE);
   6531    }
   6532 
   6533    UChar* p = (UChar*)place_to_patch;
   6534    vassert(0 == (3 & (HWord)p));
   6535 
   6536    Int len = 0;
   6537    if (mode64) {
   6538       vassert(isLoadImm_EXACTLY2or5(p, /*r*/30,
   6539                                     0x6555655565556555ULL, True/*mode64*/,
   6540                                     endness_host));
   6541       vassert(fetch32(p + 20, endness_host) == 0xEBBE0000);
   6542       vassert(fetch32(p + 24, endness_host) == 0x3BBD0001);
   6543       vassert(fetch32(p + 28, endness_host) == 0xFBBE0000);
   6544       p = mkLoadImm_EXACTLY2or5(p, /*r*/30,
   6545                                 (Addr)location_of_counter,
   6546                                 True/*mode64*/, endness_host);
   6547       len = p - (UChar*)place_to_patch;
   6548       vassert(len == 20);
   6549    } else {
   6550       vassert(isLoadImm_EXACTLY2or5(p, /*r*/30,
   6551                                     0x65556555ULL, False/*!mode64*/,
   6552                                     endness_host));
   6553       vassert(fetch32(p +  8, endness_host) == 0x83BE0004);
   6554       vassert(fetch32(p + 12, endness_host) == 0x37BD0001);
   6555       vassert(fetch32(p + 16, endness_host) == 0x93BE0004);
   6556       vassert(fetch32(p + 20, endness_host) == 0x83BE0000);
   6557       vassert(fetch32(p + 24, endness_host) == 0x7FBD0194);
   6558       vassert(fetch32(p + 28, endness_host) == 0x93BE0000);
   6559       p = mkLoadImm_EXACTLY2or5(p, /*r*/30,
   6560                                 (Addr)location_of_counter,
   6561                                 False/*!mode64*/, endness_host);
   6562       len = p - (UChar*)place_to_patch;
   6563       vassert(len == 8);
   6564    }
   6565    VexInvalRange vir = {(HWord)place_to_patch, len};
   6566    return vir;
   6567 }
   6568 
   6569 
   6570 /*---------------------------------------------------------------*/
   6571 /*--- end                                     host_ppc_defs.c ---*/
   6572 /*---------------------------------------------------------------*/
   6573