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-2010 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 void ppHRegPPC ( HReg reg )
     48 {
     49    Int r;
     50    static HChar* ireg32_names[32]
     51       = { "%r0",  "%r1",  "%r2",  "%r3",
     52           "%r4",  "%r5",  "%r6",  "%r7",
     53           "%r8",  "%r9",  "%r10", "%r11",
     54           "%r12", "%r13", "%r14", "%r15",
     55           "%r16", "%r17", "%r18", "%r19",
     56           "%r20", "%r21", "%r22", "%r23",
     57           "%r24", "%r25", "%r26", "%r27",
     58           "%r28", "%r29", "%r30", "%r31" };
     59    /* Be generic for all virtual regs. */
     60    if (hregIsVirtual(reg)) {
     61       ppHReg(reg);
     62       return;
     63    }
     64    /* But specific for real regs. */
     65    switch (hregClass(reg)) {
     66    case HRcInt64:
     67       r = hregNumber(reg);
     68       vassert(r >= 0 && r < 32);
     69       vex_printf("%s", ireg32_names[r]);
     70       return;
     71    case HRcInt32:
     72       r = hregNumber(reg);
     73       vassert(r >= 0 && r < 32);
     74       vex_printf("%s", ireg32_names[r]);
     75       return;
     76    case HRcFlt64:
     77       r = hregNumber(reg);
     78       vassert(r >= 0 && r < 32);
     79       vex_printf("%%fr%d", r);
     80       return;
     81    case HRcVec128:
     82       r = hregNumber(reg);
     83       vassert(r >= 0 && r < 32);
     84       vex_printf("%%v%d", r);
     85       return;
     86    default:
     87       vpanic("ppHRegPPC");
     88    }
     89 }
     90 
     91 
     92 #define MkHRegGPR(_n, _mode64) \
     93    mkHReg(_n, _mode64 ? HRcInt64 : HRcInt32, False)
     94 
     95 HReg hregPPC_GPR0  ( Bool mode64 ) { return MkHRegGPR( 0, mode64); }
     96 HReg hregPPC_GPR1  ( Bool mode64 ) { return MkHRegGPR( 1, mode64); }
     97 HReg hregPPC_GPR2  ( Bool mode64 ) { return MkHRegGPR( 2, mode64); }
     98 HReg hregPPC_GPR3  ( Bool mode64 ) { return MkHRegGPR( 3, mode64); }
     99 HReg hregPPC_GPR4  ( Bool mode64 ) { return MkHRegGPR( 4, mode64); }
    100 HReg hregPPC_GPR5  ( Bool mode64 ) { return MkHRegGPR( 5, mode64); }
    101 HReg hregPPC_GPR6  ( Bool mode64 ) { return MkHRegGPR( 6, mode64); }
    102 HReg hregPPC_GPR7  ( Bool mode64 ) { return MkHRegGPR( 7, mode64); }
    103 HReg hregPPC_GPR8  ( Bool mode64 ) { return MkHRegGPR( 8, mode64); }
    104 HReg hregPPC_GPR9  ( Bool mode64 ) { return MkHRegGPR( 9, mode64); }
    105 HReg hregPPC_GPR10 ( Bool mode64 ) { return MkHRegGPR(10, mode64); }
    106 HReg hregPPC_GPR11 ( Bool mode64 ) { return MkHRegGPR(11, mode64); }
    107 HReg hregPPC_GPR12 ( Bool mode64 ) { return MkHRegGPR(12, mode64); }
    108 HReg hregPPC_GPR13 ( Bool mode64 ) { return MkHRegGPR(13, mode64); }
    109 HReg hregPPC_GPR14 ( Bool mode64 ) { return MkHRegGPR(14, mode64); }
    110 HReg hregPPC_GPR15 ( Bool mode64 ) { return MkHRegGPR(15, mode64); }
    111 HReg hregPPC_GPR16 ( Bool mode64 ) { return MkHRegGPR(16, mode64); }
    112 HReg hregPPC_GPR17 ( Bool mode64 ) { return MkHRegGPR(17, mode64); }
    113 HReg hregPPC_GPR18 ( Bool mode64 ) { return MkHRegGPR(18, mode64); }
    114 HReg hregPPC_GPR19 ( Bool mode64 ) { return MkHRegGPR(19, mode64); }
    115 HReg hregPPC_GPR20 ( Bool mode64 ) { return MkHRegGPR(20, mode64); }
    116 HReg hregPPC_GPR21 ( Bool mode64 ) { return MkHRegGPR(21, mode64); }
    117 HReg hregPPC_GPR22 ( Bool mode64 ) { return MkHRegGPR(22, mode64); }
    118 HReg hregPPC_GPR23 ( Bool mode64 ) { return MkHRegGPR(23, mode64); }
    119 HReg hregPPC_GPR24 ( Bool mode64 ) { return MkHRegGPR(24, mode64); }
    120 HReg hregPPC_GPR25 ( Bool mode64 ) { return MkHRegGPR(25, mode64); }
    121 HReg hregPPC_GPR26 ( Bool mode64 ) { return MkHRegGPR(26, mode64); }
    122 HReg hregPPC_GPR27 ( Bool mode64 ) { return MkHRegGPR(27, mode64); }
    123 HReg hregPPC_GPR28 ( Bool mode64 ) { return MkHRegGPR(28, mode64); }
    124 HReg hregPPC_GPR29 ( Bool mode64 ) { return MkHRegGPR(29, mode64); }
    125 HReg hregPPC_GPR30 ( Bool mode64 ) { return MkHRegGPR(30, mode64); }
    126 HReg hregPPC_GPR31 ( Bool mode64 ) { return MkHRegGPR(31, mode64); }
    127 
    128 #undef MK_INT_HREG
    129 
    130 HReg hregPPC_FPR0  ( void ) { return mkHReg( 0, HRcFlt64, False); }
    131 HReg hregPPC_FPR1  ( void ) { return mkHReg( 1, HRcFlt64, False); }
    132 HReg hregPPC_FPR2  ( void ) { return mkHReg( 2, HRcFlt64, False); }
    133 HReg hregPPC_FPR3  ( void ) { return mkHReg( 3, HRcFlt64, False); }
    134 HReg hregPPC_FPR4  ( void ) { return mkHReg( 4, HRcFlt64, False); }
    135 HReg hregPPC_FPR5  ( void ) { return mkHReg( 5, HRcFlt64, False); }
    136 HReg hregPPC_FPR6  ( void ) { return mkHReg( 6, HRcFlt64, False); }
    137 HReg hregPPC_FPR7  ( void ) { return mkHReg( 7, HRcFlt64, False); }
    138 HReg hregPPC_FPR8  ( void ) { return mkHReg( 8, HRcFlt64, False); }
    139 HReg hregPPC_FPR9  ( void ) { return mkHReg( 9, HRcFlt64, False); }
    140 HReg hregPPC_FPR10 ( void ) { return mkHReg(10, HRcFlt64, False); }
    141 HReg hregPPC_FPR11 ( void ) { return mkHReg(11, HRcFlt64, False); }
    142 HReg hregPPC_FPR12 ( void ) { return mkHReg(12, HRcFlt64, False); }
    143 HReg hregPPC_FPR13 ( void ) { return mkHReg(13, HRcFlt64, False); }
    144 HReg hregPPC_FPR14 ( void ) { return mkHReg(14, HRcFlt64, False); }
    145 HReg hregPPC_FPR15 ( void ) { return mkHReg(15, HRcFlt64, False); }
    146 HReg hregPPC_FPR16 ( void ) { return mkHReg(16, HRcFlt64, False); }
    147 HReg hregPPC_FPR17 ( void ) { return mkHReg(17, HRcFlt64, False); }
    148 HReg hregPPC_FPR18 ( void ) { return mkHReg(18, HRcFlt64, False); }
    149 HReg hregPPC_FPR19 ( void ) { return mkHReg(19, HRcFlt64, False); }
    150 HReg hregPPC_FPR20 ( void ) { return mkHReg(20, HRcFlt64, False); }
    151 HReg hregPPC_FPR21 ( void ) { return mkHReg(21, HRcFlt64, False); }
    152 HReg hregPPC_FPR22 ( void ) { return mkHReg(22, HRcFlt64, False); }
    153 HReg hregPPC_FPR23 ( void ) { return mkHReg(23, HRcFlt64, False); }
    154 HReg hregPPC_FPR24 ( void ) { return mkHReg(24, HRcFlt64, False); }
    155 HReg hregPPC_FPR25 ( void ) { return mkHReg(25, HRcFlt64, False); }
    156 HReg hregPPC_FPR26 ( void ) { return mkHReg(26, HRcFlt64, False); }
    157 HReg hregPPC_FPR27 ( void ) { return mkHReg(27, HRcFlt64, False); }
    158 HReg hregPPC_FPR28 ( void ) { return mkHReg(28, HRcFlt64, False); }
    159 HReg hregPPC_FPR29 ( void ) { return mkHReg(29, HRcFlt64, False); }
    160 HReg hregPPC_FPR30 ( void ) { return mkHReg(30, HRcFlt64, False); }
    161 HReg hregPPC_FPR31 ( void ) { return mkHReg(31, HRcFlt64, False); }
    162 
    163 HReg hregPPC_VR0  ( void ) { return mkHReg( 0, HRcVec128, False); }
    164 HReg hregPPC_VR1  ( void ) { return mkHReg( 1, HRcVec128, False); }
    165 HReg hregPPC_VR2  ( void ) { return mkHReg( 2, HRcVec128, False); }
    166 HReg hregPPC_VR3  ( void ) { return mkHReg( 3, HRcVec128, False); }
    167 HReg hregPPC_VR4  ( void ) { return mkHReg( 4, HRcVec128, False); }
    168 HReg hregPPC_VR5  ( void ) { return mkHReg( 5, HRcVec128, False); }
    169 HReg hregPPC_VR6  ( void ) { return mkHReg( 6, HRcVec128, False); }
    170 HReg hregPPC_VR7  ( void ) { return mkHReg( 7, HRcVec128, False); }
    171 HReg hregPPC_VR8  ( void ) { return mkHReg( 8, HRcVec128, False); }
    172 HReg hregPPC_VR9  ( void ) { return mkHReg( 9, HRcVec128, False); }
    173 HReg hregPPC_VR10 ( void ) { return mkHReg(10, HRcVec128, False); }
    174 HReg hregPPC_VR11 ( void ) { return mkHReg(11, HRcVec128, False); }
    175 HReg hregPPC_VR12 ( void ) { return mkHReg(12, HRcVec128, False); }
    176 HReg hregPPC_VR13 ( void ) { return mkHReg(13, HRcVec128, False); }
    177 HReg hregPPC_VR14 ( void ) { return mkHReg(14, HRcVec128, False); }
    178 HReg hregPPC_VR15 ( void ) { return mkHReg(15, HRcVec128, False); }
    179 HReg hregPPC_VR16 ( void ) { return mkHReg(16, HRcVec128, False); }
    180 HReg hregPPC_VR17 ( void ) { return mkHReg(17, HRcVec128, False); }
    181 HReg hregPPC_VR18 ( void ) { return mkHReg(18, HRcVec128, False); }
    182 HReg hregPPC_VR19 ( void ) { return mkHReg(19, HRcVec128, False); }
    183 HReg hregPPC_VR20 ( void ) { return mkHReg(20, HRcVec128, False); }
    184 HReg hregPPC_VR21 ( void ) { return mkHReg(21, HRcVec128, False); }
    185 HReg hregPPC_VR22 ( void ) { return mkHReg(22, HRcVec128, False); }
    186 HReg hregPPC_VR23 ( void ) { return mkHReg(23, HRcVec128, False); }
    187 HReg hregPPC_VR24 ( void ) { return mkHReg(24, HRcVec128, False); }
    188 HReg hregPPC_VR25 ( void ) { return mkHReg(25, HRcVec128, False); }
    189 HReg hregPPC_VR26 ( void ) { return mkHReg(26, HRcVec128, False); }
    190 HReg hregPPC_VR27 ( void ) { return mkHReg(27, HRcVec128, False); }
    191 HReg hregPPC_VR28 ( void ) { return mkHReg(28, HRcVec128, False); }
    192 HReg hregPPC_VR29 ( void ) { return mkHReg(29, HRcVec128, False); }
    193 HReg hregPPC_VR30 ( void ) { return mkHReg(30, HRcVec128, False); }
    194 HReg hregPPC_VR31 ( void ) { return mkHReg(31, HRcVec128, False); }
    195 
    196 void getAllocableRegs_PPC ( Int* nregs, HReg** arr, Bool mode64 )
    197 {
    198    UInt i=0;
    199    if (mode64)
    200       *nregs = (32-9) + (32-24) + (32-24);
    201    else
    202       *nregs = (32-7) + (32-24) + (32-24);
    203    *arr = LibVEX_Alloc(*nregs * sizeof(HReg));
    204    // GPR0 = scratch reg where poss. - some ops interpret as value zero
    205    // GPR1 = stack pointer
    206    // GPR2 = TOC pointer
    207    (*arr)[i++] = hregPPC_GPR3(mode64);
    208    (*arr)[i++] = hregPPC_GPR4(mode64);
    209    (*arr)[i++] = hregPPC_GPR5(mode64);
    210    (*arr)[i++] = hregPPC_GPR6(mode64);
    211    (*arr)[i++] = hregPPC_GPR7(mode64);
    212    (*arr)[i++] = hregPPC_GPR8(mode64);
    213    (*arr)[i++] = hregPPC_GPR9(mode64);
    214    (*arr)[i++] = hregPPC_GPR10(mode64);
    215    if (!mode64) {
    216       /* in mode64:
    217          r11 used for calls by ptr / env ptr for some langs
    218          r12 used for exception handling and global linkage code */
    219       (*arr)[i++] = hregPPC_GPR11(mode64);
    220       (*arr)[i++] = hregPPC_GPR12(mode64);
    221    }
    222    // GPR13 = thread specific pointer
    223    // GPR14 and above are callee save.  Yay.
    224    (*arr)[i++] = hregPPC_GPR14(mode64);
    225    (*arr)[i++] = hregPPC_GPR15(mode64);
    226    (*arr)[i++] = hregPPC_GPR16(mode64);
    227    (*arr)[i++] = hregPPC_GPR17(mode64);
    228    (*arr)[i++] = hregPPC_GPR18(mode64);
    229    (*arr)[i++] = hregPPC_GPR19(mode64);
    230    (*arr)[i++] = hregPPC_GPR20(mode64);
    231    (*arr)[i++] = hregPPC_GPR21(mode64);
    232    (*arr)[i++] = hregPPC_GPR22(mode64);
    233    (*arr)[i++] = hregPPC_GPR23(mode64);
    234    (*arr)[i++] = hregPPC_GPR24(mode64);
    235    (*arr)[i++] = hregPPC_GPR25(mode64);
    236    (*arr)[i++] = hregPPC_GPR26(mode64);
    237    (*arr)[i++] = hregPPC_GPR27(mode64);
    238    (*arr)[i++] = hregPPC_GPR28(mode64);
    239    // GPR29 is reserved for the dispatcher
    240    // GPR30 is reserved as AltiVec spill reg temporary
    241    // GPR31 is reserved for the GuestStatePtr
    242 
    243    /* Don't waste the reg-allocs's time trawling through zillions of
    244       FP registers - they mostly will never be used.  We'll tolerate
    245       the occasional extra spill instead. */
    246    /* For both ppc32-linux and ppc64-linux, f14-f31 are callee save.
    247       So use them. */
    248    (*arr)[i++] = hregPPC_FPR14();
    249    (*arr)[i++] = hregPPC_FPR15();
    250    (*arr)[i++] = hregPPC_FPR16();
    251    (*arr)[i++] = hregPPC_FPR17();
    252    (*arr)[i++] = hregPPC_FPR18();
    253    (*arr)[i++] = hregPPC_FPR19();
    254    (*arr)[i++] = hregPPC_FPR20();
    255    (*arr)[i++] = hregPPC_FPR21();
    256 
    257    /* Same deal re Altivec */
    258    /* For both ppc32-linux and ppc64-linux, v20-v31 are callee save.
    259       So use them. */
    260    /* NB, vr29 is used as a scratch temporary -- do not allocate */
    261    (*arr)[i++] = hregPPC_VR20();
    262    (*arr)[i++] = hregPPC_VR21();
    263    (*arr)[i++] = hregPPC_VR22();
    264    (*arr)[i++] = hregPPC_VR23();
    265    (*arr)[i++] = hregPPC_VR24();
    266    (*arr)[i++] = hregPPC_VR25();
    267    (*arr)[i++] = hregPPC_VR26();
    268    (*arr)[i++] = hregPPC_VR27();
    269 
    270    vassert(i == *nregs);
    271 }
    272 
    273 
    274 /* --------- Condition codes, Intel encoding. --------- */
    275 
    276 HChar* showPPCCondCode ( PPCCondCode cond )
    277 {
    278    if (cond.test == Pct_ALWAYS) return "always";
    279 
    280    switch (cond.flag) {
    281    case Pcf_7SO:
    282       return (cond.test == Pct_TRUE) ? "cr7.so=1" : "cr7.so=0";
    283    case Pcf_7EQ:
    284       return (cond.test == Pct_TRUE) ? "cr7.eq=1" : "cr7.eq=0";
    285    case Pcf_7GT:
    286       return (cond.test == Pct_TRUE) ? "cr7.gt=1" : "cr7.gt=0";
    287    case Pcf_7LT:
    288       return (cond.test == Pct_TRUE) ? "cr7.lt=1" : "cr7.lt=0";
    289    default: vpanic("ppPPCCondCode");
    290    }
    291 }
    292 
    293 /* construct condition code */
    294 PPCCondCode mk_PPCCondCode ( PPCCondTest test, PPCCondFlag flag )
    295 {
    296    PPCCondCode cc;
    297    cc.flag = flag;
    298    cc.test = test;
    299    return cc;
    300 }
    301 
    302 /* false->true, true->false */
    303 PPCCondTest invertCondTest ( PPCCondTest ct )
    304 {
    305    vassert(ct != Pct_ALWAYS);
    306    return (ct == Pct_TRUE) ? Pct_FALSE : Pct_TRUE;
    307 }
    308 
    309 
    310 /* --------- PPCAMode: memory address expressions. --------- */
    311 
    312 PPCAMode* PPCAMode_IR ( Int idx, HReg base ) {
    313    PPCAMode* am = LibVEX_Alloc(sizeof(PPCAMode));
    314    vassert(idx >= -0x8000 && idx < 0x8000);
    315    am->tag = Pam_IR;
    316    am->Pam.IR.base = base;
    317    am->Pam.IR.index = idx;
    318    return am;
    319 }
    320 PPCAMode* PPCAMode_RR ( HReg idx, HReg base ) {
    321    PPCAMode* am = LibVEX_Alloc(sizeof(PPCAMode));
    322    am->tag = Pam_RR;
    323    am->Pam.RR.base = base;
    324    am->Pam.RR.index = idx;
    325    return am;
    326 }
    327 
    328 PPCAMode* dopyPPCAMode ( PPCAMode* am ) {
    329    switch (am->tag) {
    330    case Pam_IR:
    331       return PPCAMode_IR( am->Pam.IR.index, am->Pam.IR.base );
    332    case Pam_RR:
    333       return PPCAMode_RR( am->Pam.RR.index, am->Pam.RR.base );
    334    default:
    335       vpanic("dopyPPCAMode");
    336    }
    337 }
    338 
    339 void ppPPCAMode ( PPCAMode* am ) {
    340    switch (am->tag) {
    341    case Pam_IR:
    342       if (am->Pam.IR.index == 0)
    343          vex_printf("0(");
    344       else
    345          vex_printf("%d(", (Int)am->Pam.IR.index);
    346       ppHRegPPC(am->Pam.IR.base);
    347       vex_printf(")");
    348       return;
    349    case Pam_RR:
    350       ppHRegPPC(am->Pam.RR.base);
    351       vex_printf(",");
    352       ppHRegPPC(am->Pam.RR.index);
    353       return;
    354    default:
    355       vpanic("ppPPCAMode");
    356    }
    357 }
    358 
    359 static void addRegUsage_PPCAMode ( HRegUsage* u, PPCAMode* am ) {
    360    switch (am->tag) {
    361    case Pam_IR:
    362       addHRegUse(u, HRmRead, am->Pam.IR.base);
    363       return;
    364    case Pam_RR:
    365       addHRegUse(u, HRmRead, am->Pam.RR.base);
    366       addHRegUse(u, HRmRead, am->Pam.RR.index);
    367       return;
    368    default:
    369       vpanic("addRegUsage_PPCAMode");
    370    }
    371 }
    372 
    373 static void mapRegs_PPCAMode ( HRegRemap* m, PPCAMode* am ) {
    374    switch (am->tag) {
    375    case Pam_IR:
    376       am->Pam.IR.base = lookupHRegRemap(m, am->Pam.IR.base);
    377       return;
    378    case Pam_RR:
    379       am->Pam.RR.base = lookupHRegRemap(m, am->Pam.RR.base);
    380       am->Pam.RR.index = lookupHRegRemap(m, am->Pam.RR.index);
    381       return;
    382    default:
    383       vpanic("mapRegs_PPCAMode");
    384    }
    385 }
    386 
    387 /* --------- Operand, which can be a reg or a u16/s16. --------- */
    388 
    389 PPCRH* PPCRH_Imm ( Bool syned, UShort imm16 ) {
    390    PPCRH* op         = LibVEX_Alloc(sizeof(PPCRH));
    391    op->tag           = Prh_Imm;
    392    op->Prh.Imm.syned = syned;
    393    op->Prh.Imm.imm16 = imm16;
    394    /* If this is a signed value, ensure it's not -32768, so that we
    395       are guaranteed always to be able to negate if needed. */
    396    if (syned)
    397       vassert(imm16 != 0x8000);
    398    vassert(syned == True || syned == False);
    399    return op;
    400 }
    401 PPCRH* PPCRH_Reg ( HReg reg ) {
    402    PPCRH* op       = LibVEX_Alloc(sizeof(PPCRH));
    403    op->tag         = Prh_Reg;
    404    op->Prh.Reg.reg = reg;
    405    return op;
    406 }
    407 
    408 void ppPPCRH ( PPCRH* op ) {
    409    switch (op->tag) {
    410    case Prh_Imm:
    411       if (op->Prh.Imm.syned)
    412          vex_printf("%d", (Int)(Short)op->Prh.Imm.imm16);
    413       else
    414          vex_printf("%u", (UInt)(UShort)op->Prh.Imm.imm16);
    415       return;
    416    case Prh_Reg:
    417       ppHRegPPC(op->Prh.Reg.reg);
    418       return;
    419    default:
    420       vpanic("ppPPCRH");
    421    }
    422 }
    423 
    424 /* An PPCRH can only be used in a "read" context (what would it mean
    425    to write or modify a literal?) and so we enumerate its registers
    426    accordingly. */
    427 static void addRegUsage_PPCRH ( HRegUsage* u, PPCRH* op ) {
    428    switch (op->tag) {
    429    case Prh_Imm:
    430       return;
    431    case Prh_Reg:
    432       addHRegUse(u, HRmRead, op->Prh.Reg.reg);
    433       return;
    434    default:
    435       vpanic("addRegUsage_PPCRH");
    436    }
    437 }
    438 
    439 static void mapRegs_PPCRH ( HRegRemap* m, PPCRH* op ) {
    440    switch (op->tag) {
    441    case Prh_Imm:
    442       return;
    443    case Prh_Reg:
    444       op->Prh.Reg.reg = lookupHRegRemap(m, op->Prh.Reg.reg);
    445       return;
    446    default:
    447       vpanic("mapRegs_PPCRH");
    448    }
    449 }
    450 
    451 
    452 /* --------- Operand, which can be a reg or a u32/64. --------- */
    453 
    454 PPCRI* PPCRI_Imm ( ULong imm64 ) {
    455    PPCRI* op   = LibVEX_Alloc(sizeof(PPCRI));
    456    op->tag     = Pri_Imm;
    457    op->Pri.Imm = imm64;
    458    return op;
    459 }
    460 PPCRI* PPCRI_Reg ( HReg reg ) {
    461    PPCRI* op   = LibVEX_Alloc(sizeof(PPCRI));
    462    op->tag     = Pri_Reg;
    463    op->Pri.Reg = reg;
    464    return op;
    465 }
    466 
    467 void ppPPCRI ( PPCRI* dst ) {
    468    switch (dst->tag) {
    469       case Pri_Imm:
    470          vex_printf("0x%llx", dst->Pri.Imm);
    471          break;
    472       case Pri_Reg:
    473          ppHRegPPC(dst->Pri.Reg);
    474          break;
    475       default:
    476          vpanic("ppPPCRI");
    477    }
    478 }
    479 
    480 /* An PPCRI can only be used in a "read" context (what would it
    481    mean to write or modify a literal?) and so we enumerate its
    482    registers accordingly. */
    483 static void addRegUsage_PPCRI ( HRegUsage* u, PPCRI* dst ) {
    484    switch (dst->tag) {
    485       case Pri_Imm:
    486          return;
    487       case Pri_Reg:
    488          addHRegUse(u, HRmRead, dst->Pri.Reg);
    489          return;
    490       default:
    491          vpanic("addRegUsage_PPCRI");
    492    }
    493 }
    494 
    495 static void mapRegs_PPCRI ( HRegRemap* m, PPCRI* dst ) {
    496    switch (dst->tag) {
    497       case Pri_Imm:
    498          return;
    499       case Pri_Reg:
    500          dst->Pri.Reg = lookupHRegRemap(m, dst->Pri.Reg);
    501          return;
    502       default:
    503          vpanic("mapRegs_PPCRI");
    504    }
    505 }
    506 
    507 
    508 /* --------- Operand, which can be a vector reg or a simm5. --------- */
    509 
    510 PPCVI5s* PPCVI5s_Imm ( Char simm5 ) {
    511    PPCVI5s* op   = LibVEX_Alloc(sizeof(PPCVI5s));
    512    op->tag       = Pvi_Imm;
    513    op->Pvi.Imm5s = simm5;
    514    vassert(simm5 >= -16 && simm5 <= 15);
    515    return op;
    516 }
    517 PPCVI5s* PPCVI5s_Reg ( HReg reg ) {
    518    PPCVI5s* op = LibVEX_Alloc(sizeof(PPCVI5s));
    519    op->tag     = Pvi_Reg;
    520    op->Pvi.Reg = reg;
    521    vassert(hregClass(reg) == HRcVec128);
    522    return op;
    523 }
    524 
    525 void ppPPCVI5s ( PPCVI5s* src ) {
    526    switch (src->tag) {
    527       case Pvi_Imm:
    528          vex_printf("%d", (Int)src->Pvi.Imm5s);
    529          break;
    530       case Pvi_Reg:
    531          ppHRegPPC(src->Pvi.Reg);
    532          break;
    533       default:
    534          vpanic("ppPPCVI5s");
    535    }
    536 }
    537 
    538 /* An PPCVI5s can only be used in a "read" context (what would it
    539    mean to write or modify a literal?) and so we enumerate its
    540    registers accordingly. */
    541 static void addRegUsage_PPCVI5s ( HRegUsage* u, PPCVI5s* dst ) {
    542    switch (dst->tag) {
    543       case Pvi_Imm:
    544          return;
    545       case Pvi_Reg:
    546          addHRegUse(u, HRmRead, dst->Pvi.Reg);
    547          return;
    548       default:
    549          vpanic("addRegUsage_PPCVI5s");
    550    }
    551 }
    552 
    553 static void mapRegs_PPCVI5s ( HRegRemap* m, PPCVI5s* dst ) {
    554    switch (dst->tag) {
    555       case Pvi_Imm:
    556          return;
    557       case Pvi_Reg:
    558          dst->Pvi.Reg = lookupHRegRemap(m, dst->Pvi.Reg);
    559          return;
    560       default:
    561          vpanic("mapRegs_PPCVI5s");
    562    }
    563 }
    564 
    565 
    566 /* --------- Instructions. --------- */
    567 
    568 HChar* showPPCUnaryOp ( PPCUnaryOp op ) {
    569    switch (op) {
    570    case Pun_NOT:   return "not";
    571    case Pun_NEG:   return "neg";
    572    case Pun_CLZ32: return "cntlzw";
    573    case Pun_CLZ64: return "cntlzd";
    574    case Pun_EXTSW: return "extsw";
    575    default: vpanic("showPPCUnaryOp");
    576    }
    577 }
    578 
    579 HChar* showPPCAluOp ( PPCAluOp op, Bool immR ) {
    580    switch (op) {
    581       case Palu_ADD: return immR ? "addi"  : "add";
    582       case Palu_SUB: return immR ? "subi"  : "sub";
    583       case Palu_AND: return immR ? "andi." : "and";
    584       case Palu_OR:  return immR ? "ori"   : "or";
    585       case Palu_XOR: return immR ? "xori"  : "xor";
    586       default: vpanic("showPPCAluOp");
    587    }
    588 }
    589 
    590 HChar* showPPCShftOp ( PPCShftOp op, Bool immR, Bool sz32 ) {
    591    switch (op) {
    592       case Pshft_SHL: return sz32 ? (immR ? "slwi"  : "slw") :
    593                                     (immR ? "sldi"  : "sld");
    594       case Pshft_SHR: return sz32 ? (immR ? "srwi"  : "srw") :
    595                                     (immR ? "srdi"  : "srd");
    596       case Pshft_SAR: return sz32 ? (immR ? "srawi" : "sraw") :
    597                                     (immR ? "sradi" : "srad");
    598       default: vpanic("showPPCShftOp");
    599    }
    600 }
    601 
    602 HChar* showPPCFpOp ( PPCFpOp op ) {
    603    switch (op) {
    604       case Pfp_ADDD:   return "fadd";
    605       case Pfp_SUBD:   return "fsub";
    606       case Pfp_MULD:   return "fmul";
    607       case Pfp_DIVD:   return "fdiv";
    608       case Pfp_MADDD:  return "fmadd";
    609       case Pfp_MSUBD:  return "fmsub";
    610       case Pfp_MADDS:  return "fmadds";
    611       case Pfp_MSUBS:  return "fmsubs";
    612       case Pfp_ADDS:   return "fadds";
    613       case Pfp_SUBS:   return "fsubs";
    614       case Pfp_MULS:   return "fmuls";
    615       case Pfp_DIVS:   return "fdivs";
    616       case Pfp_SQRT:   return "fsqrt";
    617       case Pfp_ABS:    return "fabs";
    618       case Pfp_NEG:    return "fneg";
    619       case Pfp_MOV:    return "fmr";
    620       case Pfp_RES:    return "fres";
    621       case Pfp_RSQRTE: return "frsqrte";
    622       case Pfp_FRIM:   return "frim";
    623       case Pfp_FRIN:   return "frin";
    624       case Pfp_FRIP:   return "frip";
    625       case Pfp_FRIZ:   return "friz";
    626       default: vpanic("showPPCFpOp");
    627    }
    628 }
    629 
    630 HChar* showPPCAvOp ( PPCAvOp op ) {
    631    switch (op) {
    632 
    633    /* Unary */
    634    case Pav_MOV:       return "vmr";      /* Mov */
    635 
    636    case Pav_AND:       return "vand";     /* Bitwise */
    637    case Pav_OR:        return "vor";
    638    case Pav_XOR:       return "vxor";
    639    case Pav_NOT:       return "vnot";
    640 
    641    case Pav_UNPCKH8S:  return "vupkhsb";  /* Unpack */
    642    case Pav_UNPCKH16S: return "vupkhsh";
    643    case Pav_UNPCKL8S:  return "vupklsb";
    644    case Pav_UNPCKL16S: return "vupklsh";
    645    case Pav_UNPCKHPIX: return "vupkhpx";
    646    case Pav_UNPCKLPIX: return "vupklpx";
    647 
    648    /* Integer binary */
    649    case Pav_ADDU:      return "vaddu_m";  // b,h,w
    650    case Pav_QADDU:     return "vaddu_s";  // b,h,w
    651    case Pav_QADDS:     return "vadds_s";  // b,h,w
    652 
    653    case Pav_SUBU:      return "vsubu_m";  // b,h,w
    654    case Pav_QSUBU:     return "vsubu_s";  // b,h,w
    655    case Pav_QSUBS:     return "vsubs_s";  // b,h,w
    656 
    657    case Pav_OMULU:     return "vmulou";   // b,h
    658    case Pav_OMULS:     return "vmulos";   // b,h
    659    case Pav_EMULU:     return "vmuleu";   // b,h
    660    case Pav_EMULS:     return "vmules";   // b,h
    661 
    662    case Pav_AVGU:      return "vavgu";    // b,h,w
    663    case Pav_AVGS:      return "vavgs";    // b,h,w
    664 
    665    case Pav_MAXU:      return "vmaxu";    // b,h,w
    666    case Pav_MAXS:      return "vmaxs";    // b,h,w
    667 
    668    case Pav_MINU:      return "vminu";    // b,h,w
    669    case Pav_MINS:      return "vmins";    // b,h,w
    670 
    671    /* Compare (always affects CR field 6) */
    672    case Pav_CMPEQU:    return "vcmpequ";  // b,h,w
    673    case Pav_CMPGTU:    return "vcmpgtu";  // b,h,w
    674    case Pav_CMPGTS:    return "vcmpgts";  // b,h,w
    675 
    676    /* Shift */
    677    case Pav_SHL:       return "vsl";      // ' ',b,h,w
    678    case Pav_SHR:       return "vsr";      // ' ',b,h,w
    679    case Pav_SAR:       return "vsra";     // b,h,w
    680    case Pav_ROTL:      return "vrl";      // b,h,w
    681 
    682    /* Pack */
    683    case Pav_PACKUU:    return "vpku_um";  // h,w
    684    case Pav_QPACKUU:   return "vpku_us";  // h,w
    685    case Pav_QPACKSU:   return "vpks_us";  // h,w
    686    case Pav_QPACKSS:   return "vpks_ss";  // h,w
    687    case Pav_PACKPXL:   return "vpkpx";
    688 
    689    /* Merge */
    690    case Pav_MRGHI:     return "vmrgh";    // b,h,w
    691    case Pav_MRGLO:     return "vmrgl";    // b,h,w
    692 
    693    default: vpanic("showPPCAvOp");
    694    }
    695 }
    696 
    697 HChar* showPPCAvFpOp ( PPCAvFpOp op ) {
    698    switch (op) {
    699    /* Floating Point Binary */
    700    case Pavfp_ADDF:      return "vaddfp";
    701    case Pavfp_SUBF:      return "vsubfp";
    702    case Pavfp_MULF:      return "vmaddfp";
    703    case Pavfp_MAXF:      return "vmaxfp";
    704    case Pavfp_MINF:      return "vminfp";
    705    case Pavfp_CMPEQF:    return "vcmpeqfp";
    706    case Pavfp_CMPGTF:    return "vcmpgtfp";
    707    case Pavfp_CMPGEF:    return "vcmpgefp";
    708 
    709    /* Floating Point Unary */
    710    case Pavfp_RCPF:      return "vrefp";
    711    case Pavfp_RSQRTF:    return "vrsqrtefp";
    712    case Pavfp_CVTU2F:    return "vcfux";
    713    case Pavfp_CVTS2F:    return "vcfsx";
    714    case Pavfp_QCVTF2U:   return "vctuxs";
    715    case Pavfp_QCVTF2S:   return "vctsxs";
    716    case Pavfp_ROUNDM:    return "vrfim";
    717    case Pavfp_ROUNDP:    return "vrfip";
    718    case Pavfp_ROUNDN:    return "vrfin";
    719    case Pavfp_ROUNDZ:    return "vrfiz";
    720 
    721    default: vpanic("showPPCAvFpOp");
    722    }
    723 }
    724 
    725 PPCInstr* PPCInstr_LI ( HReg dst, ULong imm64, Bool mode64 )
    726 {
    727    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
    728    i->tag          = Pin_LI;
    729    i->Pin.LI.dst   = dst;
    730    i->Pin.LI.imm64 = imm64;
    731    if (!mode64)
    732       vassert( (Long)imm64 == (Long)(Int)(UInt)imm64 );
    733    return i;
    734 }
    735 PPCInstr* PPCInstr_Alu ( PPCAluOp op, HReg dst,
    736                          HReg srcL, PPCRH* srcR ) {
    737    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
    738    i->tag          = Pin_Alu;
    739    i->Pin.Alu.op   = op;
    740    i->Pin.Alu.dst  = dst;
    741    i->Pin.Alu.srcL = srcL;
    742    i->Pin.Alu.srcR = srcR;
    743    return i;
    744 }
    745 PPCInstr* PPCInstr_Shft ( PPCShftOp op, Bool sz32,
    746                           HReg dst, HReg srcL, PPCRH* srcR ) {
    747    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    748    i->tag           = Pin_Shft;
    749    i->Pin.Shft.op   = op;
    750    i->Pin.Shft.sz32 = sz32;
    751    i->Pin.Shft.dst  = dst;
    752    i->Pin.Shft.srcL = srcL;
    753    i->Pin.Shft.srcR = srcR;
    754    return i;
    755 }
    756 PPCInstr* PPCInstr_AddSubC ( Bool isAdd, Bool setC,
    757                              HReg dst, HReg srcL, HReg srcR ) {
    758    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
    759    i->tag               = Pin_AddSubC;
    760    i->Pin.AddSubC.isAdd = isAdd;
    761    i->Pin.AddSubC.setC  = setC;
    762    i->Pin.AddSubC.dst   = dst;
    763    i->Pin.AddSubC.srcL  = srcL;
    764    i->Pin.AddSubC.srcR  = srcR;
    765    return i;
    766 }
    767 PPCInstr* PPCInstr_Cmp ( Bool syned, Bool sz32,
    768                          UInt crfD, HReg srcL, PPCRH* srcR ) {
    769    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    770    i->tag           = Pin_Cmp;
    771    i->Pin.Cmp.syned = syned;
    772    i->Pin.Cmp.sz32  = sz32;
    773    i->Pin.Cmp.crfD  = crfD;
    774    i->Pin.Cmp.srcL  = srcL;
    775    i->Pin.Cmp.srcR  = srcR;
    776    return i;
    777 }
    778 PPCInstr* PPCInstr_Unary ( PPCUnaryOp op, HReg dst, HReg src ) {
    779    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    780    i->tag           = Pin_Unary;
    781    i->Pin.Unary.op  = op;
    782    i->Pin.Unary.dst = dst;
    783    i->Pin.Unary.src = src;
    784    return i;
    785 }
    786 PPCInstr* PPCInstr_MulL ( Bool syned, Bool hi, Bool sz32,
    787                           HReg dst, HReg srcL, HReg srcR ) {
    788    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
    789    i->tag            = Pin_MulL;
    790    i->Pin.MulL.syned = syned;
    791    i->Pin.MulL.hi    = hi;
    792    i->Pin.MulL.sz32  = sz32;
    793    i->Pin.MulL.dst   = dst;
    794    i->Pin.MulL.srcL  = srcL;
    795    i->Pin.MulL.srcR  = srcR;
    796    /* if doing the low word, the signedness is irrelevant, but tie it
    797       down anyway. */
    798    if (!hi) vassert(!syned);
    799    return i;
    800 }
    801 PPCInstr* PPCInstr_Div ( Bool syned, Bool sz32,
    802                          HReg dst, HReg srcL, HReg srcR ) {
    803    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    804    i->tag           = Pin_Div;
    805    i->Pin.Div.syned = syned;
    806    i->Pin.Div.sz32  = sz32;
    807    i->Pin.Div.dst   = dst;
    808    i->Pin.Div.srcL  = srcL;
    809    i->Pin.Div.srcR  = srcR;
    810    return i;
    811 }
    812 PPCInstr* PPCInstr_Call ( PPCCondCode cond,
    813                           Addr64 target, UInt argiregs ) {
    814    UInt mask;
    815    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
    816    i->tag               = Pin_Call;
    817    i->Pin.Call.cond     = cond;
    818    i->Pin.Call.target   = target;
    819    i->Pin.Call.argiregs = argiregs;
    820    /* Only r3 .. r10 inclusive may be used as arg regs. Hence: */
    821    mask = (1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10);
    822    vassert(0 == (argiregs & ~mask));
    823    return i;
    824 }
    825 PPCInstr* PPCInstr_Goto ( IRJumpKind jk,
    826                           PPCCondCode cond, PPCRI* dst ) {
    827    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    828    i->tag           = Pin_Goto;
    829    i->Pin.Goto.cond = cond;
    830    i->Pin.Goto.dst  = dst;
    831    i->Pin.Goto.jk   = jk;
    832    return i;
    833 }
    834 PPCInstr* PPCInstr_CMov  ( PPCCondCode cond,
    835                            HReg dst, PPCRI* src ) {
    836    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    837    i->tag           = Pin_CMov;
    838    i->Pin.CMov.cond = cond;
    839    i->Pin.CMov.src  = src;
    840    i->Pin.CMov.dst  = dst;
    841    vassert(cond.test != Pct_ALWAYS);
    842    return i;
    843 }
    844 PPCInstr* PPCInstr_Load ( UChar sz,
    845                           HReg dst, PPCAMode* src, Bool mode64 ) {
    846    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
    847    i->tag            = Pin_Load;
    848    i->Pin.Load.sz    = sz;
    849    i->Pin.Load.src   = src;
    850    i->Pin.Load.dst   = dst;
    851    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
    852    if (sz == 8) vassert(mode64);
    853    return i;
    854 }
    855 PPCInstr* PPCInstr_LoadL ( UChar sz,
    856                            HReg dst, HReg src, Bool mode64 )
    857 {
    858    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
    859    i->tag            = Pin_LoadL;
    860    i->Pin.LoadL.sz   = sz;
    861    i->Pin.LoadL.src  = src;
    862    i->Pin.LoadL.dst  = dst;
    863    vassert(sz == 4 || sz == 8);
    864    if (sz == 8) vassert(mode64);
    865    return i;
    866 }
    867 PPCInstr* PPCInstr_Store ( UChar sz, PPCAMode* dst, HReg src,
    868                            Bool mode64 ) {
    869    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    870    i->tag           = Pin_Store;
    871    i->Pin.Store.sz  = sz;
    872    i->Pin.Store.src = src;
    873    i->Pin.Store.dst = dst;
    874    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
    875    if (sz == 8) vassert(mode64);
    876    return i;
    877 }
    878 PPCInstr* PPCInstr_StoreC ( UChar sz, HReg dst, HReg src, Bool mode64 ) {
    879    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
    880    i->tag            = Pin_StoreC;
    881    i->Pin.StoreC.sz  = sz;
    882    i->Pin.StoreC.src = src;
    883    i->Pin.StoreC.dst = dst;
    884    vassert(sz == 4 || sz == 8);
    885    if (sz == 8) vassert(mode64);
    886    return i;
    887 }
    888 PPCInstr* PPCInstr_Set ( PPCCondCode cond, HReg dst ) {
    889    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
    890    i->tag          = Pin_Set;
    891    i->Pin.Set.cond = cond;
    892    i->Pin.Set.dst  = dst;
    893    return i;
    894 }
    895 PPCInstr* PPCInstr_MfCR ( HReg dst )
    896 {
    897    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
    898    i->tag          = Pin_MfCR;
    899    i->Pin.MfCR.dst = dst;
    900    return i;
    901 }
    902 PPCInstr* PPCInstr_MFence ( void )
    903 {
    904    PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr));
    905    i->tag      = Pin_MFence;
    906    return i;
    907 }
    908 
    909 PPCInstr* PPCInstr_FpUnary ( PPCFpOp op, HReg dst, HReg src ) {
    910    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
    911    i->tag             = Pin_FpUnary;
    912    i->Pin.FpUnary.op  = op;
    913    i->Pin.FpUnary.dst = dst;
    914    i->Pin.FpUnary.src = src;
    915    return i;
    916 }
    917 PPCInstr* PPCInstr_FpBinary ( PPCFpOp op, HReg dst,
    918                               HReg srcL, HReg srcR ) {
    919    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
    920    i->tag               = Pin_FpBinary;
    921    i->Pin.FpBinary.op   = op;
    922    i->Pin.FpBinary.dst  = dst;
    923    i->Pin.FpBinary.srcL = srcL;
    924    i->Pin.FpBinary.srcR = srcR;
    925    return i;
    926 }
    927 PPCInstr* PPCInstr_FpMulAcc ( PPCFpOp op, HReg dst, HReg srcML,
    928                                           HReg srcMR, HReg srcAcc )
    929 {
    930    PPCInstr* i            = LibVEX_Alloc(sizeof(PPCInstr));
    931    i->tag                 = Pin_FpMulAcc;
    932    i->Pin.FpMulAcc.op     = op;
    933    i->Pin.FpMulAcc.dst    = dst;
    934    i->Pin.FpMulAcc.srcML  = srcML;
    935    i->Pin.FpMulAcc.srcMR  = srcMR;
    936    i->Pin.FpMulAcc.srcAcc = srcAcc;
    937    return i;
    938 }
    939 PPCInstr* PPCInstr_FpLdSt ( Bool isLoad, UChar sz,
    940                             HReg reg, PPCAMode* addr ) {
    941    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
    942    i->tag               = Pin_FpLdSt;
    943    i->Pin.FpLdSt.isLoad = isLoad;
    944    i->Pin.FpLdSt.sz     = sz;
    945    i->Pin.FpLdSt.reg    = reg;
    946    i->Pin.FpLdSt.addr   = addr;
    947    vassert(sz == 4 || sz == 8);
    948    return i;
    949 }
    950 PPCInstr* PPCInstr_FpSTFIW ( HReg addr, HReg data )
    951 {
    952    PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
    953    i->tag              = Pin_FpSTFIW;
    954    i->Pin.FpSTFIW.addr = addr;
    955    i->Pin.FpSTFIW.data = data;
    956    return i;
    957 }
    958 PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src ) {
    959    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
    960    i->tag           = Pin_FpRSP;
    961    i->Pin.FpRSP.dst = dst;
    962    i->Pin.FpRSP.src = src;
    963    return i;
    964 }
    965 PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32,
    966                             HReg dst, HReg src ) {
    967    PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
    968    i->tag              = Pin_FpCftI;
    969    i->Pin.FpCftI.fromI = fromI;
    970    i->Pin.FpCftI.int32 = int32;
    971    i->Pin.FpCftI.dst   = dst;
    972    i->Pin.FpCftI.src   = src;
    973    vassert(!(int32 && fromI)); /* no such insn ("fcfiw"). */
    974    return i;
    975 }
    976 PPCInstr* PPCInstr_FpCMov ( PPCCondCode cond, HReg dst, HReg src ) {
    977    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
    978    i->tag             = Pin_FpCMov;
    979    i->Pin.FpCMov.cond = cond;
    980    i->Pin.FpCMov.dst  = dst;
    981    i->Pin.FpCMov.src  = src;
    982    vassert(cond.test != Pct_ALWAYS);
    983    return i;
    984 }
    985 PPCInstr* PPCInstr_FpLdFPSCR ( HReg src ) {
    986    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
    987    i->tag               = Pin_FpLdFPSCR;
    988    i->Pin.FpLdFPSCR.src = src;
    989    return i;
    990 }
    991 PPCInstr* PPCInstr_FpCmp ( HReg dst, HReg srcL, HReg srcR ) {
    992    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
    993    i->tag            = Pin_FpCmp;
    994    i->Pin.FpCmp.dst  = dst;
    995    i->Pin.FpCmp.srcL = srcL;
    996    i->Pin.FpCmp.srcR = srcR;
    997    return i;
    998 }
    999 
   1000 /* Read/Write Link Register */
   1001 PPCInstr* PPCInstr_RdWrLR ( Bool wrLR, HReg gpr ) {
   1002    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
   1003    i->tag             = Pin_RdWrLR;
   1004    i->Pin.RdWrLR.wrLR = wrLR;
   1005    i->Pin.RdWrLR.gpr  = gpr;
   1006    return i;
   1007 }
   1008 
   1009 /* AltiVec */
   1010 PPCInstr* PPCInstr_AvLdSt ( Bool isLoad, UChar sz,
   1011                             HReg reg, PPCAMode* addr ) {
   1012    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
   1013    i->tag               = Pin_AvLdSt;
   1014    i->Pin.AvLdSt.isLoad = isLoad;
   1015    i->Pin.AvLdSt.sz     = sz;
   1016    i->Pin.AvLdSt.reg    = reg;
   1017    i->Pin.AvLdSt.addr   = addr;
   1018    return i;
   1019 }
   1020 PPCInstr* PPCInstr_AvUnary ( PPCAvOp op, HReg dst, HReg src ) {
   1021    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
   1022    i->tag             = Pin_AvUnary;
   1023    i->Pin.AvUnary.op  = op;
   1024    i->Pin.AvUnary.dst = dst;
   1025    i->Pin.AvUnary.src = src;
   1026    return i;
   1027 }
   1028 PPCInstr* PPCInstr_AvBinary ( PPCAvOp op, HReg dst,
   1029                               HReg srcL, HReg srcR ) {
   1030    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
   1031    i->tag               = Pin_AvBinary;
   1032    i->Pin.AvBinary.op   = op;
   1033    i->Pin.AvBinary.dst  = dst;
   1034    i->Pin.AvBinary.srcL = srcL;
   1035    i->Pin.AvBinary.srcR = srcR;
   1036    return i;
   1037 }
   1038 PPCInstr* PPCInstr_AvBin8x16 ( PPCAvOp op, HReg dst,
   1039                                HReg srcL, HReg srcR ) {
   1040    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
   1041    i->tag                = Pin_AvBin8x16;
   1042    i->Pin.AvBin8x16.op   = op;
   1043    i->Pin.AvBin8x16.dst  = dst;
   1044    i->Pin.AvBin8x16.srcL = srcL;
   1045    i->Pin.AvBin8x16.srcR = srcR;
   1046    return i;
   1047 }
   1048 PPCInstr* PPCInstr_AvBin16x8 ( PPCAvOp op, HReg dst,
   1049                                HReg srcL, HReg srcR ) {
   1050    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
   1051    i->tag                = Pin_AvBin16x8;
   1052    i->Pin.AvBin16x8.op   = op;
   1053    i->Pin.AvBin16x8.dst  = dst;
   1054    i->Pin.AvBin16x8.srcL = srcL;
   1055    i->Pin.AvBin16x8.srcR = srcR;
   1056    return i;
   1057 }
   1058 PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst,
   1059                                HReg srcL, HReg srcR ) {
   1060    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
   1061    i->tag                = Pin_AvBin32x4;
   1062    i->Pin.AvBin32x4.op   = op;
   1063    i->Pin.AvBin32x4.dst  = dst;
   1064    i->Pin.AvBin32x4.srcL = srcL;
   1065    i->Pin.AvBin32x4.srcR = srcR;
   1066    return i;
   1067 }
   1068 PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvOp op, HReg dst,
   1069                                 HReg srcL, HReg srcR ) {
   1070    PPCInstr* i            = LibVEX_Alloc(sizeof(PPCInstr));
   1071    i->tag                 = Pin_AvBin32Fx4;
   1072    i->Pin.AvBin32Fx4.op   = op;
   1073    i->Pin.AvBin32Fx4.dst  = dst;
   1074    i->Pin.AvBin32Fx4.srcL = srcL;
   1075    i->Pin.AvBin32Fx4.srcR = srcR;
   1076    return i;
   1077 }
   1078 PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvOp op, HReg dst, HReg src ) {
   1079    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
   1080    i->tag               = Pin_AvUn32Fx4;
   1081    i->Pin.AvUn32Fx4.op  = op;
   1082    i->Pin.AvUn32Fx4.dst = dst;
   1083    i->Pin.AvUn32Fx4.src = src;
   1084    return i;
   1085 }
   1086 PPCInstr* PPCInstr_AvPerm ( HReg dst, HReg srcL, HReg srcR, HReg ctl ) {
   1087    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
   1088    i->tag             = Pin_AvPerm;
   1089    i->Pin.AvPerm.dst  = dst;
   1090    i->Pin.AvPerm.srcL = srcL;
   1091    i->Pin.AvPerm.srcR = srcR;
   1092    i->Pin.AvPerm.ctl  = ctl;
   1093    return i;
   1094 }
   1095 PPCInstr* PPCInstr_AvSel ( HReg ctl, HReg dst, HReg srcL, HReg srcR ) {
   1096    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
   1097    i->tag            = Pin_AvSel;
   1098    i->Pin.AvSel.ctl  = ctl;
   1099    i->Pin.AvSel.dst  = dst;
   1100    i->Pin.AvSel.srcL = srcL;
   1101    i->Pin.AvSel.srcR = srcR;
   1102    return i;
   1103 }
   1104 PPCInstr* PPCInstr_AvShlDbl ( UChar shift, HReg dst,
   1105                               HReg srcL, HReg srcR ) {
   1106    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
   1107    i->tag                = Pin_AvShlDbl;
   1108    i->Pin.AvShlDbl.shift = shift;
   1109    i->Pin.AvShlDbl.dst   = dst;
   1110    i->Pin.AvShlDbl.srcL  = srcL;
   1111    i->Pin.AvShlDbl.srcR  = srcR;
   1112    return i;
   1113 }
   1114 PPCInstr* PPCInstr_AvSplat ( UChar sz, HReg dst, PPCVI5s* src ) {
   1115    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
   1116    i->tag             = Pin_AvSplat;
   1117    i->Pin.AvSplat.sz  = sz;
   1118    i->Pin.AvSplat.dst = dst;
   1119    i->Pin.AvSplat.src = src;
   1120    return i;
   1121 }
   1122 PPCInstr* PPCInstr_AvCMov ( PPCCondCode cond, HReg dst, HReg src ) {
   1123    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
   1124    i->tag             = Pin_AvCMov;
   1125    i->Pin.AvCMov.cond = cond;
   1126    i->Pin.AvCMov.dst  = dst;
   1127    i->Pin.AvCMov.src  = src;
   1128    vassert(cond.test != Pct_ALWAYS);
   1129    return i;
   1130 }
   1131 PPCInstr* PPCInstr_AvLdVSCR ( HReg src ) {
   1132    PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
   1133    i->tag              = Pin_AvLdVSCR;
   1134    i->Pin.AvLdVSCR.src = src;
   1135    return i;
   1136 }
   1137 
   1138 
   1139 /* Pretty Print instructions */
   1140 static void ppLoadImm ( HReg dst, ULong imm, Bool mode64 ) {
   1141    vex_printf("li_word ");
   1142    ppHRegPPC(dst);
   1143    if (!mode64) {
   1144       vex_printf(",0x%08x", (UInt)imm);
   1145    } else {
   1146       vex_printf(",0x%016llx", imm);
   1147    }
   1148 }
   1149 
   1150 static void ppMovReg ( HReg dst, HReg src ) {
   1151    if (hregNumber(dst) != hregNumber(src)) {
   1152       vex_printf("mr ");
   1153       ppHRegPPC(dst);
   1154       vex_printf(",");
   1155       ppHRegPPC(src);
   1156    }
   1157 }
   1158 
   1159 void ppPPCInstr ( PPCInstr* i, Bool mode64 )
   1160 {
   1161    switch (i->tag) {
   1162    case Pin_LI:
   1163       ppLoadImm(i->Pin.LI.dst, i->Pin.LI.imm64, mode64);
   1164       break;
   1165    case Pin_Alu: {
   1166       HReg   r_srcL  = i->Pin.Alu.srcL;
   1167       PPCRH* rh_srcR = i->Pin.Alu.srcR;
   1168       /* special-case "mr" */
   1169       if (i->Pin.Alu.op == Palu_OR &&   // or Rd,Rs,Rs == mr Rd,Rs
   1170           rh_srcR->tag == Prh_Reg &&
   1171           rh_srcR->Prh.Reg.reg == r_srcL) {
   1172          vex_printf("mr ");
   1173          ppHRegPPC(i->Pin.Alu.dst);
   1174          vex_printf(",");
   1175          ppHRegPPC(r_srcL);
   1176          return;
   1177       }
   1178       /* special-case "li" */
   1179       if (i->Pin.Alu.op == Palu_ADD &&   // addi Rd,0,imm == li Rd,imm
   1180           rh_srcR->tag == Prh_Imm &&
   1181           hregNumber(r_srcL) == 0) {
   1182          vex_printf("li ");
   1183          ppHRegPPC(i->Pin.Alu.dst);
   1184          vex_printf(",");
   1185          ppPPCRH(rh_srcR);
   1186          return;
   1187       }
   1188       /* generic */
   1189       vex_printf("%s ", showPPCAluOp(i->Pin.Alu.op,
   1190                                      toBool(rh_srcR->tag == Prh_Imm)));
   1191       ppHRegPPC(i->Pin.Alu.dst);
   1192       vex_printf(",");
   1193       ppHRegPPC(r_srcL);
   1194       vex_printf(",");
   1195       ppPPCRH(rh_srcR);
   1196       return;
   1197    }
   1198    case Pin_Shft: {
   1199       HReg   r_srcL  = i->Pin.Shft.srcL;
   1200       PPCRH* rh_srcR = i->Pin.Shft.srcR;
   1201       vex_printf("%s ", showPPCShftOp(i->Pin.Shft.op,
   1202                                       toBool(rh_srcR->tag == Prh_Imm),
   1203                                       i->Pin.Shft.sz32));
   1204       ppHRegPPC(i->Pin.Shft.dst);
   1205       vex_printf(",");
   1206       ppHRegPPC(r_srcL);
   1207       vex_printf(",");
   1208       ppPPCRH(rh_srcR);
   1209       return;
   1210    }
   1211    case Pin_AddSubC:
   1212       vex_printf("%s%s ",
   1213                  i->Pin.AddSubC.isAdd ? "add" : "sub",
   1214                  i->Pin.AddSubC.setC ? "c" : "e");
   1215       ppHRegPPC(i->Pin.AddSubC.dst);
   1216       vex_printf(",");
   1217       ppHRegPPC(i->Pin.AddSubC.srcL);
   1218       vex_printf(",");
   1219       ppHRegPPC(i->Pin.AddSubC.srcR);
   1220       return;
   1221    case Pin_Cmp:
   1222       vex_printf("%s%c%s %%cr%u,",
   1223                  i->Pin.Cmp.syned ? "cmp" : "cmpl",
   1224                  i->Pin.Cmp.sz32 ? 'w' : 'd',
   1225                  i->Pin.Cmp.srcR->tag == Prh_Imm ? "i" : "",
   1226                  i->Pin.Cmp.crfD);
   1227       ppHRegPPC(i->Pin.Cmp.srcL);
   1228       vex_printf(",");
   1229       ppPPCRH(i->Pin.Cmp.srcR);
   1230       return;
   1231    case Pin_Unary:
   1232       vex_printf("%s ", showPPCUnaryOp(i->Pin.Unary.op));
   1233       ppHRegPPC(i->Pin.Unary.dst);
   1234       vex_printf(",");
   1235       ppHRegPPC(i->Pin.Unary.src);
   1236       return;
   1237    case Pin_MulL:
   1238       vex_printf("mul%c%c%s ",
   1239                  i->Pin.MulL.hi ? 'h' : 'l',
   1240                  i->Pin.MulL.sz32 ? 'w' : 'd',
   1241                  i->Pin.MulL.hi ? (i->Pin.MulL.syned ? "s" : "u") : "");
   1242       ppHRegPPC(i->Pin.MulL.dst);
   1243       vex_printf(",");
   1244       ppHRegPPC(i->Pin.MulL.srcL);
   1245       vex_printf(",");
   1246       ppHRegPPC(i->Pin.MulL.srcR);
   1247       return;
   1248    case Pin_Div:
   1249       vex_printf("div%c%s ",
   1250                  i->Pin.Div.sz32 ? 'w' : 'd',
   1251                  i->Pin.Div.syned ? "" : "u");
   1252       ppHRegPPC(i->Pin.Div.dst);
   1253       vex_printf(",");
   1254       ppHRegPPC(i->Pin.Div.srcL);
   1255       vex_printf(",");
   1256       ppHRegPPC(i->Pin.Div.srcR);
   1257       return;
   1258    case Pin_Call: {
   1259       Int n;
   1260       vex_printf("call: ");
   1261       if (i->Pin.Call.cond.test != Pct_ALWAYS) {
   1262          vex_printf("if (%s) ", showPPCCondCode(i->Pin.Call.cond));
   1263       }
   1264       vex_printf("{ ");
   1265       ppLoadImm(hregPPC_GPR10(mode64), i->Pin.Call.target, mode64);
   1266       vex_printf(" ; mtctr r10 ; bctrl [");
   1267       for (n = 0; n < 32; n++) {
   1268          if (i->Pin.Call.argiregs & (1<<n)) {
   1269             vex_printf("r%d", n);
   1270             if ((i->Pin.Call.argiregs >> n) > 1)
   1271                vex_printf(",");
   1272          }
   1273       }
   1274       vex_printf("] }");
   1275       break;
   1276    }
   1277    case Pin_Goto:
   1278       vex_printf("goto: ");
   1279       if (i->Pin.Goto.cond.test != Pct_ALWAYS) {
   1280          vex_printf("if (%s) ", showPPCCondCode(i->Pin.Goto.cond));
   1281       }
   1282       vex_printf("{ ");
   1283       if (i->Pin.Goto.jk != Ijk_Boring
   1284           && i->Pin.Goto.jk != Ijk_Call
   1285           && i->Pin.Goto.jk != Ijk_Ret) {
   1286          vex_printf("li %%r31,$");
   1287          ppIRJumpKind(i->Pin.Goto.jk);
   1288          vex_printf(" ; ");
   1289       }
   1290       if (i->Pin.Goto.dst->tag == Pri_Imm) {
   1291          ppLoadImm(hregPPC_GPR3(mode64), i->Pin.Goto.dst->Pri.Imm,
   1292                    mode64);
   1293       } else {
   1294          ppMovReg(hregPPC_GPR3(mode64), i->Pin.Goto.dst->Pri.Reg);
   1295       }
   1296       vex_printf(" ; blr }");
   1297       return;
   1298    case Pin_CMov:
   1299       vex_printf("cmov (%s) ", showPPCCondCode(i->Pin.CMov.cond));
   1300       ppHRegPPC(i->Pin.CMov.dst);
   1301       vex_printf(",");
   1302       ppPPCRI(i->Pin.CMov.src);
   1303       vex_printf(": ");
   1304       if (i->Pin.CMov.cond.test != Pct_ALWAYS) {
   1305          vex_printf("if (%s) ", showPPCCondCode(i->Pin.CMov.cond));
   1306       }
   1307       vex_printf("{ ");
   1308       if (i->Pin.CMov.src->tag == Pri_Imm) {
   1309          ppLoadImm(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Imm, mode64);
   1310       } else {
   1311          ppMovReg(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Reg);
   1312       }
   1313       vex_printf(" }");
   1314       return;
   1315    case Pin_Load: {
   1316       Bool idxd = toBool(i->Pin.Load.src->tag == Pam_RR);
   1317       UChar sz = i->Pin.Load.sz;
   1318       UChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd';
   1319       vex_printf("l%c%s%s ", c_sz, sz==8 ? "" : "z", idxd ? "x" : "" );
   1320       ppHRegPPC(i->Pin.Load.dst);
   1321       vex_printf(",");
   1322       ppPPCAMode(i->Pin.Load.src);
   1323       return;
   1324    }
   1325    case Pin_LoadL:
   1326       vex_printf("l%carx ", i->Pin.LoadL.sz==4 ? 'w' : 'd');
   1327       ppHRegPPC(i->Pin.LoadL.dst);
   1328       vex_printf(",%%r0,");
   1329       ppHRegPPC(i->Pin.LoadL.src);
   1330       return;
   1331    case Pin_Store: {
   1332       UChar sz = i->Pin.Store.sz;
   1333       Bool idxd = toBool(i->Pin.Store.dst->tag == Pam_RR);
   1334       UChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : /*8*/ 'd';
   1335       vex_printf("st%c%s ", c_sz, idxd ? "x" : "" );
   1336       ppHRegPPC(i->Pin.Store.src);
   1337       vex_printf(",");
   1338       ppPPCAMode(i->Pin.Store.dst);
   1339       return;
   1340    }
   1341    case Pin_StoreC:
   1342       vex_printf("st%ccx. ", i->Pin.StoreC.sz==4 ? 'w' : 'd');
   1343       ppHRegPPC(i->Pin.StoreC.src);
   1344       vex_printf(",%%r0,");
   1345       ppHRegPPC(i->Pin.StoreC.dst);
   1346       return;
   1347    case Pin_Set: {
   1348       PPCCondCode cc = i->Pin.Set.cond;
   1349       vex_printf("set (%s),", showPPCCondCode(cc));
   1350       ppHRegPPC(i->Pin.Set.dst);
   1351       if (cc.test == Pct_ALWAYS) {
   1352          vex_printf(": { li ");
   1353          ppHRegPPC(i->Pin.Set.dst);
   1354          vex_printf(",1 }");
   1355       } else {
   1356          vex_printf(": { mfcr r0 ; rlwinm ");
   1357          ppHRegPPC(i->Pin.Set.dst);
   1358          vex_printf(",r0,%u,31,31", cc.flag+1);
   1359          if (cc.test == Pct_FALSE) {
   1360             vex_printf("; xori ");
   1361             ppHRegPPC(i->Pin.Set.dst);
   1362             vex_printf(",");
   1363             ppHRegPPC(i->Pin.Set.dst);
   1364             vex_printf(",1");
   1365          }
   1366          vex_printf(" }");
   1367       }
   1368       return;
   1369    }
   1370    case Pin_MfCR:
   1371       vex_printf("mfcr ");
   1372       ppHRegPPC(i->Pin.MfCR.dst);
   1373       break;
   1374    case Pin_MFence:
   1375       vex_printf("mfence (=sync)");
   1376       return;
   1377 
   1378    case Pin_FpUnary:
   1379       vex_printf("%s ", showPPCFpOp(i->Pin.FpUnary.op));
   1380       ppHRegPPC(i->Pin.FpUnary.dst);
   1381       vex_printf(",");
   1382       ppHRegPPC(i->Pin.FpUnary.src);
   1383       return;
   1384    case Pin_FpBinary:
   1385       vex_printf("%s ", showPPCFpOp(i->Pin.FpBinary.op));
   1386       ppHRegPPC(i->Pin.FpBinary.dst);
   1387       vex_printf(",");
   1388       ppHRegPPC(i->Pin.FpBinary.srcL);
   1389       vex_printf(",");
   1390       ppHRegPPC(i->Pin.FpBinary.srcR);
   1391       return;
   1392    case Pin_FpMulAcc:
   1393       vex_printf("%s ", showPPCFpOp(i->Pin.FpMulAcc.op));
   1394       ppHRegPPC(i->Pin.FpMulAcc.dst);
   1395       vex_printf(",");
   1396       ppHRegPPC(i->Pin.FpMulAcc.srcML);
   1397       vex_printf(",");
   1398       ppHRegPPC(i->Pin.FpMulAcc.srcMR);
   1399       vex_printf(",");
   1400       ppHRegPPC(i->Pin.FpMulAcc.srcAcc);
   1401       return;
   1402    case Pin_FpLdSt: {
   1403       UChar sz = i->Pin.FpLdSt.sz;
   1404       Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR);
   1405       if (i->Pin.FpLdSt.isLoad) {
   1406          vex_printf("lf%c%s ",
   1407                     (sz==4 ? 's' : 'd'),
   1408                     idxd ? "x" : "" );
   1409          ppHRegPPC(i->Pin.FpLdSt.reg);
   1410          vex_printf(",");
   1411          ppPPCAMode(i->Pin.FpLdSt.addr);
   1412       } else {
   1413          vex_printf("stf%c%s ",
   1414                     (sz==4 ? 's' : 'd'),
   1415                     idxd ? "x" : "" );
   1416          ppHRegPPC(i->Pin.FpLdSt.reg);
   1417          vex_printf(",");
   1418          ppPPCAMode(i->Pin.FpLdSt.addr);
   1419       }
   1420       return;
   1421    }
   1422    case Pin_FpSTFIW:
   1423       vex_printf("stfiwz ");
   1424       ppHRegPPC(i->Pin.FpSTFIW.data);
   1425       vex_printf(",0(");
   1426       ppHRegPPC(i->Pin.FpSTFIW.addr);
   1427       vex_printf(")");
   1428       return;
   1429    case Pin_FpRSP:
   1430       vex_printf("frsp ");
   1431       ppHRegPPC(i->Pin.FpRSP.dst);
   1432       vex_printf(",");
   1433       ppHRegPPC(i->Pin.FpRSP.src);
   1434       return;
   1435    case Pin_FpCftI: {
   1436       HChar* str = "fc???";
   1437       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False)
   1438          str = "fctid";
   1439       else
   1440       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True)
   1441          str = "fctiw";
   1442       else
   1443       if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False)
   1444          str = "fcfid";
   1445       vex_printf("%s ", str);
   1446       ppHRegPPC(i->Pin.FpCftI.dst);
   1447       vex_printf(",");
   1448       ppHRegPPC(i->Pin.FpCftI.src);
   1449       return;
   1450    }
   1451    case Pin_FpCMov:
   1452       vex_printf("fpcmov (%s) ", showPPCCondCode(i->Pin.FpCMov.cond));
   1453       ppHRegPPC(i->Pin.FpCMov.dst);
   1454       vex_printf(",");
   1455       ppHRegPPC(i->Pin.FpCMov.src);
   1456       vex_printf(": ");
   1457       vex_printf("if (fr_dst != fr_src) { ");
   1458       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS) {
   1459          vex_printf("if (%s) { ", showPPCCondCode(i->Pin.FpCMov.cond));
   1460       }
   1461       vex_printf("fmr ");
   1462       ppHRegPPC(i->Pin.FpCMov.dst);
   1463       vex_printf(",");
   1464       ppHRegPPC(i->Pin.FpCMov.src);
   1465       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS)
   1466          vex_printf(" }");
   1467       vex_printf(" }");
   1468       return;
   1469    case Pin_FpLdFPSCR:
   1470       vex_printf("mtfsf 0xFF,");
   1471       ppHRegPPC(i->Pin.FpLdFPSCR.src);
   1472       return;
   1473    case Pin_FpCmp:
   1474       vex_printf("fcmpo %%cr1,");
   1475       ppHRegPPC(i->Pin.FpCmp.srcL);
   1476       vex_printf(",");
   1477       ppHRegPPC(i->Pin.FpCmp.srcR);
   1478       vex_printf("; mfcr ");
   1479       ppHRegPPC(i->Pin.FpCmp.dst);
   1480       vex_printf("; rlwinm ");
   1481       ppHRegPPC(i->Pin.FpCmp.dst);
   1482       vex_printf(",");
   1483       ppHRegPPC(i->Pin.FpCmp.dst);
   1484       vex_printf(",8,28,31");
   1485       return;
   1486 
   1487    case Pin_RdWrLR:
   1488       vex_printf("%s ", i->Pin.RdWrLR.wrLR ? "mtlr" : "mflr");
   1489       ppHRegPPC(i->Pin.RdWrLR.gpr);
   1490       return;
   1491 
   1492    case Pin_AvLdSt: {
   1493       UChar  sz = i->Pin.AvLdSt.sz;
   1494       HChar* str_size;
   1495       if (i->Pin.AvLdSt.addr->tag == Pam_IR) {
   1496          ppLoadImm(hregPPC_GPR30(mode64),
   1497                    i->Pin.AvLdSt.addr->Pam.RR.index, mode64);
   1498          vex_printf(" ; ");
   1499       }
   1500       str_size = sz==1 ? "eb" : sz==2 ? "eh" : sz==4 ? "ew" : "";
   1501       if (i->Pin.AvLdSt.isLoad)
   1502          vex_printf("lv%sx ", str_size);
   1503       else
   1504          vex_printf("stv%sx ", str_size);
   1505       ppHRegPPC(i->Pin.AvLdSt.reg);
   1506       vex_printf(",");
   1507       if (i->Pin.AvLdSt.addr->tag == Pam_IR)
   1508          vex_printf("%%r30");
   1509       else
   1510          ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.index);
   1511       vex_printf(",");
   1512       ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.base);
   1513       return;
   1514    }
   1515    case Pin_AvUnary:
   1516       vex_printf("%s ", showPPCAvOp(i->Pin.AvUnary.op));
   1517       ppHRegPPC(i->Pin.AvUnary.dst);
   1518       vex_printf(",");
   1519       ppHRegPPC(i->Pin.AvUnary.src);
   1520       return;
   1521    case Pin_AvBinary:
   1522       vex_printf("%s ", showPPCAvOp(i->Pin.AvBinary.op));
   1523       ppHRegPPC(i->Pin.AvBinary.dst);
   1524       vex_printf(",");
   1525       ppHRegPPC(i->Pin.AvBinary.srcL);
   1526       vex_printf(",");
   1527       ppHRegPPC(i->Pin.AvBinary.srcR);
   1528       return;
   1529    case Pin_AvBin8x16:
   1530       vex_printf("%s(b) ", showPPCAvOp(i->Pin.AvBin8x16.op));
   1531       ppHRegPPC(i->Pin.AvBin8x16.dst);
   1532       vex_printf(",");
   1533       ppHRegPPC(i->Pin.AvBin8x16.srcL);
   1534       vex_printf(",");
   1535       ppHRegPPC(i->Pin.AvBin8x16.srcR);
   1536       return;
   1537    case Pin_AvBin16x8:
   1538       vex_printf("%s(h) ", showPPCAvOp(i->Pin.AvBin16x8.op));
   1539       ppHRegPPC(i->Pin.AvBin16x8.dst);
   1540       vex_printf(",");
   1541       ppHRegPPC(i->Pin.AvBin16x8.srcL);
   1542       vex_printf(",");
   1543       ppHRegPPC(i->Pin.AvBin16x8.srcR);
   1544       return;
   1545    case Pin_AvBin32x4:
   1546       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin32x4.op));
   1547       ppHRegPPC(i->Pin.AvBin32x4.dst);
   1548       vex_printf(",");
   1549       ppHRegPPC(i->Pin.AvBin32x4.srcL);
   1550       vex_printf(",");
   1551       ppHRegPPC(i->Pin.AvBin32x4.srcR);
   1552       return;
   1553    case Pin_AvBin32Fx4:
   1554       vex_printf("%s ", showPPCAvFpOp(i->Pin.AvBin32Fx4.op));
   1555       ppHRegPPC(i->Pin.AvBin32Fx4.dst);
   1556       vex_printf(",");
   1557       ppHRegPPC(i->Pin.AvBin32Fx4.srcL);
   1558       vex_printf(",");
   1559       ppHRegPPC(i->Pin.AvBin32Fx4.srcR);
   1560       return;
   1561    case Pin_AvUn32Fx4:
   1562       vex_printf("%s ", showPPCAvFpOp(i->Pin.AvUn32Fx4.op));
   1563       ppHRegPPC(i->Pin.AvUn32Fx4.dst);
   1564       vex_printf(",");
   1565       ppHRegPPC(i->Pin.AvUn32Fx4.src);
   1566       return;
   1567    case Pin_AvPerm:
   1568       vex_printf("vperm ");
   1569       ppHRegPPC(i->Pin.AvPerm.dst);
   1570       vex_printf(",");
   1571       ppHRegPPC(i->Pin.AvPerm.srcL);
   1572       vex_printf(",");
   1573       ppHRegPPC(i->Pin.AvPerm.srcR);
   1574       vex_printf(",");
   1575       ppHRegPPC(i->Pin.AvPerm.ctl);
   1576       return;
   1577 
   1578    case Pin_AvSel:
   1579       vex_printf("vsel ");
   1580       ppHRegPPC(i->Pin.AvSel.dst);
   1581       vex_printf(",");
   1582       ppHRegPPC(i->Pin.AvSel.srcL);
   1583       vex_printf(",");
   1584       ppHRegPPC(i->Pin.AvSel.srcR);
   1585       vex_printf(",");
   1586       ppHRegPPC(i->Pin.AvSel.ctl);
   1587       return;
   1588 
   1589    case Pin_AvShlDbl:
   1590       vex_printf("vsldoi ");
   1591       ppHRegPPC(i->Pin.AvShlDbl.dst);
   1592       vex_printf(",");
   1593       ppHRegPPC(i->Pin.AvShlDbl.srcL);
   1594       vex_printf(",");
   1595       ppHRegPPC(i->Pin.AvShlDbl.srcR);
   1596       vex_printf(",%d", i->Pin.AvShlDbl.shift);
   1597       return;
   1598 
   1599    case Pin_AvSplat: {
   1600       UChar sz = i->Pin.AvSplat.sz;
   1601       UChar ch_sz = toUChar( (sz == 8) ? 'b' : (sz == 16) ? 'h' : 'w' );
   1602       vex_printf("vsplt%s%c ",
   1603                  i->Pin.AvSplat.src->tag == Pvi_Imm ? "is" : "", ch_sz);
   1604       ppHRegPPC(i->Pin.AvSplat.dst);
   1605       vex_printf(",");
   1606       ppPPCVI5s(i->Pin.AvSplat.src);
   1607       if (i->Pin.AvSplat.src->tag == Pvi_Reg)
   1608          vex_printf(", %d", (128/sz)-1);   /* louis lane */
   1609       return;
   1610    }
   1611 
   1612    case Pin_AvCMov:
   1613       vex_printf("avcmov (%s) ", showPPCCondCode(i->Pin.AvCMov.cond));
   1614       ppHRegPPC(i->Pin.AvCMov.dst);
   1615       vex_printf(",");
   1616       ppHRegPPC(i->Pin.AvCMov.src);
   1617       vex_printf(": ");
   1618       vex_printf("if (v_dst != v_src) { ");
   1619       if (i->Pin.AvCMov.cond.test != Pct_ALWAYS) {
   1620          vex_printf("if (%s) { ", showPPCCondCode(i->Pin.AvCMov.cond));
   1621       }
   1622       vex_printf("vmr ");
   1623       ppHRegPPC(i->Pin.AvCMov.dst);
   1624       vex_printf(",");
   1625       ppHRegPPC(i->Pin.AvCMov.src);
   1626       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS)
   1627          vex_printf(" }");
   1628       vex_printf(" }");
   1629       return;
   1630 
   1631    case Pin_AvLdVSCR:
   1632       vex_printf("mtvscr ");
   1633       ppHRegPPC(i->Pin.AvLdVSCR.src);
   1634       return;
   1635 
   1636    default:
   1637       vex_printf("\nppPPCInstr: No such tag(%d)\n", (Int)i->tag);
   1638       vpanic("ppPPCInstr");
   1639    }
   1640 }
   1641 
   1642 /* --------- Helpers for register allocation. --------- */
   1643 
   1644 void getRegUsage_PPCInstr ( HRegUsage* u, PPCInstr* i, Bool mode64 )
   1645 {
   1646    initHRegUsage(u);
   1647    switch (i->tag) {
   1648    case Pin_LI:
   1649       addHRegUse(u, HRmWrite, i->Pin.LI.dst);
   1650       break;
   1651    case Pin_Alu:
   1652       addHRegUse(u, HRmRead,  i->Pin.Alu.srcL);
   1653       addRegUsage_PPCRH(u,    i->Pin.Alu.srcR);
   1654       addHRegUse(u, HRmWrite, i->Pin.Alu.dst);
   1655       return;
   1656    case Pin_Shft:
   1657       addHRegUse(u, HRmRead,  i->Pin.Shft.srcL);
   1658       addRegUsage_PPCRH(u,    i->Pin.Shft.srcR);
   1659       addHRegUse(u, HRmWrite, i->Pin.Shft.dst);
   1660       return;
   1661    case Pin_AddSubC:
   1662       addHRegUse(u, HRmWrite, i->Pin.AddSubC.dst);
   1663       addHRegUse(u, HRmRead,  i->Pin.AddSubC.srcL);
   1664       addHRegUse(u, HRmRead,  i->Pin.AddSubC.srcR);
   1665       return;
   1666    case Pin_Cmp:
   1667       addHRegUse(u, HRmRead, i->Pin.Cmp.srcL);
   1668       addRegUsage_PPCRH(u,   i->Pin.Cmp.srcR);
   1669       return;
   1670    case Pin_Unary:
   1671       addHRegUse(u, HRmWrite, i->Pin.Unary.dst);
   1672       addHRegUse(u, HRmRead,  i->Pin.Unary.src);
   1673       return;
   1674    case Pin_MulL:
   1675       addHRegUse(u, HRmWrite, i->Pin.MulL.dst);
   1676       addHRegUse(u, HRmRead,  i->Pin.MulL.srcL);
   1677       addHRegUse(u, HRmRead,  i->Pin.MulL.srcR);
   1678       return;
   1679    case Pin_Div:
   1680       addHRegUse(u, HRmWrite, i->Pin.Div.dst);
   1681       addHRegUse(u, HRmRead,  i->Pin.Div.srcL);
   1682       addHRegUse(u, HRmRead,  i->Pin.Div.srcR);
   1683       return;
   1684    case Pin_Call: {
   1685       UInt argir;
   1686       /* This is a bit subtle. */
   1687       /* First off, claim it trashes all the caller-saved regs
   1688          which fall within the register allocator's jurisdiction.
   1689          These I believe to be:
   1690          mode32: r3 to r12
   1691          mode64: r3 to r10
   1692       */
   1693       /* XXXXXXXXXXXXXXXXX BUG! This doesn't say anything about the FP
   1694          or Altivec registers.  We get away with this ONLY because
   1695          getAllocatableRegs_PPC gives the allocator callee-saved fp
   1696          and Altivec regs, and no caller-save ones. */
   1697       addHRegUse(u, HRmWrite, hregPPC_GPR3(mode64));
   1698       addHRegUse(u, HRmWrite, hregPPC_GPR4(mode64));
   1699       addHRegUse(u, HRmWrite, hregPPC_GPR5(mode64));
   1700       addHRegUse(u, HRmWrite, hregPPC_GPR6(mode64));
   1701       addHRegUse(u, HRmWrite, hregPPC_GPR7(mode64));
   1702       addHRegUse(u, HRmWrite, hregPPC_GPR8(mode64));
   1703       addHRegUse(u, HRmWrite, hregPPC_GPR9(mode64));
   1704       addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64));
   1705       if (!mode64) {
   1706          addHRegUse(u, HRmWrite, hregPPC_GPR11(mode64));
   1707          addHRegUse(u, HRmWrite, hregPPC_GPR12(mode64));
   1708       }
   1709 
   1710       /* Now we have to state any parameter-carrying registers
   1711          which might be read.  This depends on the argiregs field. */
   1712       argir = i->Pin.Call.argiregs;
   1713       if (argir &(1<<10)) addHRegUse(u, HRmRead, hregPPC_GPR10(mode64));
   1714       if (argir & (1<<9)) addHRegUse(u, HRmRead, hregPPC_GPR9(mode64));
   1715       if (argir & (1<<8)) addHRegUse(u, HRmRead, hregPPC_GPR8(mode64));
   1716       if (argir & (1<<7)) addHRegUse(u, HRmRead, hregPPC_GPR7(mode64));
   1717       if (argir & (1<<6)) addHRegUse(u, HRmRead, hregPPC_GPR6(mode64));
   1718       if (argir & (1<<5)) addHRegUse(u, HRmRead, hregPPC_GPR5(mode64));
   1719       if (argir & (1<<4)) addHRegUse(u, HRmRead, hregPPC_GPR4(mode64));
   1720       if (argir & (1<<3)) addHRegUse(u, HRmRead, hregPPC_GPR3(mode64));
   1721 
   1722       vassert(0 == (argir & ~((1<<3)|(1<<4)|(1<<5)|(1<<6)
   1723                               |(1<<7)|(1<<8)|(1<<9)|(1<<10))));
   1724 
   1725       /* Finally, there is the issue that the insn trashes a
   1726          register because the literal target address has to be
   1727          loaded into a register.  %r10 seems a suitable victim.
   1728          (Can't use %r0, as some insns interpret it as value zero). */
   1729       addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64));
   1730       /* Upshot of this is that the assembler really must use %r10,
   1731          and no other, as a destination temporary. */
   1732       return;
   1733    }
   1734    case Pin_Goto:
   1735       addRegUsage_PPCRI(u, i->Pin.Goto.dst);
   1736       /* GPR3 holds destination address from Pin_Goto */
   1737       addHRegUse(u, HRmWrite, hregPPC_GPR3(mode64));
   1738       if (i->Pin.Goto.jk != Ijk_Boring
   1739           && i->Pin.Goto.jk != Ijk_Call
   1740           && i->Pin.Goto.jk != Ijk_Ret)
   1741             /* note, this is irrelevant since the guest state pointer
   1742                register is not actually available to the allocator.
   1743                But still .. */
   1744          addHRegUse(u, HRmWrite, GuestStatePtr(mode64));
   1745       return;
   1746    case Pin_CMov:
   1747       addRegUsage_PPCRI(u,  i->Pin.CMov.src);
   1748       addHRegUse(u, HRmWrite, i->Pin.CMov.dst);
   1749       return;
   1750    case Pin_Load:
   1751       addRegUsage_PPCAMode(u, i->Pin.Load.src);
   1752       addHRegUse(u, HRmWrite, i->Pin.Load.dst);
   1753       return;
   1754    case Pin_LoadL:
   1755       addHRegUse(u, HRmRead,  i->Pin.LoadL.src);
   1756       addHRegUse(u, HRmWrite, i->Pin.LoadL.dst);
   1757       return;
   1758    case Pin_Store:
   1759       addHRegUse(u, HRmRead,  i->Pin.Store.src);
   1760       addRegUsage_PPCAMode(u, i->Pin.Store.dst);
   1761       return;
   1762    case Pin_StoreC:
   1763       addHRegUse(u, HRmRead, i->Pin.StoreC.src);
   1764       addHRegUse(u, HRmRead, i->Pin.StoreC.dst);
   1765       return;
   1766    case Pin_Set:
   1767       addHRegUse(u, HRmWrite, i->Pin.Set.dst);
   1768       return;
   1769    case Pin_MfCR:
   1770       addHRegUse(u, HRmWrite, i->Pin.MfCR.dst);
   1771       return;
   1772    case Pin_MFence:
   1773       return;
   1774 
   1775    case Pin_FpUnary:
   1776       addHRegUse(u, HRmWrite, i->Pin.FpUnary.dst);
   1777       addHRegUse(u, HRmRead,  i->Pin.FpUnary.src);
   1778       return;
   1779    case Pin_FpBinary:
   1780       addHRegUse(u, HRmWrite, i->Pin.FpBinary.dst);
   1781       addHRegUse(u, HRmRead,  i->Pin.FpBinary.srcL);
   1782       addHRegUse(u, HRmRead,  i->Pin.FpBinary.srcR);
   1783       return;
   1784    case Pin_FpMulAcc:
   1785       addHRegUse(u, HRmWrite, i->Pin.FpMulAcc.dst);
   1786       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcML);
   1787       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcMR);
   1788       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcAcc);
   1789       return;
   1790    case Pin_FpLdSt:
   1791       addHRegUse(u, (i->Pin.FpLdSt.isLoad ? HRmWrite : HRmRead),
   1792                  i->Pin.FpLdSt.reg);
   1793       addRegUsage_PPCAMode(u, i->Pin.FpLdSt.addr);
   1794       return;
   1795    case Pin_FpSTFIW:
   1796       addHRegUse(u, HRmRead, i->Pin.FpSTFIW.addr);
   1797       addHRegUse(u, HRmRead, i->Pin.FpSTFIW.data);
   1798       return;
   1799    case Pin_FpRSP:
   1800       addHRegUse(u, HRmWrite, i->Pin.FpRSP.dst);
   1801       addHRegUse(u, HRmRead,  i->Pin.FpRSP.src);
   1802       return;
   1803    case Pin_FpCftI:
   1804       addHRegUse(u, HRmWrite, i->Pin.FpCftI.dst);
   1805       addHRegUse(u, HRmRead,  i->Pin.FpCftI.src);
   1806       return;
   1807    case Pin_FpCMov:
   1808       addHRegUse(u, HRmModify, i->Pin.FpCMov.dst);
   1809       addHRegUse(u, HRmRead,   i->Pin.FpCMov.src);
   1810       return;
   1811    case Pin_FpLdFPSCR:
   1812       addHRegUse(u, HRmRead, i->Pin.FpLdFPSCR.src);
   1813       return;
   1814    case Pin_FpCmp:
   1815       addHRegUse(u, HRmWrite, i->Pin.FpCmp.dst);
   1816       addHRegUse(u, HRmRead,  i->Pin.FpCmp.srcL);
   1817       addHRegUse(u, HRmRead,  i->Pin.FpCmp.srcR);
   1818       return;
   1819 
   1820    case Pin_RdWrLR:
   1821       addHRegUse(u, (i->Pin.RdWrLR.wrLR ? HRmRead : HRmWrite),
   1822                  i->Pin.RdWrLR.gpr);
   1823       return;
   1824 
   1825    case Pin_AvLdSt:
   1826       addHRegUse(u, (i->Pin.AvLdSt.isLoad ? HRmWrite : HRmRead),
   1827                  i->Pin.AvLdSt.reg);
   1828       if (i->Pin.AvLdSt.addr->tag == Pam_IR)
   1829          addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64));
   1830       addRegUsage_PPCAMode(u, i->Pin.AvLdSt.addr);
   1831       return;
   1832    case Pin_AvUnary:
   1833       addHRegUse(u, HRmWrite, i->Pin.AvUnary.dst);
   1834       addHRegUse(u, HRmRead,  i->Pin.AvUnary.src);
   1835       return;
   1836    case Pin_AvBinary:
   1837       if (i->Pin.AvBinary.op == Pav_XOR
   1838           && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcL
   1839           && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcR) {
   1840          /* reg-alloc needs to understand 'xor r,r,r' as a write of r */
   1841          /* (as opposed to a rite of passage :-) */
   1842          addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
   1843       } else {
   1844          addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
   1845          addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcL);
   1846          addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcR);
   1847       }
   1848       return;
   1849    case Pin_AvBin8x16:
   1850       addHRegUse(u, HRmWrite, i->Pin.AvBin8x16.dst);
   1851       addHRegUse(u, HRmRead,  i->Pin.AvBin8x16.srcL);
   1852       addHRegUse(u, HRmRead,  i->Pin.AvBin8x16.srcR);
   1853       return;
   1854    case Pin_AvBin16x8:
   1855       addHRegUse(u, HRmWrite, i->Pin.AvBin16x8.dst);
   1856       addHRegUse(u, HRmRead,  i->Pin.AvBin16x8.srcL);
   1857       addHRegUse(u, HRmRead,  i->Pin.AvBin16x8.srcR);
   1858       return;
   1859    case Pin_AvBin32x4:
   1860       addHRegUse(u, HRmWrite, i->Pin.AvBin32x4.dst);
   1861       addHRegUse(u, HRmRead,  i->Pin.AvBin32x4.srcL);
   1862       addHRegUse(u, HRmRead,  i->Pin.AvBin32x4.srcR);
   1863       return;
   1864    case Pin_AvBin32Fx4:
   1865       addHRegUse(u, HRmWrite, i->Pin.AvBin32Fx4.dst);
   1866       addHRegUse(u, HRmRead,  i->Pin.AvBin32Fx4.srcL);
   1867       addHRegUse(u, HRmRead,  i->Pin.AvBin32Fx4.srcR);
   1868       if (i->Pin.AvBin32Fx4.op == Pavfp_MULF)
   1869          addHRegUse(u, HRmWrite, hregPPC_VR29());
   1870       return;
   1871    case Pin_AvUn32Fx4:
   1872       addHRegUse(u, HRmWrite, i->Pin.AvUn32Fx4.dst);
   1873       addHRegUse(u, HRmRead,  i->Pin.AvUn32Fx4.src);
   1874       return;
   1875    case Pin_AvPerm:
   1876       addHRegUse(u, HRmWrite, i->Pin.AvPerm.dst);
   1877       addHRegUse(u, HRmRead,  i->Pin.AvPerm.srcL);
   1878       addHRegUse(u, HRmRead,  i->Pin.AvPerm.srcR);
   1879       addHRegUse(u, HRmRead,  i->Pin.AvPerm.ctl);
   1880       return;
   1881    case Pin_AvSel:
   1882       addHRegUse(u, HRmWrite, i->Pin.AvSel.dst);
   1883       addHRegUse(u, HRmRead,  i->Pin.AvSel.ctl);
   1884       addHRegUse(u, HRmRead,  i->Pin.AvSel.srcL);
   1885       addHRegUse(u, HRmRead,  i->Pin.AvSel.srcR);
   1886       return;
   1887    case Pin_AvShlDbl:
   1888       addHRegUse(u, HRmWrite, i->Pin.AvShlDbl.dst);
   1889       addHRegUse(u, HRmRead,  i->Pin.AvShlDbl.srcL);
   1890       addHRegUse(u, HRmRead,  i->Pin.AvShlDbl.srcR);
   1891       return;
   1892    case Pin_AvSplat:
   1893       addHRegUse(u, HRmWrite, i->Pin.AvSplat.dst);
   1894       addRegUsage_PPCVI5s(u,  i->Pin.AvSplat.src);
   1895       return;
   1896    case Pin_AvCMov:
   1897       addHRegUse(u, HRmModify, i->Pin.AvCMov.dst);
   1898       addHRegUse(u, HRmRead,   i->Pin.AvCMov.src);
   1899       return;
   1900    case Pin_AvLdVSCR:
   1901       addHRegUse(u, HRmRead, i->Pin.AvLdVSCR.src);
   1902       return;
   1903 
   1904    default:
   1905       ppPPCInstr(i, mode64);
   1906       vpanic("getRegUsage_PPCInstr");
   1907    }
   1908 }
   1909 
   1910 /* local helper */
   1911 static void mapReg( HRegRemap* m, HReg* r )
   1912 {
   1913    *r = lookupHRegRemap(m, *r);
   1914 }
   1915 
   1916 void mapRegs_PPCInstr ( HRegRemap* m, PPCInstr* i, Bool mode64 )
   1917 {
   1918    switch (i->tag) {
   1919    case Pin_LI:
   1920       mapReg(m, &i->Pin.LI.dst);
   1921       return;
   1922    case Pin_Alu:
   1923       mapReg(m, &i->Pin.Alu.dst);
   1924       mapReg(m, &i->Pin.Alu.srcL);
   1925       mapRegs_PPCRH(m, i->Pin.Alu.srcR);
   1926       return;
   1927    case Pin_Shft:
   1928       mapReg(m, &i->Pin.Shft.dst);
   1929       mapReg(m, &i->Pin.Shft.srcL);
   1930       mapRegs_PPCRH(m, i->Pin.Shft.srcR);
   1931       return;
   1932    case Pin_AddSubC:
   1933       mapReg(m, &i->Pin.AddSubC.dst);
   1934       mapReg(m, &i->Pin.AddSubC.srcL);
   1935       mapReg(m, &i->Pin.AddSubC.srcR);
   1936       return;
   1937    case Pin_Cmp:
   1938       mapReg(m, &i->Pin.Cmp.srcL);
   1939       mapRegs_PPCRH(m, i->Pin.Cmp.srcR);
   1940       return;
   1941    case Pin_Unary:
   1942       mapReg(m, &i->Pin.Unary.dst);
   1943       mapReg(m, &i->Pin.Unary.src);
   1944       return;
   1945    case Pin_MulL:
   1946       mapReg(m, &i->Pin.MulL.dst);
   1947       mapReg(m, &i->Pin.MulL.srcL);
   1948       mapReg(m, &i->Pin.MulL.srcR);
   1949       return;
   1950    case Pin_Div:
   1951       mapReg(m, &i->Pin.Div.dst);
   1952       mapReg(m, &i->Pin.Div.srcL);
   1953       mapReg(m, &i->Pin.Div.srcR);
   1954       return;
   1955    case Pin_Call:
   1956       return;
   1957    case Pin_Goto:
   1958       mapRegs_PPCRI(m, i->Pin.Goto.dst);
   1959       return;
   1960    case Pin_CMov:
   1961       mapRegs_PPCRI(m, i->Pin.CMov.src);
   1962       mapReg(m, &i->Pin.CMov.dst);
   1963       return;
   1964    case Pin_Load:
   1965       mapRegs_PPCAMode(m, i->Pin.Load.src);
   1966       mapReg(m, &i->Pin.Load.dst);
   1967       return;
   1968    case Pin_LoadL:
   1969       mapReg(m, &i->Pin.LoadL.src);
   1970       mapReg(m, &i->Pin.LoadL.dst);
   1971       return;
   1972    case Pin_Store:
   1973       mapReg(m, &i->Pin.Store.src);
   1974       mapRegs_PPCAMode(m, i->Pin.Store.dst);
   1975       return;
   1976    case Pin_StoreC:
   1977       mapReg(m, &i->Pin.StoreC.src);
   1978       mapReg(m, &i->Pin.StoreC.dst);
   1979       return;
   1980    case Pin_Set:
   1981       mapReg(m, &i->Pin.Set.dst);
   1982       return;
   1983    case Pin_MfCR:
   1984       mapReg(m, &i->Pin.MfCR.dst);
   1985       return;
   1986    case Pin_MFence:
   1987       return;
   1988    case Pin_FpUnary:
   1989       mapReg(m, &i->Pin.FpUnary.dst);
   1990       mapReg(m, &i->Pin.FpUnary.src);
   1991       return;
   1992    case Pin_FpBinary:
   1993       mapReg(m, &i->Pin.FpBinary.dst);
   1994       mapReg(m, &i->Pin.FpBinary.srcL);
   1995       mapReg(m, &i->Pin.FpBinary.srcR);
   1996       return;
   1997    case Pin_FpMulAcc:
   1998       mapReg(m, &i->Pin.FpMulAcc.dst);
   1999       mapReg(m, &i->Pin.FpMulAcc.srcML);
   2000       mapReg(m, &i->Pin.FpMulAcc.srcMR);
   2001       mapReg(m, &i->Pin.FpMulAcc.srcAcc);
   2002       return;
   2003    case Pin_FpLdSt:
   2004       mapReg(m, &i->Pin.FpLdSt.reg);
   2005       mapRegs_PPCAMode(m, i->Pin.FpLdSt.addr);
   2006       return;
   2007    case Pin_FpSTFIW:
   2008       mapReg(m, &i->Pin.FpSTFIW.addr);
   2009       mapReg(m, &i->Pin.FpSTFIW.data);
   2010       return;
   2011    case Pin_FpRSP:
   2012       mapReg(m, &i->Pin.FpRSP.dst);
   2013       mapReg(m, &i->Pin.FpRSP.src);
   2014       return;
   2015    case Pin_FpCftI:
   2016       mapReg(m, &i->Pin.FpCftI.dst);
   2017       mapReg(m, &i->Pin.FpCftI.src);
   2018       return;
   2019    case Pin_FpCMov:
   2020       mapReg(m, &i->Pin.FpCMov.dst);
   2021       mapReg(m, &i->Pin.FpCMov.src);
   2022       return;
   2023    case Pin_FpLdFPSCR:
   2024       mapReg(m, &i->Pin.FpLdFPSCR.src);
   2025       return;
   2026    case Pin_FpCmp:
   2027       mapReg(m, &i->Pin.FpCmp.dst);
   2028       mapReg(m, &i->Pin.FpCmp.srcL);
   2029       mapReg(m, &i->Pin.FpCmp.srcR);
   2030       return;
   2031    case Pin_RdWrLR:
   2032       mapReg(m, &i->Pin.RdWrLR.gpr);
   2033       return;
   2034    case Pin_AvLdSt:
   2035       mapReg(m, &i->Pin.AvLdSt.reg);
   2036       mapRegs_PPCAMode(m, i->Pin.AvLdSt.addr);
   2037       return;
   2038    case Pin_AvUnary:
   2039       mapReg(m, &i->Pin.AvUnary.dst);
   2040       mapReg(m, &i->Pin.AvUnary.src);
   2041       return;
   2042    case Pin_AvBinary:
   2043       mapReg(m, &i->Pin.AvBinary.dst);
   2044       mapReg(m, &i->Pin.AvBinary.srcL);
   2045       mapReg(m, &i->Pin.AvBinary.srcR);
   2046       return;
   2047    case Pin_AvBin8x16:
   2048       mapReg(m, &i->Pin.AvBin8x16.dst);
   2049       mapReg(m, &i->Pin.AvBin8x16.srcL);
   2050       mapReg(m, &i->Pin.AvBin8x16.srcR);
   2051       return;
   2052    case Pin_AvBin16x8:
   2053       mapReg(m, &i->Pin.AvBin16x8.dst);
   2054       mapReg(m, &i->Pin.AvBin16x8.srcL);
   2055       mapReg(m, &i->Pin.AvBin16x8.srcR);
   2056       return;
   2057    case Pin_AvBin32x4:
   2058       mapReg(m, &i->Pin.AvBin32x4.dst);
   2059       mapReg(m, &i->Pin.AvBin32x4.srcL);
   2060       mapReg(m, &i->Pin.AvBin32x4.srcR);
   2061       return;
   2062    case Pin_AvBin32Fx4:
   2063       mapReg(m, &i->Pin.AvBin32Fx4.dst);
   2064       mapReg(m, &i->Pin.AvBin32Fx4.srcL);
   2065       mapReg(m, &i->Pin.AvBin32Fx4.srcR);
   2066       return;
   2067    case Pin_AvUn32Fx4:
   2068       mapReg(m, &i->Pin.AvUn32Fx4.dst);
   2069       mapReg(m, &i->Pin.AvUn32Fx4.src);
   2070       return;
   2071    case Pin_AvPerm:
   2072       mapReg(m, &i->Pin.AvPerm.dst);
   2073       mapReg(m, &i->Pin.AvPerm.srcL);
   2074       mapReg(m, &i->Pin.AvPerm.srcR);
   2075       mapReg(m, &i->Pin.AvPerm.ctl);
   2076       return;
   2077    case Pin_AvSel:
   2078       mapReg(m, &i->Pin.AvSel.dst);
   2079       mapReg(m, &i->Pin.AvSel.srcL);
   2080       mapReg(m, &i->Pin.AvSel.srcR);
   2081       mapReg(m, &i->Pin.AvSel.ctl);
   2082       return;
   2083    case Pin_AvShlDbl:
   2084       mapReg(m, &i->Pin.AvShlDbl.dst);
   2085       mapReg(m, &i->Pin.AvShlDbl.srcL);
   2086       mapReg(m, &i->Pin.AvShlDbl.srcR);
   2087       return;
   2088    case Pin_AvSplat:
   2089       mapReg(m, &i->Pin.AvSplat.dst);
   2090       mapRegs_PPCVI5s(m, i->Pin.AvSplat.src);
   2091       return;
   2092    case Pin_AvCMov:
   2093      mapReg(m, &i->Pin.AvCMov.dst);
   2094      mapReg(m, &i->Pin.AvCMov.src);
   2095      return;
   2096    case Pin_AvLdVSCR:
   2097       mapReg(m, &i->Pin.AvLdVSCR.src);
   2098       return;
   2099 
   2100    default:
   2101       ppPPCInstr(i, mode64);
   2102       vpanic("mapRegs_PPCInstr");
   2103    }
   2104 }
   2105 
   2106 /* Figure out if i represents a reg-reg move, and if so assign the
   2107    source and destination to *src and *dst.  If in doubt say No.  Used
   2108    by the register allocator to do move coalescing.
   2109 */
   2110 Bool isMove_PPCInstr ( PPCInstr* i, HReg* src, HReg* dst )
   2111 {
   2112    /* Moves between integer regs */
   2113    if (i->tag == Pin_Alu) {
   2114       // or Rd,Rs,Rs == mr Rd,Rs
   2115       if (i->Pin.Alu.op != Palu_OR)
   2116          return False;
   2117       if (i->Pin.Alu.srcR->tag != Prh_Reg)
   2118          return False;
   2119       if (i->Pin.Alu.srcR->Prh.Reg.reg != i->Pin.Alu.srcL)
   2120          return False;
   2121       *src = i->Pin.Alu.srcL;
   2122       *dst = i->Pin.Alu.dst;
   2123       return True;
   2124    }
   2125    /* Moves between FP regs */
   2126    if (i->tag == Pin_FpUnary) {
   2127       if (i->Pin.FpUnary.op != Pfp_MOV)
   2128          return False;
   2129       *src = i->Pin.FpUnary.src;
   2130       *dst = i->Pin.FpUnary.dst;
   2131       return True;
   2132    }
   2133    return False;
   2134 }
   2135 
   2136 
   2137 /* Generate ppc spill/reload instructions under the direction of the
   2138    register allocator.  Note it's critical these don't write the
   2139    condition codes. */
   2140 
   2141 void genSpill_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
   2142                     HReg rreg, Int offsetB, Bool mode64 )
   2143 {
   2144    PPCAMode* am;
   2145    vassert(!hregIsVirtual(rreg));
   2146    *i1 = *i2 = NULL;
   2147    am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) );
   2148    switch (hregClass(rreg)) {
   2149       case HRcInt64:
   2150          vassert(mode64);
   2151          *i1 = PPCInstr_Store( 8, am, rreg, mode64 );
   2152          return;
   2153       case HRcInt32:
   2154          vassert(!mode64);
   2155          *i1 = PPCInstr_Store( 4, am, rreg, mode64 );
   2156          return;
   2157       case HRcFlt64:
   2158          *i1 = PPCInstr_FpLdSt ( False/*store*/, 8, rreg, am );
   2159          return;
   2160       case HRcVec128:
   2161          // XXX: GPR30 used as spill register to kludge AltiVec
   2162          // AMode_IR
   2163          *i1 = PPCInstr_AvLdSt ( False/*store*/, 16, rreg, am );
   2164          return;
   2165       default:
   2166          ppHRegClass(hregClass(rreg));
   2167          vpanic("genSpill_PPC: unimplemented regclass");
   2168    }
   2169 }
   2170 
   2171 void genReload_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
   2172                      HReg rreg, Int offsetB, Bool mode64 )
   2173 {
   2174    PPCAMode* am;
   2175    vassert(!hregIsVirtual(rreg));
   2176    *i1 = *i2 = NULL;
   2177    am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) );
   2178    switch (hregClass(rreg)) {
   2179       case HRcInt64:
   2180          vassert(mode64);
   2181          *i1 = PPCInstr_Load( 8, rreg, am, mode64 );
   2182          return;
   2183       case HRcInt32:
   2184          vassert(!mode64);
   2185          *i1 = PPCInstr_Load( 4, rreg, am, mode64 );
   2186          return;
   2187       case HRcFlt64:
   2188          *i1 = PPCInstr_FpLdSt ( True/*load*/, 8, rreg, am );
   2189          return;
   2190       case HRcVec128:
   2191          // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR
   2192          *i1 = PPCInstr_AvLdSt ( True/*load*/, 16, rreg, am );
   2193          return;
   2194       default:
   2195          ppHRegClass(hregClass(rreg));
   2196          vpanic("genReload_PPC: unimplemented regclass");
   2197    }
   2198 }
   2199 
   2200 
   2201 /* --------- The ppc assembler (bleh.) --------- */
   2202 
   2203 static UInt iregNo ( HReg r, Bool mode64 )
   2204 {
   2205    UInt n;
   2206    vassert(hregClass(r) == mode64 ? HRcInt64 : HRcInt32);
   2207    vassert(!hregIsVirtual(r));
   2208    n = hregNumber(r);
   2209    vassert(n <= 32);
   2210    return n;
   2211 }
   2212 
   2213 static UInt fregNo ( HReg fr )
   2214 {
   2215    UInt n;
   2216    vassert(hregClass(fr) == HRcFlt64);
   2217    vassert(!hregIsVirtual(fr));
   2218    n = hregNumber(fr);
   2219    vassert(n <= 32);
   2220    return n;
   2221 }
   2222 
   2223 static UInt vregNo ( HReg v )
   2224 {
   2225    UInt n;
   2226    vassert(hregClass(v) == HRcVec128);
   2227    vassert(!hregIsVirtual(v));
   2228    n = hregNumber(v);
   2229    vassert(n <= 32);
   2230    return n;
   2231 }
   2232 
   2233 /* Emit 32bit instruction big-endianly */
   2234 static UChar* emit32 ( UChar* p, UInt w32 )
   2235 {
   2236    *p++ = toUChar((w32 >> 24) & 0x000000FF);
   2237    *p++ = toUChar((w32 >> 16) & 0x000000FF);
   2238    *p++ = toUChar((w32 >>  8) & 0x000000FF);
   2239    *p++ = toUChar((w32)       & 0x000000FF);
   2240    return p;
   2241 }
   2242 
   2243 /* The following mkForm[...] functions refer to ppc instruction forms
   2244    as per PPC32 p576
   2245  */
   2246 
   2247 static UChar* mkFormD ( UChar* p, UInt opc1,
   2248                         UInt r1, UInt r2, UInt imm )
   2249 {
   2250    UInt theInstr;
   2251    vassert(opc1 < 0x40);
   2252    vassert(r1   < 0x20);
   2253    vassert(r2   < 0x20);
   2254    imm = imm & 0xFFFF;
   2255    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (imm));
   2256    return emit32(p, theInstr);
   2257 }
   2258 
   2259 static UChar* mkFormMD ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2260                          UInt imm1, UInt imm2, UInt opc2 )
   2261 {
   2262    UInt theInstr;
   2263    vassert(opc1 < 0x40);
   2264    vassert(r1   < 0x20);
   2265    vassert(r2   < 0x20);
   2266    vassert(imm1 < 0x40);
   2267    vassert(imm2 < 0x40);
   2268    vassert(opc2 < 0x08);
   2269    imm2 = ((imm2 & 0x1F) << 1) | (imm2 >> 5);
   2270    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2271                ((imm1 & 0x1F)<<11) | (imm2<<5) |
   2272                (opc2<<2) | ((imm1 >> 5)<<1));
   2273    return emit32(p, theInstr);
   2274 }
   2275 
   2276 static UChar* mkFormX ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2277                         UInt r3, UInt opc2, UInt b0 )
   2278 {
   2279    UInt theInstr;
   2280    vassert(opc1 < 0x40);
   2281    vassert(r1   < 0x20);
   2282    vassert(r2   < 0x20);
   2283    vassert(r3   < 0x20);
   2284    vassert(opc2 < 0x400);
   2285    vassert(b0   < 0x2);
   2286    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2287                (r3<<11) | (opc2<<1) | (b0));
   2288    return emit32(p, theInstr);
   2289 }
   2290 
   2291 static UChar* mkFormXO ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2292                          UInt r3, UInt b10, UInt opc2, UInt b0 )
   2293 {
   2294    UInt theInstr;
   2295    vassert(opc1 < 0x40);
   2296    vassert(r1   < 0x20);
   2297    vassert(r2   < 0x20);
   2298    vassert(r3   < 0x20);
   2299    vassert(b10  < 0x2);
   2300    vassert(opc2 < 0x200);
   2301    vassert(b0   < 0x2);
   2302    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2303                (r3<<11) | (b10 << 10) | (opc2<<1) | (b0));
   2304    return emit32(p, theInstr);
   2305 }
   2306 
   2307 static UChar* mkFormXL ( UChar* p, UInt opc1, UInt f1, UInt f2,
   2308                          UInt f3, UInt opc2, UInt b0 )
   2309 {
   2310    UInt theInstr;
   2311    vassert(opc1 < 0x40);
   2312    vassert(f1   < 0x20);
   2313    vassert(f2   < 0x20);
   2314    vassert(f3   < 0x20);
   2315    vassert(opc2 < 0x400);
   2316    vassert(b0   < 0x2);
   2317    theInstr = ((opc1<<26) | (f1<<21) | (f2<<16) |
   2318                (f3<<11) | (opc2<<1) | (b0));
   2319    return emit32(p, theInstr);
   2320 }
   2321 
   2322 // Note: for split field ops, give mnemonic arg
   2323 static UChar* mkFormXFX ( UChar* p, UInt r1, UInt f2, UInt opc2 )
   2324 {
   2325    UInt theInstr;
   2326    vassert(r1   < 0x20);
   2327    vassert(f2   < 0x20);
   2328    vassert(opc2 < 0x400);
   2329    switch (opc2) {
   2330    case 144:  // mtcrf
   2331       vassert(f2 < 0x100);
   2332       f2 = f2 << 1;
   2333       break;
   2334    case 339:  // mfspr
   2335    case 371:  // mftb
   2336    case 467:  // mtspr
   2337       vassert(f2 < 0x400);
   2338       // re-arrange split field
   2339       f2 = ((f2>>5) & 0x1F) | ((f2 & 0x1F)<<5);
   2340       break;
   2341    default: vpanic("mkFormXFX(ppch)");
   2342    }
   2343    theInstr = ((31<<26) | (r1<<21) | (f2<<11) | (opc2<<1));
   2344    return emit32(p, theInstr);
   2345 }
   2346 
   2347 // Only used by mtfsf
   2348 static UChar* mkFormXFL ( UChar* p, UInt FM, UInt freg )
   2349 {
   2350    UInt theInstr;
   2351    vassert(FM   < 0x100);
   2352    vassert(freg < 0x20);
   2353    theInstr = ((63<<26) | (FM<<17) | (freg<<11) | (711<<1));
   2354    return emit32(p, theInstr);
   2355 }
   2356 
   2357 static UChar* mkFormXS ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2358                          UInt imm, UInt opc2, UInt b0 )
   2359 {
   2360    UInt theInstr;
   2361    vassert(opc1 < 0x40);
   2362    vassert(r1   < 0x20);
   2363    vassert(r2   < 0x20);
   2364    vassert(imm  < 0x40);
   2365    vassert(opc2 < 0x400);
   2366    vassert(b0   < 0x2);
   2367    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2368                ((imm & 0x1F)<<11) | (opc2<<2) | ((imm>>5)<<1) | (b0));
   2369    return emit32(p, theInstr);
   2370 }
   2371 
   2372 
   2373 #if 0
   2374 // 'b'
   2375 static UChar* mkFormI ( UChar* p, UInt LI, UInt AA, UInt LK )
   2376 {
   2377    UInt theInstr;
   2378    vassert(LI  < 0x1000000);
   2379    vassert(AA  < 0x2);
   2380    vassert(LK  < 0x2);
   2381    theInstr = ((18<<26) | (LI<<2) | (AA<<1) | (LK));
   2382    return emit32(p, theInstr);
   2383 }
   2384 #endif
   2385 
   2386 // 'bc'
   2387 static UChar* mkFormB ( UChar* p, UInt BO, UInt BI,
   2388                         UInt BD, UInt AA, UInt LK )
   2389 {
   2390    UInt theInstr;
   2391    vassert(BO  < 0x20);
   2392    vassert(BI  < 0x20);
   2393    vassert(BD  < 0x4000);
   2394    vassert(AA  < 0x2);
   2395    vassert(LK  < 0x2);
   2396    theInstr = ((16<<26) | (BO<<21) | (BI<<16) |
   2397                (BD<<2) | (AA<<1) | (LK));
   2398    return emit32(p, theInstr);
   2399 }
   2400 
   2401 // rotates
   2402 static UChar* mkFormM ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2403                         UInt f3, UInt MB, UInt ME, UInt Rc )
   2404 {
   2405    UInt theInstr;
   2406    vassert(opc1 < 0x40);
   2407    vassert(r1   < 0x20);
   2408    vassert(r2   < 0x20);
   2409    vassert(f3   < 0x20);
   2410    vassert(MB   < 0x20);
   2411    vassert(ME   < 0x20);
   2412    vassert(Rc   < 0x2);
   2413    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2414                (f3<<11) | (MB<<6) | (ME<<1) | (Rc));
   2415    return emit32(p, theInstr);
   2416 }
   2417 
   2418 static UChar* mkFormA ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2419                         UInt r3, UInt r4, UInt opc2, UInt b0 )
   2420 {
   2421    UInt theInstr;
   2422    vassert(opc1 < 0x40);
   2423    vassert(r1   < 0x20);
   2424    vassert(r2   < 0x20);
   2425    vassert(r3   < 0x20);
   2426    vassert(r4   < 0x20);
   2427    vassert(opc2 < 0x20);
   2428    vassert(b0   < 0x2 );
   2429    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) |
   2430                (r4<<6) | (opc2<<1) | (b0));
   2431    return emit32(p, theInstr);
   2432 }
   2433 
   2434 static UChar* doAMode_IR ( UChar* p, UInt opc1, UInt rSD,
   2435                            PPCAMode* am, Bool mode64 )
   2436 {
   2437    UInt rA, idx;
   2438    vassert(am->tag == Pam_IR);
   2439    vassert(am->Pam.IR.index < 0x10000);
   2440 
   2441    rA  = iregNo(am->Pam.IR.base, mode64);
   2442    idx = am->Pam.IR.index;
   2443 
   2444    if (opc1 == 58 || opc1 == 62) { // ld/std: mode64 only
   2445       vassert(mode64);
   2446       /* stay sane with DS form: lowest 2 bits must be 00.  This
   2447          should be guaranteed to us by iselWordExpr_AMode. */
   2448       vassert(0 == (idx & 3));
   2449    }
   2450    p = mkFormD(p, opc1, rSD, rA, idx);
   2451    return p;
   2452 }
   2453 
   2454 static UChar* doAMode_RR ( UChar* p, UInt opc1, UInt opc2,
   2455                            UInt rSD, PPCAMode* am, Bool mode64 )
   2456 {
   2457    UInt rA, rB;
   2458    vassert(am->tag == Pam_RR);
   2459 
   2460    rA  = iregNo(am->Pam.RR.base, mode64);
   2461    rB  = iregNo(am->Pam.RR.index, mode64);
   2462 
   2463    p = mkFormX(p, opc1, rSD, rA, rB, opc2, 0);
   2464    return p;
   2465 }
   2466 
   2467 
   2468 /* Load imm to r_dst */
   2469 static UChar* mkLoadImm ( UChar* p, UInt r_dst, ULong imm, Bool mode64 )
   2470 {
   2471    vassert(r_dst < 0x20);
   2472 
   2473    if (!mode64) {
   2474       /* In 32-bit mode, make sure the top 32 bits of imm are a sign
   2475          extension of the bottom 32 bits, so that the range tests
   2476          below work correctly. */
   2477       UInt u32 = (UInt)imm;
   2478       Int  s32 = (Int)u32;
   2479       Long s64 = (Long)s32;
   2480       imm = (ULong)s64;
   2481    }
   2482 
   2483    if (imm >= 0xFFFFFFFFFFFF8000ULL || imm < 0x8000) {
   2484       // sign-extendable from 16 bits
   2485 
   2486       // addi r_dst,0,imm  => li r_dst,imm
   2487       p = mkFormD(p, 14, r_dst, 0, imm & 0xFFFF);
   2488    } else {
   2489       if (imm >= 0xFFFFFFFF80000000ULL || imm < 0x80000000ULL) {
   2490          // sign-extendable from 32 bits
   2491 
   2492          // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
   2493          p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF);
   2494          // ori r_dst, r_dst, (imm & 0xFFFF)
   2495          p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF);
   2496       } else {
   2497          // full 64bit immediate load: 5 (five!) insns.
   2498          vassert(mode64);
   2499 
   2500          // load high word
   2501 
   2502          // lis r_dst, (imm>>48) & 0xFFFF
   2503          p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF);
   2504 
   2505          // ori r_dst, r_dst, (imm>>32) & 0xFFFF
   2506          if ((imm>>32) & 0xFFFF)
   2507             p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF);
   2508 
   2509          // shift r_dst low word to high word => rldicr
   2510          p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1);
   2511 
   2512          // load low word
   2513 
   2514          // oris r_dst, r_dst, (imm>>16) & 0xFFFF
   2515          if ((imm>>16) & 0xFFFF)
   2516             p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF);
   2517 
   2518          // ori r_dst, r_dst, (imm) & 0xFFFF
   2519          if (imm & 0xFFFF)
   2520             p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF);
   2521       }
   2522    }
   2523    return p;
   2524 }
   2525 
   2526 /* Move r_dst to r_src */
   2527 static UChar* mkMoveReg ( UChar* p, UInt r_dst, UInt r_src )
   2528 {
   2529    vassert(r_dst < 0x20);
   2530    vassert(r_src < 0x20);
   2531 
   2532    if (r_dst != r_src) {
   2533       /* or r_dst, r_src, r_src */
   2534       p = mkFormX(p, 31, r_src, r_dst, r_src, 444, 0 );
   2535    }
   2536    return p;
   2537 }
   2538 
   2539 static UChar* mkFormVX ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2540                          UInt r3, UInt opc2 )
   2541 {
   2542    UInt theInstr;
   2543    vassert(opc1 < 0x40);
   2544    vassert(r1   < 0x20);
   2545    vassert(r2   < 0x20);
   2546    vassert(r3   < 0x20);
   2547    vassert(opc2 < 0x800);
   2548    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | opc2);
   2549    return emit32(p, theInstr);
   2550 }
   2551 
   2552 static UChar* mkFormVXR ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2553                           UInt r3, UInt Rc, UInt opc2 )
   2554 {
   2555    UInt theInstr;
   2556    vassert(opc1 < 0x40);
   2557    vassert(r1   < 0x20);
   2558    vassert(r2   < 0x20);
   2559    vassert(r3   < 0x20);
   2560    vassert(Rc   < 0x2);
   2561    vassert(opc2 < 0x400);
   2562    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2563                (r3<<11) | (Rc<<10) | opc2);
   2564    return emit32(p, theInstr);
   2565 }
   2566 
   2567 static UChar* mkFormVA ( UChar* p, UInt opc1, UInt r1, UInt r2,
   2568                          UInt r3, UInt r4, UInt opc2 )
   2569 {
   2570    UInt theInstr;
   2571    vassert(opc1 < 0x40);
   2572    vassert(r1   < 0x20);
   2573    vassert(r2   < 0x20);
   2574    vassert(r3   < 0x20);
   2575    vassert(r4   < 0x20);
   2576    vassert(opc2 < 0x40);
   2577    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
   2578                (r3<<11) | (r4<<6) | opc2);
   2579    return emit32(p, theInstr);
   2580 }
   2581 
   2582 
   2583 
   2584 /* Emit an instruction into buf and return the number of bytes used.
   2585    Note that buf is not the insn's final place, and therefore it is
   2586    imperative to emit position-independent code.
   2587 
   2588    Note, dispatch should always be NULL since ppc32/64 backends
   2589    use a call-return scheme to get from the dispatcher to generated
   2590    code and back.
   2591 */
   2592 Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i,
   2593                     Bool mode64, void* dispatch )
   2594 {
   2595    UChar* p = &buf[0];
   2596    UChar* ptmp = p;
   2597    vassert(nbuf >= 32);
   2598 
   2599    if (0) {
   2600       vex_printf("asm  ");ppPPCInstr(i, mode64); vex_printf("\n");
   2601    }
   2602 
   2603    switch (i->tag) {
   2604 
   2605    case Pin_LI:
   2606       p = mkLoadImm(p, iregNo(i->Pin.LI.dst, mode64),
   2607                     i->Pin.LI.imm64, mode64);
   2608       goto done;
   2609 
   2610    case Pin_Alu: {
   2611       PPCRH* srcR   = i->Pin.Alu.srcR;
   2612       Bool   immR   = toBool(srcR->tag == Prh_Imm);
   2613       UInt   r_dst  = iregNo(i->Pin.Alu.dst, mode64);
   2614       UInt   r_srcL = iregNo(i->Pin.Alu.srcL, mode64);
   2615       UInt   r_srcR = immR ? (-1)/*bogus*/ :
   2616                              iregNo(srcR->Prh.Reg.reg, mode64);
   2617 
   2618       switch (i->Pin.Alu.op) {
   2619       case Palu_ADD:
   2620          if (immR) {
   2621             /* addi (PPC32 p350) */
   2622             vassert(srcR->Prh.Imm.syned);
   2623             vassert(srcR->Prh.Imm.imm16 != 0x8000);
   2624             p = mkFormD(p, 14, r_dst, r_srcL, srcR->Prh.Imm.imm16);
   2625          } else {
   2626             /* add (PPC32 p347) */
   2627             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 266, 0);
   2628          }
   2629          break;
   2630 
   2631       case Palu_SUB:
   2632          if (immR) {
   2633             /* addi (PPC32 p350), but with negated imm */
   2634             vassert(srcR->Prh.Imm.syned);
   2635             vassert(srcR->Prh.Imm.imm16 != 0x8000);
   2636             p = mkFormD(p, 14, r_dst, r_srcL, (- srcR->Prh.Imm.imm16));
   2637          } else {
   2638             /* subf (PPC32 p537), with args the "wrong" way round */
   2639             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 40, 0);
   2640          }
   2641          break;
   2642 
   2643       case Palu_AND:
   2644          if (immR) {
   2645             /* andi. (PPC32 p358) */
   2646             vassert(!srcR->Prh.Imm.syned);
   2647             p = mkFormD(p, 28, r_srcL, r_dst, srcR->Prh.Imm.imm16);
   2648          } else {
   2649             /* and (PPC32 p356) */
   2650             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 28, 0);
   2651          }
   2652          break;
   2653 
   2654       case Palu_OR:
   2655          if (immR) {
   2656             /* ori (PPC32 p497) */
   2657             vassert(!srcR->Prh.Imm.syned);
   2658             p = mkFormD(p, 24, r_srcL, r_dst, srcR->Prh.Imm.imm16);
   2659          } else {
   2660             /* or (PPC32 p495) */
   2661             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 444, 0);
   2662          }
   2663          break;
   2664 
   2665       case Palu_XOR:
   2666          if (immR) {
   2667             /* xori (PPC32 p550) */
   2668             vassert(!srcR->Prh.Imm.syned);
   2669             p = mkFormD(p, 26, r_srcL, r_dst, srcR->Prh.Imm.imm16);
   2670          } else {
   2671             /* xor (PPC32 p549) */
   2672             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 316, 0);
   2673          }
   2674          break;
   2675 
   2676       default:
   2677          goto bad;
   2678       }
   2679       goto done;
   2680    }
   2681 
   2682    case Pin_Shft: {
   2683       PPCRH* srcR   = i->Pin.Shft.srcR;
   2684       Bool   sz32   = i->Pin.Shft.sz32;
   2685       Bool   immR   = toBool(srcR->tag == Prh_Imm);
   2686       UInt   r_dst  = iregNo(i->Pin.Shft.dst, mode64);
   2687       UInt   r_srcL = iregNo(i->Pin.Shft.srcL, mode64);
   2688       UInt   r_srcR = immR ? (-1)/*bogus*/ :
   2689                              iregNo(srcR->Prh.Reg.reg, mode64);
   2690       if (!mode64)
   2691          vassert(sz32);
   2692 
   2693       switch (i->Pin.Shft.op) {
   2694       case Pshft_SHL:
   2695          if (sz32) {
   2696             if (immR) {
   2697                /* rd = rs << n, 1 <= n <= 31
   2698                   is
   2699                   rlwinm rd,rs,n,0,31-n  (PPC32 p501)
   2700                */
   2701                UInt n = srcR->Prh.Imm.imm16;
   2702                vassert(!srcR->Prh.Imm.syned);
   2703                vassert(n > 0 && n < 32);
   2704                p = mkFormM(p, 21, r_srcL, r_dst, n, 0, 31-n, 0);
   2705             } else {
   2706                /* slw (PPC32 p505) */
   2707                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 24, 0);
   2708             }
   2709          } else {
   2710             if (immR) {
   2711                /* rd = rs << n, 1 <= n <= 63
   2712                   is
   2713                   rldicr rd,rs,n,63-n  (PPC64 p559)
   2714                */
   2715                UInt n = srcR->Prh.Imm.imm16;
   2716                vassert(!srcR->Prh.Imm.syned);
   2717                vassert(n > 0 && n < 64);
   2718                p = mkFormMD(p, 30, r_srcL, r_dst, n, 63-n, 1);
   2719             } else {
   2720                /* sld (PPC64 p568) */
   2721                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 27, 0);
   2722             }
   2723          }
   2724          break;
   2725 
   2726       case Pshft_SHR:
   2727          if (sz32) {
   2728              if (immR) {
   2729                /* rd = rs >>u n, 1 <= n <= 31
   2730                   is
   2731                   rlwinm rd,rs,32-n,n,31  (PPC32 p501)
   2732                */
   2733                UInt n = srcR->Prh.Imm.imm16;
   2734                vassert(!srcR->Prh.Imm.syned);
   2735                vassert(n > 0 && n < 32);
   2736                p = mkFormM(p, 21, r_srcL, r_dst, 32-n, n, 31, 0);
   2737             } else {
   2738                /* srw (PPC32 p508) */
   2739                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 536, 0);
   2740             }
   2741          } else {
   2742             if (immR) {
   2743                /* rd = rs >>u n, 1 <= n <= 63
   2744                   is
   2745                   rldicl rd,rs,64-n,n  (PPC64 p558)
   2746                */
   2747                UInt n = srcR->Prh.Imm.imm16;
   2748                vassert(!srcR->Prh.Imm.syned);
   2749                vassert(n > 0 && n < 64);
   2750                p = mkFormMD(p, 30, r_srcL, r_dst, 64-n, n, 0);
   2751             } else {
   2752                /* srd (PPC64 p574) */
   2753                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 539, 0);
   2754             }
   2755          }
   2756          break;
   2757 
   2758       case Pshft_SAR:
   2759          if (sz32) {
   2760             if (immR) {
   2761                /* srawi (PPC32 p507) */
   2762                UInt n = srcR->Prh.Imm.imm16;
   2763                vassert(!srcR->Prh.Imm.syned);
   2764                /* In 64-bit mode, we allow right shifts by zero bits
   2765                   as that is a handy way to sign extend the lower 32
   2766                   bits into the upper 32 bits. */
   2767                if (mode64)
   2768                   vassert(n >= 0 && n < 32);
   2769                else
   2770                   vassert(n > 0 && n < 32);
   2771                p = mkFormX(p, 31, r_srcL, r_dst, n, 824, 0);
   2772             } else {
   2773                /* sraw (PPC32 p506) */
   2774                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 792, 0);
   2775             }
   2776          } else {
   2777             if (immR) {
   2778                /* sradi (PPC64 p571) */
   2779                UInt n = srcR->Prh.Imm.imm16;
   2780                vassert(!srcR->Prh.Imm.syned);
   2781                vassert(n > 0 && n < 64);
   2782                p = mkFormXS(p, 31, r_srcL, r_dst, n, 413, 0);
   2783             } else {
   2784                /* srad (PPC32 p570) */
   2785                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 794, 0);
   2786             }
   2787          }
   2788          break;
   2789 
   2790       default:
   2791          goto bad;
   2792       }
   2793       goto done;
   2794    }
   2795 
   2796    case Pin_AddSubC: {
   2797       Bool isAdd  = i->Pin.AddSubC.isAdd;
   2798       Bool setC   = i->Pin.AddSubC.setC;
   2799       UInt r_srcL = iregNo(i->Pin.AddSubC.srcL, mode64);
   2800       UInt r_srcR = iregNo(i->Pin.AddSubC.srcR, mode64);
   2801       UInt r_dst  = iregNo(i->Pin.AddSubC.dst, mode64);
   2802 
   2803       if (isAdd) {
   2804          if (setC) /* addc (PPC32 p348) */
   2805             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 10, 0);
   2806          else          /* adde (PPC32 p349) */
   2807             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 138, 0);
   2808       } else {
   2809          /* subfX, with args the "wrong" way round */
   2810          if (setC) /* subfc (PPC32 p538) */
   2811             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 8, 0);
   2812          else          /* subfe (PPC32 p539) */
   2813             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 136, 0);
   2814       }
   2815       goto done;
   2816    }
   2817 
   2818    case Pin_Cmp: {
   2819       Bool syned  = i->Pin.Cmp.syned;
   2820       Bool sz32   = i->Pin.Cmp.sz32;
   2821       UInt fld1   = i->Pin.Cmp.crfD << 2;
   2822       UInt r_srcL = iregNo(i->Pin.Cmp.srcL, mode64);
   2823       UInt r_srcR, imm_srcR;
   2824       PPCRH* srcR = i->Pin.Cmp.srcR;
   2825 
   2826       if (!mode64)        // cmp double word invalid for mode32
   2827          vassert(sz32);
   2828       else if (!sz32)     // mode64 && cmp64: set L=1
   2829          fld1 |= 1;
   2830 
   2831       switch (srcR->tag) {
   2832       case Prh_Imm:
   2833          vassert(syned == srcR->Prh.Imm.syned);
   2834          imm_srcR = srcR->Prh.Imm.imm16;
   2835          if (syned) {  // cmpw/di  (signed)   (PPC32 p368)
   2836             vassert(imm_srcR != 0x8000);
   2837             p = mkFormD(p, 11, fld1, r_srcL, imm_srcR);
   2838          } else {      // cmplw/di (unsigned) (PPC32 p370)
   2839             p = mkFormD(p, 10, fld1, r_srcL, imm_srcR);
   2840          }
   2841          break;
   2842       case Prh_Reg:
   2843          r_srcR = iregNo(srcR->Prh.Reg.reg, mode64);
   2844          if (syned)  // cmpwi  (signed)   (PPC32 p367)
   2845             p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 0, 0);
   2846          else        // cmplwi (unsigned) (PPC32 p379)
   2847             p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 32, 0);
   2848          break;
   2849       default:
   2850          goto bad;
   2851       }
   2852       goto done;
   2853    }
   2854 
   2855    case Pin_Unary: {
   2856       UInt r_dst = iregNo(i->Pin.Unary.dst, mode64);
   2857       UInt r_src = iregNo(i->Pin.Unary.src, mode64);
   2858 
   2859       switch (i->Pin.Unary.op) {
   2860       case Pun_NOT:  // nor r_dst,r_src,r_src
   2861          p = mkFormX(p, 31, r_src, r_dst, r_src, 124, 0);
   2862          break;
   2863       case Pun_NEG:  // neg r_dst,r_src
   2864          p = mkFormXO(p, 31, r_dst, r_src, 0, 0, 104, 0);
   2865          break;
   2866       case Pun_CLZ32:  // cntlzw r_dst, r_src
   2867          p = mkFormX(p, 31, r_src, r_dst, 0, 26, 0);
   2868          break;
   2869       case Pun_CLZ64:  // cntlzd r_dst, r_src
   2870          vassert(mode64);
   2871          p = mkFormX(p, 31, r_src, r_dst, 0, 58, 0);
   2872          break;
   2873       case Pun_EXTSW:  // extsw r_dst, r_src
   2874          vassert(mode64);
   2875          p = mkFormX(p, 31, r_src, r_dst, 0, 986, 0);
   2876          break;
   2877       default: goto bad;
   2878       }
   2879       goto done;
   2880    }
   2881 
   2882    case Pin_MulL: {
   2883       Bool syned  = i->Pin.MulL.syned;
   2884       Bool sz32   = i->Pin.MulL.sz32;
   2885       UInt r_dst  = iregNo(i->Pin.MulL.dst, mode64);
   2886       UInt r_srcL = iregNo(i->Pin.MulL.srcL, mode64);
   2887       UInt r_srcR = iregNo(i->Pin.MulL.srcR, mode64);
   2888 
   2889       if (!mode64)
   2890          vassert(sz32);
   2891 
   2892       if (i->Pin.MulL.hi) {
   2893          // mul hi words, must consider sign
   2894          if (sz32) {
   2895             if (syned)  // mulhw r_dst,r_srcL,r_srcR
   2896                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 75, 0);
   2897             else        // mulhwu r_dst,r_srcL,r_srcR
   2898                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 11, 0);
   2899          } else {
   2900             if (syned)  // mulhd r_dst,r_srcL,r_srcR
   2901                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 73, 0);
   2902             else        // mulhdu r_dst,r_srcL,r_srcR
   2903                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 9, 0);
   2904          }
   2905       } else {
   2906          // mul low word, sign is irrelevant
   2907          vassert(!i->Pin.MulL.syned);
   2908          if (sz32)      // mullw r_dst,r_srcL,r_srcR
   2909             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 235, 0);
   2910          else           // mulld r_dst,r_srcL,r_srcR
   2911             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 233, 0);
   2912       }
   2913       goto done;
   2914    }
   2915 
   2916    case Pin_Div: {
   2917       Bool syned  = i->Pin.Div.syned;
   2918       Bool sz32   = i->Pin.Div.sz32;
   2919       UInt r_dst  = iregNo(i->Pin.Div.dst, mode64);
   2920       UInt r_srcL = iregNo(i->Pin.Div.srcL, mode64);
   2921       UInt r_srcR = iregNo(i->Pin.Div.srcR, mode64);
   2922 
   2923       if (!mode64)
   2924          vassert(sz32);
   2925 
   2926       if (sz32) {
   2927          if (syned)  // divw r_dst,r_srcL,r_srcR
   2928             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 491, 0);
   2929          else        // divwu r_dst,r_srcL,r_srcR
   2930             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 459, 0);
   2931       } else {
   2932          if (syned)  // divd r_dst,r_srcL,r_srcR
   2933             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 489, 0);
   2934          else        // divdu r_dst,r_srcL,r_srcR
   2935             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 457, 0);
   2936       }
   2937       goto done;
   2938    }
   2939 
   2940    case Pin_Call: {
   2941       PPCCondCode cond  = i->Pin.Call.cond;
   2942       UInt        r_dst = 10;
   2943       /* As per detailed comment for Pin_Call in
   2944          getRegUsage_PPCInstr above, %r10 is used as an address temp */
   2945 
   2946       /* jump over the following insns if condition does not hold */
   2947       if (cond.test != Pct_ALWAYS) {
   2948          /* jmp fwds if !condition */
   2949          /* don't know how many bytes to jump over yet...
   2950             make space for a jump instruction and fill in later. */
   2951          ptmp = p; /* fill in this bit later */
   2952          p += 4;                                          // p += 4
   2953       }
   2954 
   2955       /* load target to r_dst */                          // p += 4|8|20
   2956       p = mkLoadImm(p, r_dst, i->Pin.Call.target, mode64);
   2957 
   2958       /* mtspr 9,r_dst => move r_dst to count register */
   2959       p = mkFormXFX(p, r_dst, 9, 467);                    // p += 4
   2960 
   2961       /* bctrl => branch to count register (and save to lr) */
   2962       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 1);      // p += 4
   2963 
   2964       /* Fix up the conditional jump, if there was one. */
   2965       if (cond.test != Pct_ALWAYS) {
   2966          Int delta = p - ptmp;
   2967          vassert(delta >= 16 && delta <= 32);
   2968          /* bc !ct,cf,delta */
   2969          mkFormB(ptmp, invertCondTest(cond.test),
   2970                  cond.flag, (delta>>2), 0, 0);
   2971       }
   2972       goto done;
   2973    }
   2974 
   2975    case Pin_Goto: {
   2976       UInt        trc   = 0;
   2977       UChar       r_ret = 3;        /* Put target addr into %r3 */
   2978       PPCCondCode cond  = i->Pin.Goto.cond;
   2979       UInt r_dst;
   2980       ULong imm_dst;
   2981 
   2982       vassert(dispatch == NULL);
   2983 
   2984       /* First off, if this is conditional, create a conditional
   2985          jump over the rest of it. */
   2986       if (cond.test != Pct_ALWAYS) {
   2987          /* jmp fwds if !condition */
   2988          /* don't know how many bytes to jump over yet...
   2989             make space for a jump instruction and fill in later. */
   2990          ptmp = p; /* fill in this bit later */
   2991          p += 4;
   2992       }
   2993 
   2994       // cond succeeds...
   2995 
   2996       /* If a non-boring, set GuestStatePtr appropriately. */
   2997       switch (i->Pin.Goto.jk) {
   2998          case Ijk_ClientReq:   trc = VEX_TRC_JMP_CLIENTREQ;   break;
   2999          case Ijk_Sys_syscall: trc = VEX_TRC_JMP_SYS_SYSCALL; break;
   3000          case Ijk_Yield:       trc = VEX_TRC_JMP_YIELD;       break;
   3001          case Ijk_YieldNoRedir: trc = VEX_TRC_JMP_YIELD_NOREDIR; break;
   3002          case Ijk_EmWarn:      trc = VEX_TRC_JMP_EMWARN;      break;
   3003          case Ijk_EmFail:      trc = VEX_TRC_JMP_EMFAIL;      break;
   3004          case Ijk_MapFail:     trc = VEX_TRC_JMP_MAPFAIL;     break;
   3005          case Ijk_NoDecode:    trc = VEX_TRC_JMP_NODECODE;    break;
   3006          case Ijk_TInval:      trc = VEX_TRC_JMP_TINVAL;      break;
   3007          case Ijk_NoRedir:     trc = VEX_TRC_JMP_NOREDIR;     break;
   3008          case Ijk_SigTRAP:     trc = VEX_TRC_JMP_SIGTRAP;     break;
   3009          case Ijk_SigBUS:      trc = VEX_TRC_JMP_SIGBUS;      break;
   3010          case Ijk_Ret:
   3011          case Ijk_Call:
   3012          case Ijk_Boring:
   3013             break;
   3014          default:
   3015             ppIRJumpKind(i->Pin.Goto.jk);
   3016             vpanic("emit_PPCInstr.Pin_Goto: unknown jump kind");
   3017       }
   3018       if (trc !=0) {
   3019          vassert(trc < 0x10000);
   3020          /* addi r31,0,trc */
   3021          p = mkFormD(p, 14, 31, 0, trc);               // p += 4
   3022       }
   3023 
   3024       /* Get the destination address into %r_ret */
   3025       if (i->Pin.Goto.dst->tag == Pri_Imm) {
   3026          imm_dst = i->Pin.Goto.dst->Pri.Imm;
   3027          p = mkLoadImm(p, r_ret, imm_dst, mode64);     // p += 4|8|20
   3028       } else {
   3029          vassert(i->Pin.Goto.dst->tag == Pri_Reg);
   3030          r_dst = iregNo(i->Pin.Goto.dst->Pri.Reg, mode64);
   3031          p = mkMoveReg(p, r_ret, r_dst);               // p += 4
   3032       }
   3033 
   3034       /* blr */
   3035       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 16, 0);    // p += 4
   3036 
   3037       /* Fix up the conditional jump, if there was one. */
   3038       if (cond.test != Pct_ALWAYS) {
   3039          Int delta = p - ptmp;
   3040          vassert(delta >= 12 && delta <= 32);
   3041          /* bc !ct,cf,delta */
   3042          mkFormB(ptmp, invertCondTest(cond.test),
   3043                  cond.flag, delta>>2, 0, 0);
   3044       }
   3045       goto done;
   3046    }
   3047 
   3048    case Pin_CMov: {
   3049       UInt  r_dst, r_src;
   3050       ULong imm_src;
   3051       PPCCondCode cond;
   3052       vassert(i->Pin.CMov.cond.test != Pct_ALWAYS);
   3053 
   3054       r_dst = iregNo(i->Pin.CMov.dst, mode64);
   3055       cond = i->Pin.CMov.cond;
   3056 
   3057       /* branch (if cond fails) over move instrs */
   3058       if (cond.test != Pct_ALWAYS) {
   3059          /* don't know how many bytes to jump over yet...
   3060             make space for a jump instruction and fill in later. */
   3061          ptmp = p; /* fill in this bit later */
   3062          p += 4;
   3063       }
   3064 
   3065       // cond true: move src => dst
   3066       switch (i->Pin.CMov.src->tag) {
   3067       case Pri_Imm:
   3068          imm_src = i->Pin.CMov.src->Pri.Imm;
   3069          p = mkLoadImm(p, r_dst, imm_src, mode64);  // p += 4|8|20
   3070          break;
   3071       case Pri_Reg:
   3072          r_src = iregNo(i->Pin.CMov.src->Pri.Reg, mode64);
   3073          p = mkMoveReg(p, r_dst, r_src);            // p += 4
   3074          break;
   3075       default: goto bad;
   3076       }
   3077 
   3078       /* Fix up the conditional jump, if there was one. */
   3079       if (cond.test != Pct_ALWAYS) {
   3080          Int delta = p - ptmp;
   3081          vassert(delta >= 8 && delta <= 24);
   3082          /* bc !ct,cf,delta */
   3083          mkFormB(ptmp, invertCondTest(cond.test),
   3084                  cond.flag, (delta>>2), 0, 0);
   3085       }
   3086       goto done;
   3087    }
   3088 
   3089    case Pin_Load: {
   3090       PPCAMode* am_addr = i->Pin.Load.src;
   3091       UInt r_dst = iregNo(i->Pin.Load.dst, mode64);
   3092       UInt opc1, opc2, sz = i->Pin.Load.sz;
   3093       switch (am_addr->tag) {
   3094       case Pam_IR:
   3095          if (mode64 && (sz == 4 || sz == 8)) {
   3096             /* should be guaranteed to us by iselWordExpr_AMode */
   3097             vassert(0 == (am_addr->Pam.IR.index & 3));
   3098          }
   3099          switch(sz) {
   3100             case 1:  opc1 = 34; break;
   3101             case 2:  opc1 = 40; break;
   3102             case 4:  opc1 = 32; break;
   3103             case 8:  opc1 = 58; vassert(mode64); break;
   3104             default: goto bad;
   3105          }
   3106          p = doAMode_IR(p, opc1, r_dst, am_addr, mode64);
   3107          goto done;
   3108       case Pam_RR:
   3109          switch(sz) {
   3110             case 1:  opc2 = 87;  break;
   3111             case 2:  opc2 = 279; break;
   3112             case 4:  opc2 = 23;  break;
   3113             case 8:  opc2 = 21; vassert(mode64); break;
   3114             default: goto bad;
   3115          }
   3116          p = doAMode_RR(p, 31, opc2, r_dst, am_addr, mode64);
   3117          goto done;
   3118       default:
   3119          goto bad;
   3120       }
   3121    }
   3122 
   3123    case Pin_LoadL: {
   3124       if (i->Pin.LoadL.sz == 4) {
   3125          p = mkFormX(p, 31, iregNo(i->Pin.LoadL.dst, mode64),
   3126                      0, iregNo(i->Pin.LoadL.src, mode64), 20, 0);
   3127          goto done;
   3128       }
   3129       if (i->Pin.LoadL.sz == 8 && mode64) {
   3130          p = mkFormX(p, 31, iregNo(i->Pin.LoadL.dst, mode64),
   3131                      0, iregNo(i->Pin.LoadL.src, mode64), 84, 0);
   3132          goto done;
   3133       }
   3134       goto bad;
   3135    }
   3136 
   3137    case Pin_Set: {
   3138       /* Make the destination register be 1 or 0, depending on whether
   3139          the relevant condition holds. */
   3140       UInt        r_dst = iregNo(i->Pin.Set.dst, mode64);
   3141       PPCCondCode cond  = i->Pin.Set.cond;
   3142       UInt rot_imm, r_tmp;
   3143 
   3144       if (cond.test == Pct_ALWAYS) {
   3145          // Just load 1 to dst => li dst,1
   3146          p = mkFormD(p, 14, r_dst, 0, 1);
   3147       } else {
   3148          rot_imm = 1 + cond.flag;
   3149          r_tmp = 0;  // Not set in getAllocable, so no need to declare.
   3150 
   3151          // r_tmp = CR  => mfcr r_tmp
   3152          p = mkFormX(p, 31, r_tmp, 0, 0, 19, 0);
   3153 
   3154          // r_dst = flag (rotate left and mask)
   3155          //  => rlwinm r_dst,r_tmp,rot_imm,31,31
   3156          p = mkFormM(p, 21, r_tmp, r_dst, rot_imm, 31, 31, 0);
   3157 
   3158          if (cond.test == Pct_FALSE) {
   3159             // flip bit  => xori r_dst,r_dst,1
   3160             p = mkFormD(p, 26, r_dst, r_dst, 1);
   3161          }
   3162       }
   3163       goto done;
   3164    }
   3165 
   3166    case Pin_MfCR:
   3167       // mfcr dst
   3168       p = mkFormX(p, 31, iregNo(i->Pin.MfCR.dst, mode64), 0, 0, 19, 0);
   3169       goto done;
   3170 
   3171    case Pin_MFence: {
   3172       p = mkFormX(p, 31, 0, 0, 0, 598, 0);   // sync, PPC32 p616
   3173       // CAB: Should this be isync?
   3174       //    p = mkFormXL(p, 19, 0, 0, 0, 150, 0);  // isync, PPC32 p467
   3175       goto done;
   3176    }
   3177 
   3178    case Pin_Store: {
   3179       PPCAMode* am_addr = i->Pin.Store.dst;
   3180       UInt r_src = iregNo(i->Pin.Store.src, mode64);
   3181       UInt opc1, opc2, sz = i->Pin.Store.sz;
   3182       switch (i->Pin.Store.dst->tag) {
   3183       case Pam_IR:
   3184          if (mode64 && (sz == 4 || sz == 8)) {
   3185             /* should be guaranteed to us by iselWordExpr_AMode */
   3186             vassert(0 == (am_addr->Pam.IR.index & 3));
   3187          }
   3188          switch(sz) {
   3189          case 1: opc1 = 38; break;
   3190          case 2: opc1 = 44; break;
   3191          case 4: opc1 = 36; break;
   3192          case 8: vassert(mode64);
   3193                  opc1 = 62; break;
   3194          default:
   3195             goto bad;
   3196          }
   3197          p = doAMode_IR(p, opc1, r_src, am_addr, mode64);
   3198          goto done;
   3199       case Pam_RR:
   3200          switch(sz) {
   3201          case 1: opc2 = 215; break;
   3202          case 2: opc2 = 407; break;
   3203          case 4: opc2 = 151; break;
   3204          case 8: vassert(mode64);
   3205                  opc2 = 149; break;
   3206          default:
   3207             goto bad;
   3208          }
   3209          p = doAMode_RR(p, 31, opc2, r_src, am_addr, mode64);
   3210          goto done;
   3211       default:
   3212          goto bad;
   3213       }
   3214       goto done;
   3215    }
   3216 
   3217    case Pin_StoreC: {
   3218       if (i->Pin.StoreC.sz == 4) {
   3219          p = mkFormX(p, 31, iregNo(i->Pin.StoreC.src, mode64),
   3220                      0, iregNo(i->Pin.StoreC.dst, mode64), 150, 1);
   3221          goto done;
   3222       }
   3223       if (i->Pin.StoreC.sz == 8 && mode64) {
   3224          p = mkFormX(p, 31, iregNo(i->Pin.StoreC.src, mode64),
   3225                      0, iregNo(i->Pin.StoreC.dst, mode64), 214, 1);
   3226          goto done;
   3227       }
   3228       goto bad;
   3229    }
   3230 
   3231    case Pin_FpUnary: {
   3232       UInt fr_dst = fregNo(i->Pin.FpUnary.dst);
   3233       UInt fr_src = fregNo(i->Pin.FpUnary.src);
   3234       switch (i->Pin.FpUnary.op) {
   3235       case Pfp_RSQRTE: // frsqrtre, PPC32 p424
   3236          p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 26, 0 );
   3237          break;
   3238       case Pfp_RES:   // fres, PPC32 p421
   3239          p = mkFormA( p, 59, fr_dst, 0, fr_src, 0, 24, 0 );
   3240          break;
   3241       case Pfp_SQRT:  // fsqrt, PPC32 p427
   3242          p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 22, 0 );
   3243          break;
   3244       case Pfp_ABS:   // fabs, PPC32 p399
   3245          p = mkFormX(p, 63, fr_dst, 0, fr_src, 264, 0);
   3246          break;
   3247       case Pfp_NEG:   // fneg, PPC32 p416
   3248          p = mkFormX(p, 63, fr_dst, 0, fr_src, 40, 0);
   3249          break;
   3250       case Pfp_MOV:   // fmr, PPC32 p410
   3251          p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0);
   3252          break;
   3253       case Pfp_FRIM:  // frim, PPC ISA 2.05 p137
   3254          p = mkFormX(p, 63, fr_dst, 0, fr_src, 488, 0);
   3255          break;
   3256       case Pfp_FRIP:  // frip, PPC ISA 2.05 p137
   3257          p = mkFormX(p, 63, fr_dst, 0, fr_src, 456, 0);
   3258          break;
   3259       case Pfp_FRIN:  // frin, PPC ISA 2.05 p137
   3260          p = mkFormX(p, 63, fr_dst, 0, fr_src, 392, 0);
   3261          break;
   3262       case Pfp_FRIZ:  // friz, PPC ISA 2.05 p137
   3263          p = mkFormX(p, 63, fr_dst, 0, fr_src, 424, 0);
   3264          break;
   3265       default:
   3266          goto bad;
   3267       }
   3268       goto done;
   3269    }
   3270 
   3271    case Pin_FpBinary: {
   3272       UInt fr_dst  = fregNo(i->Pin.FpBinary.dst);
   3273       UInt fr_srcL = fregNo(i->Pin.FpBinary.srcL);
   3274       UInt fr_srcR = fregNo(i->Pin.FpBinary.srcR);
   3275       switch (i->Pin.FpBinary.op) {
   3276       case Pfp_ADDD:   // fadd, PPC32 p400
   3277          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 21, 0 );
   3278          break;
   3279       case Pfp_ADDS:   // fadds, PPC32 p401
   3280          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 21, 0 );
   3281          break;
   3282       case Pfp_SUBD:   // fsub, PPC32 p429
   3283          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 20, 0 );
   3284          break;
   3285       case Pfp_SUBS:   // fsubs, PPC32 p430
   3286          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 20, 0 );
   3287          break;
   3288       case Pfp_MULD:   // fmul, PPC32 p413
   3289          p = mkFormA( p, 63, fr_dst, fr_srcL, 0, fr_srcR, 25, 0 );
   3290          break;
   3291       case Pfp_MULS:   // fmuls, PPC32 p414
   3292          p = mkFormA( p, 59, fr_dst, fr_srcL, 0, fr_srcR, 25, 0 );
   3293          break;
   3294       case Pfp_DIVD:   // fdiv, PPC32 p406
   3295          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 18, 0 );
   3296          break;
   3297       case Pfp_DIVS:   // fdivs, PPC32 p407
   3298          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 18, 0 );
   3299          break;
   3300       default:
   3301          goto bad;
   3302       }
   3303       goto done;
   3304    }
   3305 
   3306    case Pin_FpMulAcc: {
   3307       UInt fr_dst    = fregNo(i->Pin.FpMulAcc.dst);
   3308       UInt fr_srcML  = fregNo(i->Pin.FpMulAcc.srcML);
   3309       UInt fr_srcMR  = fregNo(i->Pin.FpMulAcc.srcMR);
   3310       UInt fr_srcAcc = fregNo(i->Pin.FpMulAcc.srcAcc);
   3311       switch (i->Pin.FpMulAcc.op) {
   3312       case Pfp_MADDD:   // fmadd, PPC32 p408
   3313          p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0 );
   3314          break;
   3315       case Pfp_MADDS:   // fmadds, PPC32 p409
   3316          p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0 );
   3317          break;
   3318       case Pfp_MSUBD:   // fmsub, PPC32 p411
   3319          p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0 );
   3320          break;
   3321       case Pfp_MSUBS:   // fmsubs, PPC32 p412
   3322          p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0 );
   3323          break;
   3324       default:
   3325          goto bad;
   3326       }
   3327       goto done;
   3328    }
   3329 
   3330    case Pin_FpLdSt: {
   3331       PPCAMode* am_addr = i->Pin.FpLdSt.addr;
   3332       UInt f_reg = fregNo(i->Pin.FpLdSt.reg);
   3333       Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR);
   3334       UChar sz = i->Pin.FpLdSt.sz;
   3335       UInt opc;
   3336       vassert(sz == 4 || sz == 8);
   3337 
   3338       if (i->Pin.FpLdSt.isLoad) {   // Load from memory
   3339          if (idxd) {  // lf[s|d]x, PPC32 p444|440
   3340             opc = (sz == 4) ? 535 : 599;
   3341             p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64);
   3342          } else {     // lf[s|d], PPC32 p441|437
   3343             opc = (sz == 4) ? 48 : 50;
   3344             p = doAMode_IR(p, opc, f_reg, am_addr, mode64);
   3345          }
   3346       } else {                      // Store to memory
   3347          if (idxd) { // stf[s|d]x, PPC32 p521|516
   3348             opc = (sz == 4) ? 663 : 727;
   3349             p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64);
   3350          } else {    // stf[s|d], PPC32 p518|513
   3351             opc = (sz == 4) ? 52 : 54;
   3352             p = doAMode_IR(p, opc, f_reg, am_addr, mode64);
   3353          }
   3354       }
   3355       goto done;
   3356    }
   3357 
   3358    case Pin_FpSTFIW: {
   3359       UInt ir_addr = iregNo(i->Pin.FpSTFIW.addr, mode64);
   3360       UInt fr_data = fregNo(i->Pin.FpSTFIW.data);
   3361       // stfiwx (store fp64[lo32] as int32), PPC32 p517
   3362       // Use rA==0, so that EA == rB == ir_addr
   3363       p = mkFormX(p, 31, fr_data, 0/*rA=0*/, ir_addr, 983, 0);
   3364       goto done;
   3365    }
   3366 
   3367    case Pin_FpRSP: {
   3368       UInt fr_dst = fregNo(i->Pin.FpRSP.dst);
   3369       UInt fr_src = fregNo(i->Pin.FpRSP.src);
   3370       // frsp, PPC32 p423
   3371       p = mkFormX(p, 63, fr_dst, 0, fr_src, 12, 0);
   3372       goto done;
   3373    }
   3374 
   3375    case Pin_FpCftI: {
   3376       UInt fr_dst = fregNo(i->Pin.FpCftI.dst);
   3377       UInt fr_src = fregNo(i->Pin.FpCftI.src);
   3378       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True) {
   3379          // fctiw (conv f64 to i32), PPC32 p404
   3380          p = mkFormX(p, 63, fr_dst, 0, fr_src, 14, 0);
   3381          goto done;
   3382       }
   3383       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False) {
   3384          // fctid (conv f64 to i64), PPC64 p437
   3385          p = mkFormX(p, 63, fr_dst, 0, fr_src, 814, 0);
   3386          goto done;
   3387       }
   3388       if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
   3389          // fcfid (conv i64 to f64), PPC64 p434
   3390          p = mkFormX(p, 63, fr_dst, 0, fr_src, 846, 0);
   3391          goto done;
   3392       }
   3393       goto bad;
   3394    }
   3395 
   3396    case Pin_FpCMov: {
   3397       UInt        fr_dst = fregNo(i->Pin.FpCMov.dst);
   3398       UInt        fr_src = fregNo(i->Pin.FpCMov.src);
   3399       PPCCondCode cc     = i->Pin.FpCMov.cond;
   3400 
   3401       if (fr_dst == fr_src) goto done;
   3402 
   3403       vassert(cc.test != Pct_ALWAYS);
   3404 
   3405       /* jmp fwds if !condition */
   3406       if (cc.test != Pct_ALWAYS) {
   3407          /* bc !ct,cf,n_bytes>>2 */
   3408          p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0);
   3409       }
   3410 
   3411       // fmr, PPC32 p410
   3412       p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0);
   3413       goto done;
   3414    }
   3415 
   3416    case Pin_FpLdFPSCR: {
   3417       UInt fr_src = fregNo(i->Pin.FpLdFPSCR.src);
   3418       p = mkFormXFL(p, 0xFF, fr_src);     // mtfsf, PPC32 p480
   3419       goto done;
   3420    }
   3421 
   3422    case Pin_FpCmp: {
   3423       UChar crfD    = 1;
   3424       UInt  r_dst   = iregNo(i->Pin.FpCmp.dst, mode64);
   3425       UInt  fr_srcL = fregNo(i->Pin.FpCmp.srcL);
   3426       UInt  fr_srcR = fregNo(i->Pin.FpCmp.srcR);
   3427       vassert(crfD < 8);
   3428       // fcmpo, PPC32 p402
   3429       p = mkFormX(p, 63, crfD<<2, fr_srcL, fr_srcR, 32, 0);
   3430 
   3431       // mfcr (mv CR to r_dst), PPC32 p467
   3432       p = mkFormX(p, 31, r_dst, 0, 0, 19, 0);
   3433 
   3434       // rlwinm r_dst,r_dst,8,28,31, PPC32 p501
   3435       //  => rotate field 1 to bottomw of word, masking out upper 28
   3436       p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0);
   3437       goto done;
   3438    }
   3439 
   3440    case Pin_RdWrLR: {
   3441       UInt reg = iregNo(i->Pin.RdWrLR.gpr, mode64);
   3442       /* wrLR==True ? mtlr r4 : mflr r4 */
   3443       p = mkFormXFX(p, reg, 8, (i->Pin.RdWrLR.wrLR==True) ? 467 : 339);
   3444       goto done;
   3445    }
   3446 
   3447 
   3448    /* AltiVec */
   3449    case Pin_AvLdSt: {
   3450       UInt opc2, v_reg, r_idx, r_base;
   3451       UChar sz   = i->Pin.AvLdSt.sz;
   3452       Bool  idxd = toBool(i->Pin.AvLdSt.addr->tag == Pam_RR);
   3453       vassert(sz == 1 || sz == 2 || sz == 4 || sz == 16);
   3454 
   3455       v_reg  = vregNo(i->Pin.AvLdSt.reg);
   3456       r_base = iregNo(i->Pin.AvLdSt.addr->Pam.RR.base, mode64);
   3457 
   3458       // Only have AltiVec AMode_RR: kludge AMode_IR
   3459       if (!idxd) {
   3460          r_idx = 30;                       // XXX: Using r30 as temp
   3461          p = mkLoadImm(p, r_idx,
   3462                        i->Pin.AvLdSt.addr->Pam.IR.index, mode64);
   3463       } else {
   3464          r_idx  = iregNo(i->Pin.AvLdSt.addr->Pam.RR.index, mode64);
   3465       }
   3466 
   3467       if (i->Pin.FpLdSt.isLoad) {  // Load from memory (1,2,4,16)
   3468          opc2 = (sz==1) ?   7 : (sz==2) ?  39 : (sz==4) ?  71 : 103;
   3469          p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0);
   3470       } else {                      // Store to memory (1,2,4,16)
   3471          opc2 = (sz==1) ? 135 : (sz==2) ? 167 : (sz==4) ? 199 : 231;
   3472          p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0);
   3473       }
   3474       goto done;
   3475    }
   3476 
   3477    case Pin_AvUnary: {
   3478       UInt v_dst = vregNo(i->Pin.AvUnary.dst);
   3479       UInt v_src = vregNo(i->Pin.AvUnary.src);
   3480       UInt opc2;
   3481       switch (i->Pin.AvUnary.op) {
   3482       case Pav_MOV:       opc2 = 1156; break; // vor vD,vS,vS
   3483       case Pav_NOT:       opc2 = 1284; break; // vnor vD,vS,vS
   3484       case Pav_UNPCKH8S:  opc2 =  526; break; // vupkhsb
   3485       case Pav_UNPCKH16S: opc2 =  590; break; // vupkhsh
   3486       case Pav_UNPCKL8S:  opc2 =  654; break; // vupklsb
   3487       case Pav_UNPCKL16S: opc2 =  718; break; // vupklsh
   3488       case Pav_UNPCKHPIX: opc2 =  846; break; // vupkhpx
   3489       case Pav_UNPCKLPIX: opc2 =  974; break; // vupklpx
   3490       default:
   3491          goto bad;
   3492       }
   3493       switch (i->Pin.AvUnary.op) {
   3494       case Pav_MOV:
   3495       case Pav_NOT:
   3496          p = mkFormVX( p, 4, v_dst, v_src, v_src, opc2 );
   3497          break;
   3498       default:
   3499          p = mkFormVX( p, 4, v_dst, 0, v_src, opc2 );
   3500          break;
   3501       }
   3502       goto done;
   3503    }
   3504 
   3505    case Pin_AvBinary: {
   3506       UInt v_dst  = vregNo(i->Pin.AvBinary.dst);
   3507       UInt v_srcL = vregNo(i->Pin.AvBinary.srcL);
   3508       UInt v_srcR = vregNo(i->Pin.AvBinary.srcR);
   3509       UInt opc2;
   3510       if (i->Pin.AvBinary.op == Pav_SHL) {
   3511          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1036 ); // vslo
   3512          p = mkFormVX( p, 4, v_dst, v_dst,  v_srcR, 452 );  // vsl
   3513          goto done;
   3514       }
   3515       if (i->Pin.AvBinary.op == Pav_SHR) {
   3516          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1100 ); // vsro
   3517          p = mkFormVX( p, 4, v_dst, v_dst,  v_srcR, 708 );  // vsr
   3518          goto done;
   3519       }
   3520       switch (i->Pin.AvBinary.op) {
   3521       /* Bitwise */
   3522       case Pav_AND:       opc2 = 1028; break; // vand
   3523       case Pav_OR:        opc2 = 1156; break; // vor
   3524       case Pav_XOR:       opc2 = 1220; break; // vxor
   3525       default:
   3526          goto bad;
   3527       }
   3528       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
   3529       goto done;
   3530    }
   3531 
   3532    case Pin_AvBin8x16: {
   3533       UInt v_dst  = vregNo(i->Pin.AvBin8x16.dst);
   3534       UInt v_srcL = vregNo(i->Pin.AvBin8x16.srcL);
   3535       UInt v_srcR = vregNo(i->Pin.AvBin8x16.srcR);
   3536       UInt opc2;
   3537       switch (i->Pin.AvBin8x16.op) {
   3538 
   3539       case Pav_ADDU:     opc2 =    0; break; // vaddubm
   3540       case Pav_QADDU:    opc2 =  512; break; // vaddubs
   3541       case Pav_QADDS:    opc2 =  768; break; // vaddsbs
   3542 
   3543       case Pav_SUBU:     opc2 = 1024; break; // vsububm
   3544       case Pav_QSUBU:    opc2 = 1536; break; // vsububs
   3545       case Pav_QSUBS:    opc2 = 1792; break; // vsubsbs
   3546 
   3547       case Pav_OMULU:   opc2 =    8; break; // vmuloub
   3548       case Pav_OMULS:   opc2 =  264; break; // vmulosb
   3549       case Pav_EMULU:   opc2 =  520; break; // vmuleub
   3550       case Pav_EMULS:   opc2 =  776; break; // vmulesb
   3551 
   3552       case Pav_AVGU:     opc2 = 1026; break; // vavgub
   3553       case Pav_AVGS:     opc2 = 1282; break; // vavgsb
   3554       case Pav_MAXU:     opc2 =    2; break; // vmaxub
   3555       case Pav_MAXS:     opc2 =  258; break; // vmaxsb
   3556       case Pav_MINU:     opc2 =  514; break; // vminub
   3557       case Pav_MINS:     opc2 =  770; break; // vminsb
   3558 
   3559       case Pav_CMPEQU:   opc2 =    6; break; // vcmpequb
   3560       case Pav_CMPGTU:   opc2 =  518; break; // vcmpgtub
   3561       case Pav_CMPGTS:   opc2 =  774; break; // vcmpgtsb
   3562 
   3563       case Pav_SHL:      opc2 =  260; break; // vslb
   3564       case Pav_SHR:      opc2 =  516; break; // vsrb
   3565       case Pav_SAR:      opc2 =  772; break; // vsrab
   3566       case Pav_ROTL:     opc2 =    4; break; // vrlb
   3567 
   3568       case Pav_MRGHI:    opc2 =   12; break; // vmrghb
   3569       case Pav_MRGLO:    opc2 =  268; break; // vmrglb
   3570 
   3571       default:
   3572          goto bad;
   3573       }
   3574       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
   3575       goto done;
   3576    }
   3577 
   3578    case Pin_AvBin16x8: {
   3579       UInt v_dst  = vregNo(i->Pin.AvBin16x8.dst);
   3580       UInt v_srcL = vregNo(i->Pin.AvBin16x8.srcL);
   3581       UInt v_srcR = vregNo(i->Pin.AvBin16x8.srcR);
   3582       UInt opc2;
   3583       switch (i->Pin.AvBin16x8.op) {
   3584 
   3585       case Pav_ADDU:    opc2 =   64; break; // vadduhm
   3586       case Pav_QADDU:   opc2 =  576; break; // vadduhs
   3587       case Pav_QADDS:   opc2 =  832; break; // vaddshs
   3588 
   3589       case Pav_SUBU:    opc2 = 1088; break; // vsubuhm
   3590       case Pav_QSUBU:   opc2 = 1600; break; // vsubuhs
   3591       case Pav_QSUBS:   opc2 = 1856; break; // vsubshs
   3592 
   3593       case Pav_OMULU:   opc2 =   72; break; // vmulouh
   3594       case Pav_OMULS:   opc2 =  328; break; // vmulosh
   3595       case Pav_EMULU:   opc2 =  584; break; // vmuleuh
   3596       case Pav_EMULS:   opc2 =  840; break; // vmulesh
   3597 
   3598       case Pav_AVGU:    opc2 = 1090; break; // vavguh
   3599       case Pav_AVGS:    opc2 = 1346; break; // vavgsh
   3600       case Pav_MAXU:    opc2 =   66; break; // vmaxuh
   3601       case Pav_MAXS:    opc2 =  322; break; // vmaxsh
   3602       case Pav_MINS:    opc2 =  834; break; // vminsh
   3603       case Pav_MINU:    opc2 =  578; break; // vminuh
   3604 
   3605       case Pav_CMPEQU:  opc2 =   70; break; // vcmpequh
   3606       case Pav_CMPGTU:  opc2 =  582; break; // vcmpgtuh
   3607       case Pav_CMPGTS:  opc2 =  838; break; // vcmpgtsh
   3608 
   3609       case Pav_SHL:     opc2 =  324; break; // vslh
   3610       case Pav_SHR:     opc2 =  580; break; // vsrh
   3611       case Pav_SAR:     opc2 =  836; break; // vsrah
   3612       case Pav_ROTL:    opc2 =   68; break; // vrlh
   3613 
   3614       case Pav_PACKUU:  opc2 =   14; break; // vpkuhum
   3615       case Pav_QPACKUU: opc2 =  142; break; // vpkuhus
   3616       case Pav_QPACKSU: opc2 =  270; break; // vpkshus
   3617       case Pav_QPACKSS: opc2 =  398; break; // vpkshss
   3618       case Pav_PACKPXL: opc2 =  782; break; // vpkpx
   3619 
   3620       case Pav_MRGHI:   opc2 =   76; break; // vmrghh
   3621       case Pav_MRGLO:   opc2 =  332; break; // vmrglh
   3622 
   3623       default:
   3624          goto bad;
   3625       }
   3626       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
   3627       goto done;
   3628    }
   3629 
   3630    case Pin_AvBin32x4: {
   3631       UInt v_dst  = vregNo(i->Pin.AvBin32x4.dst);
   3632       UInt v_srcL = vregNo(i->Pin.AvBin32x4.srcL);
   3633       UInt v_srcR = vregNo(i->Pin.AvBin32x4.srcR);
   3634       UInt opc2;
   3635       switch (i->Pin.AvBin32x4.op) {
   3636 
   3637       case Pav_ADDU:    opc2 =  128; break; // vadduwm
   3638       case Pav_QADDU:   opc2 =  640; break; // vadduws
   3639       case Pav_QADDS:   opc2 =  896; break; // vaddsws
   3640 
   3641       case Pav_SUBU:    opc2 = 1152; break; // vsubuwm
   3642       case Pav_QSUBU:   opc2 = 1664; break; // vsubuws
   3643       case Pav_QSUBS:   opc2 = 1920; break; // vsubsws
   3644 
   3645       case Pav_AVGU:    opc2 = 1154; break; // vavguw
   3646       case Pav_AVGS:    opc2 = 1410; break; // vavgsw
   3647 
   3648       case Pav_MAXU:    opc2 =  130; break; // vmaxuw
   3649       case Pav_MAXS:    opc2 =  386; break; // vmaxsw
   3650 
   3651       case Pav_MINS:    opc2 =  898; break; // vminsw
   3652       case Pav_MINU:    opc2 =  642; break; // vminuw
   3653 
   3654       case Pav_CMPEQU:  opc2 =  134; break; // vcmpequw
   3655       case Pav_CMPGTS:  opc2 =  902; break; // vcmpgtsw
   3656       case Pav_CMPGTU:  opc2 =  646; break; // vcmpgtuw
   3657 
   3658       case Pav_SHL:     opc2 =  388; break; // vslw
   3659       case Pav_SHR:     opc2 =  644; break; // vsrw
   3660       case Pav_SAR:     opc2 =  900; break; // vsraw
   3661       case Pav_ROTL:    opc2 =  132; break; // vrlw
   3662 
   3663       case Pav_PACKUU:  opc2 =   78; break; // vpkuwum
   3664       case Pav_QPACKUU: opc2 =  206; break; // vpkuwus
   3665       case Pav_QPACKSU: opc2 =  334; break; // vpkswus
   3666       case Pav_QPACKSS: opc2 =  462; break; // vpkswss
   3667 
   3668       case Pav_MRGHI:   opc2 =  140; break; // vmrghw
   3669       case Pav_MRGLO:   opc2 =  396; break; // vmrglw
   3670 
   3671       default:
   3672          goto bad;
   3673       }
   3674       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
   3675       goto done;
   3676    }
   3677 
   3678    case Pin_AvBin32Fx4: {
   3679       UInt v_dst  = vregNo(i->Pin.AvBin32Fx4.dst);
   3680       UInt v_srcL = vregNo(i->Pin.AvBin32Fx4.srcL);
   3681       UInt v_srcR = vregNo(i->Pin.AvBin32Fx4.srcR);
   3682       switch (i->Pin.AvBin32Fx4.op) {
   3683 
   3684       case Pavfp_ADDF:
   3685          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 10 );   // vaddfp
   3686          break;
   3687       case Pavfp_SUBF:
   3688          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 74 );   // vsubfp
   3689          break;
   3690       case Pavfp_MAXF:
   3691          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1034 ); // vmaxfp
   3692          break;
   3693       case Pavfp_MINF:
   3694          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1098 ); // vminfp
   3695          break;
   3696 
   3697       case Pavfp_MULF: {
   3698          /* Make a vmulfp from a vmaddfp:
   3699             load -0.0 (0x8000_0000) to each 32-bit word of vB
   3700             this makes the add a noop.
   3701          */
   3702          UInt vB = 29;  // XXX: Using v29 for temp do not change
   3703                         // without also changing
   3704                         // getRegUsage_PPCInstr
   3705          UInt konst = 0x1F;
   3706 
   3707          // Better way to load -0.0 (0x80000000) ?
   3708          // vspltisw vB,0x1F   (0x1F => each word of vB)
   3709          p = mkFormVX( p, 4, vB, konst, 0, 908 );
   3710 
   3711          // vslw vB,vB,vB (each word of vB = (0x1F << 0x1F) = 0x80000000
   3712          p = mkFormVX( p, 4, vB, vB, vB, 388 );
   3713 
   3714          // Finally, do the multiply:
   3715          p = mkFormVA( p, 4, v_dst, v_srcL, vB, v_srcR, 46 );
   3716          break;
   3717       }
   3718       case Pavfp_CMPEQF:  // vcmpeqfp
   3719          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 198 );
   3720          break;
   3721       case Pavfp_CMPGTF:  // vcmpgtfp
   3722          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 710 );
   3723          break;
   3724       case Pavfp_CMPGEF:  // vcmpgefp
   3725          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 454 );
   3726          break;
   3727 
   3728       default:
   3729          goto bad;
   3730       }
   3731       goto done;
   3732    }
   3733 
   3734    case Pin_AvUn32Fx4: {
   3735       UInt v_dst = vregNo(i->Pin.AvUn32Fx4.dst);
   3736       UInt v_src = vregNo(i->Pin.AvUn32Fx4.src);
   3737       UInt opc2;
   3738       switch (i->Pin.AvUn32Fx4.op) {
   3739       case Pavfp_RCPF:    opc2 =  266; break; // vrefp
   3740       case Pavfp_RSQRTF:  opc2 =  330; break; // vrsqrtefp
   3741       case Pavfp_CVTU2F:  opc2 =  778; break; // vcfux
   3742       case Pavfp_CVTS2F:  opc2 =  842; break; // vcfsx
   3743       case Pavfp_QCVTF2U: opc2 =  906; break; // vctuxs
   3744       case Pavfp_QCVTF2S: opc2 =  970; break; // vctsxs
   3745       case Pavfp_ROUNDM:  opc2 =  714; break; // vrfim
   3746       case Pavfp_ROUNDP:  opc2 =  650; break; // vrfip
   3747       case Pavfp_ROUNDN:  opc2 =  522; break; // vrfin
   3748       case Pavfp_ROUNDZ:  opc2 =  586; break; // vrfiz
   3749       default:
   3750          goto bad;
   3751       }
   3752       p = mkFormVX( p, 4, v_dst, 0, v_src, opc2 );
   3753       goto done;
   3754    }
   3755 
   3756    case Pin_AvPerm: {  // vperm
   3757       UInt v_dst  = vregNo(i->Pin.AvPerm.dst);
   3758       UInt v_srcL = vregNo(i->Pin.AvPerm.srcL);
   3759       UInt v_srcR = vregNo(i->Pin.AvPerm.srcR);
   3760       UInt v_ctl  = vregNo(i->Pin.AvPerm.ctl);
   3761       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 43 );
   3762       goto done;
   3763    }
   3764 
   3765    case Pin_AvSel: {  // vsel
   3766       UInt v_ctl  = vregNo(i->Pin.AvSel.ctl);
   3767       UInt v_dst  = vregNo(i->Pin.AvSel.dst);
   3768       UInt v_srcL = vregNo(i->Pin.AvSel.srcL);
   3769       UInt v_srcR = vregNo(i->Pin.AvSel.srcR);
   3770       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 42 );
   3771       goto done;
   3772    }
   3773 
   3774    case Pin_AvShlDbl: {  // vsldoi
   3775       UInt shift  = i->Pin.AvShlDbl.shift;
   3776       UInt v_dst  = vregNo(i->Pin.AvShlDbl.dst);
   3777       UInt v_srcL = vregNo(i->Pin.AvShlDbl.srcL);
   3778       UInt v_srcR = vregNo(i->Pin.AvShlDbl.srcR);
   3779       vassert(shift <= 0xF);
   3780       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, shift, 44 );
   3781       goto done;
   3782    }
   3783 
   3784    case Pin_AvSplat: { // vsplt(is)(b,h,w)
   3785       UInt v_dst = vregNo(i->Pin.AvShlDbl.dst);
   3786       UChar sz   = i->Pin.AvSplat.sz;
   3787       UInt v_src, opc2;
   3788       vassert(sz == 8 || sz == 16 || sz == 32);
   3789 
   3790       if (i->Pin.AvSplat.src->tag == Pvi_Imm) {
   3791          Char simm5;
   3792          opc2 = (sz == 8) ? 780 : (sz == 16) ? 844 : 908;   // 8,16,32
   3793          /* expects 5-bit-signed-imm */
   3794          simm5 = i->Pin.AvSplat.src->Pvi.Imm5s;
   3795          vassert(simm5 >= -16 && simm5 <= 15);
   3796          simm5 = simm5 & 0x1F;
   3797          p = mkFormVX( p, 4, v_dst, (UInt)simm5, 0, opc2 );
   3798       }
   3799       else {  // Pri_Reg
   3800          UInt lowest_lane;
   3801          opc2 = (sz == 8) ? 524 : (sz == 16) ? 588 : 652;  // 8,16,32
   3802          vassert(hregClass(i->Pin.AvSplat.src->Pvi.Reg) == HRcVec128);
   3803          v_src = vregNo(i->Pin.AvSplat.src->Pvi.Reg);
   3804          lowest_lane = (128/sz)-1;
   3805          p = mkFormVX( p, 4, v_dst, lowest_lane, v_src, opc2 );
   3806       }
   3807       goto done;
   3808    }
   3809 
   3810    case Pin_AvCMov: {
   3811       UInt v_dst     = vregNo(i->Pin.AvCMov.dst);
   3812       UInt v_src     = vregNo(i->Pin.AvCMov.src);
   3813       PPCCondCode cc = i->Pin.AvCMov.cond;
   3814 
   3815       if (v_dst == v_src) goto done;
   3816 
   3817       vassert(cc.test != Pct_ALWAYS);
   3818 
   3819       /* jmp fwds 2 insns if !condition */
   3820       if (cc.test != Pct_ALWAYS) {
   3821          /* bc !ct,cf,n_bytes>>2 */
   3822          p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0);
   3823       }
   3824       /* vmr */
   3825       p = mkFormVX( p, 4, v_dst, v_src, v_src, 1156 );
   3826       goto done;
   3827    }
   3828 
   3829    case Pin_AvLdVSCR: {  // mtvscr
   3830       UInt v_src = vregNo(i->Pin.AvLdVSCR.src);
   3831       p = mkFormVX( p, 4, 0, 0, v_src, 1604 );
   3832       goto done;
   3833    }
   3834 
   3835    default:
   3836       goto bad;
   3837    }
   3838 
   3839   bad:
   3840    vex_printf("\n=> ");
   3841    ppPPCInstr(i, mode64);
   3842    vpanic("emit_PPCInstr");
   3843    /*NOTREACHED*/
   3844 
   3845   done:
   3846    vassert(p - &buf[0] <= 32);
   3847    return p - &buf[0];
   3848 }
   3849 
   3850 /*---------------------------------------------------------------*/
   3851 /*--- end                                     host_ppc_defs.c ---*/
   3852 /*---------------------------------------------------------------*/
   3853