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