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