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