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