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