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