]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/host_ppc_defs.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / priv / host_ppc_defs.c
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-2010 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
47 void ppHRegPPC ( HReg reg ) 
48 {
49    Int r;
50    static HChar* ireg32_names[32] 
51       = { "%r0",  "%r1",  "%r2",  "%r3",
52           "%r4",  "%r5",  "%r6",  "%r7",
53           "%r8",  "%r9",  "%r10", "%r11",
54           "%r12", "%r13", "%r14", "%r15",
55           "%r16", "%r17", "%r18", "%r19",
56           "%r20", "%r21", "%r22", "%r23",
57           "%r24", "%r25", "%r26", "%r27",
58           "%r28", "%r29", "%r30", "%r31" };
59    /* Be generic for all virtual regs. */
60    if (hregIsVirtual(reg)) {
61       ppHReg(reg);
62       return;
63    }
64    /* But specific for real regs. */
65    switch (hregClass(reg)) {
66    case HRcInt64:
67       r = hregNumber(reg);
68       vassert(r >= 0 && r < 32);
69       vex_printf("%s", ireg32_names[r]);
70       return;
71    case HRcInt32:
72       r = hregNumber(reg);
73       vassert(r >= 0 && r < 32);
74       vex_printf("%s", ireg32_names[r]);
75       return;
76    case HRcFlt64:
77       r = hregNumber(reg);
78       vassert(r >= 0 && r < 32);
79       vex_printf("%%fr%d", r);
80       return;
81    case HRcVec128:
82       r = hregNumber(reg);
83       vassert(r >= 0 && r < 32);
84       vex_printf("%%v%d", r);
85       return;
86    default:
87       vpanic("ppHRegPPC");
88    }
89 }
90
91
92 #define MkHRegGPR(_n, _mode64) \
93    mkHReg(_n, _mode64 ? HRcInt64 : HRcInt32, False)
94
95 HReg hregPPC_GPR0  ( Bool mode64 ) { return MkHRegGPR( 0, mode64); }
96 HReg hregPPC_GPR1  ( Bool mode64 ) { return MkHRegGPR( 1, mode64); }
97 HReg hregPPC_GPR2  ( Bool mode64 ) { return MkHRegGPR( 2, mode64); }
98 HReg hregPPC_GPR3  ( Bool mode64 ) { return MkHRegGPR( 3, mode64); }
99 HReg hregPPC_GPR4  ( Bool mode64 ) { return MkHRegGPR( 4, mode64); }
100 HReg hregPPC_GPR5  ( Bool mode64 ) { return MkHRegGPR( 5, mode64); }
101 HReg hregPPC_GPR6  ( Bool mode64 ) { return MkHRegGPR( 6, mode64); }
102 HReg hregPPC_GPR7  ( Bool mode64 ) { return MkHRegGPR( 7, mode64); }
103 HReg hregPPC_GPR8  ( Bool mode64 ) { return MkHRegGPR( 8, mode64); }
104 HReg hregPPC_GPR9  ( Bool mode64 ) { return MkHRegGPR( 9, mode64); }
105 HReg hregPPC_GPR10 ( Bool mode64 ) { return MkHRegGPR(10, mode64); }
106 HReg hregPPC_GPR11 ( Bool mode64 ) { return MkHRegGPR(11, mode64); }
107 HReg hregPPC_GPR12 ( Bool mode64 ) { return MkHRegGPR(12, mode64); }
108 HReg hregPPC_GPR13 ( Bool mode64 ) { return MkHRegGPR(13, mode64); }
109 HReg hregPPC_GPR14 ( Bool mode64 ) { return MkHRegGPR(14, mode64); }
110 HReg hregPPC_GPR15 ( Bool mode64 ) { return MkHRegGPR(15, mode64); }
111 HReg hregPPC_GPR16 ( Bool mode64 ) { return MkHRegGPR(16, mode64); }
112 HReg hregPPC_GPR17 ( Bool mode64 ) { return MkHRegGPR(17, mode64); }
113 HReg hregPPC_GPR18 ( Bool mode64 ) { return MkHRegGPR(18, mode64); }
114 HReg hregPPC_GPR19 ( Bool mode64 ) { return MkHRegGPR(19, mode64); }
115 HReg hregPPC_GPR20 ( Bool mode64 ) { return MkHRegGPR(20, mode64); }
116 HReg hregPPC_GPR21 ( Bool mode64 ) { return MkHRegGPR(21, mode64); }
117 HReg hregPPC_GPR22 ( Bool mode64 ) { return MkHRegGPR(22, mode64); }
118 HReg hregPPC_GPR23 ( Bool mode64 ) { return MkHRegGPR(23, mode64); }
119 HReg hregPPC_GPR24 ( Bool mode64 ) { return MkHRegGPR(24, mode64); }
120 HReg hregPPC_GPR25 ( Bool mode64 ) { return MkHRegGPR(25, mode64); }
121 HReg hregPPC_GPR26 ( Bool mode64 ) { return MkHRegGPR(26, mode64); }
122 HReg hregPPC_GPR27 ( Bool mode64 ) { return MkHRegGPR(27, mode64); }
123 HReg hregPPC_GPR28 ( Bool mode64 ) { return MkHRegGPR(28, mode64); }
124 HReg hregPPC_GPR29 ( Bool mode64 ) { return MkHRegGPR(29, mode64); }
125 HReg hregPPC_GPR30 ( Bool mode64 ) { return MkHRegGPR(30, mode64); }
126 HReg hregPPC_GPR31 ( Bool mode64 ) { return MkHRegGPR(31, mode64); }
127
128 #undef MK_INT_HREG
129
130 HReg hregPPC_FPR0  ( void ) { return mkHReg( 0, HRcFlt64, False); }
131 HReg hregPPC_FPR1  ( void ) { return mkHReg( 1, HRcFlt64, False); }
132 HReg hregPPC_FPR2  ( void ) { return mkHReg( 2, HRcFlt64, False); }
133 HReg hregPPC_FPR3  ( void ) { return mkHReg( 3, HRcFlt64, False); }
134 HReg hregPPC_FPR4  ( void ) { return mkHReg( 4, HRcFlt64, False); }
135 HReg hregPPC_FPR5  ( void ) { return mkHReg( 5, HRcFlt64, False); }
136 HReg hregPPC_FPR6  ( void ) { return mkHReg( 6, HRcFlt64, False); }
137 HReg hregPPC_FPR7  ( void ) { return mkHReg( 7, HRcFlt64, False); }
138 HReg hregPPC_FPR8  ( void ) { return mkHReg( 8, HRcFlt64, False); }
139 HReg hregPPC_FPR9  ( void ) { return mkHReg( 9, HRcFlt64, False); }
140 HReg hregPPC_FPR10 ( void ) { return mkHReg(10, HRcFlt64, False); }
141 HReg hregPPC_FPR11 ( void ) { return mkHReg(11, HRcFlt64, False); }
142 HReg hregPPC_FPR12 ( void ) { return mkHReg(12, HRcFlt64, False); }
143 HReg hregPPC_FPR13 ( void ) { return mkHReg(13, HRcFlt64, False); }
144 HReg hregPPC_FPR14 ( void ) { return mkHReg(14, HRcFlt64, False); }
145 HReg hregPPC_FPR15 ( void ) { return mkHReg(15, HRcFlt64, False); }
146 HReg hregPPC_FPR16 ( void ) { return mkHReg(16, HRcFlt64, False); }
147 HReg hregPPC_FPR17 ( void ) { return mkHReg(17, HRcFlt64, False); }
148 HReg hregPPC_FPR18 ( void ) { return mkHReg(18, HRcFlt64, False); }
149 HReg hregPPC_FPR19 ( void ) { return mkHReg(19, HRcFlt64, False); }
150 HReg hregPPC_FPR20 ( void ) { return mkHReg(20, HRcFlt64, False); }
151 HReg hregPPC_FPR21 ( void ) { return mkHReg(21, HRcFlt64, False); }
152 HReg hregPPC_FPR22 ( void ) { return mkHReg(22, HRcFlt64, False); }
153 HReg hregPPC_FPR23 ( void ) { return mkHReg(23, HRcFlt64, False); }
154 HReg hregPPC_FPR24 ( void ) { return mkHReg(24, HRcFlt64, False); }
155 HReg hregPPC_FPR25 ( void ) { return mkHReg(25, HRcFlt64, False); }
156 HReg hregPPC_FPR26 ( void ) { return mkHReg(26, HRcFlt64, False); }
157 HReg hregPPC_FPR27 ( void ) { return mkHReg(27, HRcFlt64, False); }
158 HReg hregPPC_FPR28 ( void ) { return mkHReg(28, HRcFlt64, False); }
159 HReg hregPPC_FPR29 ( void ) { return mkHReg(29, HRcFlt64, False); }
160 HReg hregPPC_FPR30 ( void ) { return mkHReg(30, HRcFlt64, False); }
161 HReg hregPPC_FPR31 ( void ) { return mkHReg(31, HRcFlt64, False); }
162
163 HReg hregPPC_VR0  ( void ) { return mkHReg( 0, HRcVec128, False); }
164 HReg hregPPC_VR1  ( void ) { return mkHReg( 1, HRcVec128, False); }
165 HReg hregPPC_VR2  ( void ) { return mkHReg( 2, HRcVec128, False); }
166 HReg hregPPC_VR3  ( void ) { return mkHReg( 3, HRcVec128, False); }
167 HReg hregPPC_VR4  ( void ) { return mkHReg( 4, HRcVec128, False); }
168 HReg hregPPC_VR5  ( void ) { return mkHReg( 5, HRcVec128, False); }
169 HReg hregPPC_VR6  ( void ) { return mkHReg( 6, HRcVec128, False); }
170 HReg hregPPC_VR7  ( void ) { return mkHReg( 7, HRcVec128, False); }
171 HReg hregPPC_VR8  ( void ) { return mkHReg( 8, HRcVec128, False); }
172 HReg hregPPC_VR9  ( void ) { return mkHReg( 9, HRcVec128, False); }
173 HReg hregPPC_VR10 ( void ) { return mkHReg(10, HRcVec128, False); }
174 HReg hregPPC_VR11 ( void ) { return mkHReg(11, HRcVec128, False); }
175 HReg hregPPC_VR12 ( void ) { return mkHReg(12, HRcVec128, False); }
176 HReg hregPPC_VR13 ( void ) { return mkHReg(13, HRcVec128, False); }
177 HReg hregPPC_VR14 ( void ) { return mkHReg(14, HRcVec128, False); }
178 HReg hregPPC_VR15 ( void ) { return mkHReg(15, HRcVec128, False); }
179 HReg hregPPC_VR16 ( void ) { return mkHReg(16, HRcVec128, False); }
180 HReg hregPPC_VR17 ( void ) { return mkHReg(17, HRcVec128, False); }
181 HReg hregPPC_VR18 ( void ) { return mkHReg(18, HRcVec128, False); }
182 HReg hregPPC_VR19 ( void ) { return mkHReg(19, HRcVec128, False); }
183 HReg hregPPC_VR20 ( void ) { return mkHReg(20, HRcVec128, False); }
184 HReg hregPPC_VR21 ( void ) { return mkHReg(21, HRcVec128, False); }
185 HReg hregPPC_VR22 ( void ) { return mkHReg(22, HRcVec128, False); }
186 HReg hregPPC_VR23 ( void ) { return mkHReg(23, HRcVec128, False); }
187 HReg hregPPC_VR24 ( void ) { return mkHReg(24, HRcVec128, False); }
188 HReg hregPPC_VR25 ( void ) { return mkHReg(25, HRcVec128, False); }
189 HReg hregPPC_VR26 ( void ) { return mkHReg(26, HRcVec128, False); }
190 HReg hregPPC_VR27 ( void ) { return mkHReg(27, HRcVec128, False); }
191 HReg hregPPC_VR28 ( void ) { return mkHReg(28, HRcVec128, False); }
192 HReg hregPPC_VR29 ( void ) { return mkHReg(29, HRcVec128, False); }
193 HReg hregPPC_VR30 ( void ) { return mkHReg(30, HRcVec128, False); }
194 HReg hregPPC_VR31 ( void ) { return mkHReg(31, HRcVec128, False); }
195
196 void getAllocableRegs_PPC ( Int* nregs, HReg** arr, Bool mode64 )
197 {
198    UInt i=0;
199    if (mode64)
200       *nregs = (32-9) + (32-24) + (32-24);
201    else
202       *nregs = (32-7) + (32-24) + (32-24);
203    *arr = LibVEX_Alloc(*nregs * sizeof(HReg));
204    // GPR0 = scratch reg where poss. - some ops interpret as value zero
205    // GPR1 = stack pointer
206    // GPR2 = TOC pointer
207    (*arr)[i++] = hregPPC_GPR3(mode64);
208    (*arr)[i++] = hregPPC_GPR4(mode64);
209    (*arr)[i++] = hregPPC_GPR5(mode64);
210    (*arr)[i++] = hregPPC_GPR6(mode64);
211    (*arr)[i++] = hregPPC_GPR7(mode64);
212    (*arr)[i++] = hregPPC_GPR8(mode64);
213    (*arr)[i++] = hregPPC_GPR9(mode64);
214    (*arr)[i++] = hregPPC_GPR10(mode64);
215    if (!mode64) {
216       /* in mode64: 
217          r11 used for calls by ptr / env ptr for some langs
218          r12 used for exception handling and global linkage code */
219       (*arr)[i++] = hregPPC_GPR11(mode64);
220       (*arr)[i++] = hregPPC_GPR12(mode64);
221    }
222    // GPR13 = thread specific pointer
223    // GPR14 and above are callee save.  Yay.
224    (*arr)[i++] = hregPPC_GPR14(mode64);
225    (*arr)[i++] = hregPPC_GPR15(mode64);
226    (*arr)[i++] = hregPPC_GPR16(mode64);
227    (*arr)[i++] = hregPPC_GPR17(mode64);
228    (*arr)[i++] = hregPPC_GPR18(mode64);
229    (*arr)[i++] = hregPPC_GPR19(mode64);
230    (*arr)[i++] = hregPPC_GPR20(mode64);
231    (*arr)[i++] = hregPPC_GPR21(mode64);
232    (*arr)[i++] = hregPPC_GPR22(mode64);
233    (*arr)[i++] = hregPPC_GPR23(mode64);
234    (*arr)[i++] = hregPPC_GPR24(mode64);
235    (*arr)[i++] = hregPPC_GPR25(mode64);
236    (*arr)[i++] = hregPPC_GPR26(mode64);
237    (*arr)[i++] = hregPPC_GPR27(mode64);
238    (*arr)[i++] = hregPPC_GPR28(mode64);
239    // GPR29 is reserved for the dispatcher
240    // GPR30 is reserved as AltiVec spill reg temporary
241    // GPR31 is reserved for the GuestStatePtr
242
243    /* Don't waste the reg-allocs's time trawling through zillions of
244       FP registers - they mostly will never be used.  We'll tolerate
245       the occasional extra spill instead. */
246    /* For both ppc32-linux and ppc64-linux, f14-f31 are callee save.
247       So use them. */
248    (*arr)[i++] = hregPPC_FPR14();
249    (*arr)[i++] = hregPPC_FPR15();
250    (*arr)[i++] = hregPPC_FPR16();
251    (*arr)[i++] = hregPPC_FPR17();
252    (*arr)[i++] = hregPPC_FPR18();
253    (*arr)[i++] = hregPPC_FPR19();
254    (*arr)[i++] = hregPPC_FPR20();
255    (*arr)[i++] = hregPPC_FPR21();
256
257    /* Same deal re Altivec */
258    /* For both ppc32-linux and ppc64-linux, v20-v31 are callee save.
259       So use them. */
260    /* NB, vr29 is used as a scratch temporary -- do not allocate */
261    (*arr)[i++] = hregPPC_VR20();
262    (*arr)[i++] = hregPPC_VR21();
263    (*arr)[i++] = hregPPC_VR22();
264    (*arr)[i++] = hregPPC_VR23();
265    (*arr)[i++] = hregPPC_VR24();
266    (*arr)[i++] = hregPPC_VR25();
267    (*arr)[i++] = hregPPC_VR26();
268    (*arr)[i++] = hregPPC_VR27();
269
270    vassert(i == *nregs);
271 }
272
273
274 /* --------- Condition codes, Intel encoding. --------- */
275
276 HChar* showPPCCondCode ( PPCCondCode cond )
277 {
278    if (cond.test == Pct_ALWAYS) return "always";
279
280    switch (cond.flag) {
281    case Pcf_7SO:
282       return (cond.test == Pct_TRUE) ? "cr7.so=1" : "cr7.so=0";
283    case Pcf_7EQ:
284       return (cond.test == Pct_TRUE) ? "cr7.eq=1" : "cr7.eq=0";
285    case Pcf_7GT:
286       return (cond.test == Pct_TRUE) ? "cr7.gt=1" : "cr7.gt=0";
287    case Pcf_7LT:
288       return (cond.test == Pct_TRUE) ? "cr7.lt=1" : "cr7.lt=0";
289    case Pcf_NONE:
290       return "no-flag";
291    default: vpanic("ppPPCCondCode");
292    }
293 }
294
295 /* construct condition code */
296 PPCCondCode mk_PPCCondCode ( PPCCondTest test, PPCCondFlag flag )
297 {
298    PPCCondCode cc;
299    cc.flag = flag;
300    cc.test = test;
301    if (test == Pct_ALWAYS) { 
302       vassert(flag == Pcf_NONE);
303    } else {
304       vassert(flag != Pcf_NONE);
305    }
306    return cc;
307 }
308
309 /* false->true, true->false */
310 PPCCondTest invertCondTest ( PPCCondTest ct )
311 {
312    vassert(ct != Pct_ALWAYS);
313    return (ct == Pct_TRUE) ? Pct_FALSE : Pct_TRUE;
314 }
315
316
317 /* --------- PPCAMode: memory address expressions. --------- */
318
319 PPCAMode* PPCAMode_IR ( Int idx, HReg base ) {
320    PPCAMode* am = LibVEX_Alloc(sizeof(PPCAMode));
321    vassert(idx >= -0x8000 && idx < 0x8000);
322    am->tag = Pam_IR;
323    am->Pam.IR.base = base;
324    am->Pam.IR.index = idx;
325    return am;
326 }
327 PPCAMode* PPCAMode_RR ( HReg idx, HReg base ) {
328    PPCAMode* am = LibVEX_Alloc(sizeof(PPCAMode));
329    am->tag = Pam_RR;
330    am->Pam.RR.base = base;
331    am->Pam.RR.index = idx;
332    return am;
333 }
334
335 PPCAMode* dopyPPCAMode ( PPCAMode* am ) {
336    switch (am->tag) {
337    case Pam_IR: 
338       return PPCAMode_IR( am->Pam.IR.index, am->Pam.IR.base );
339    case Pam_RR: 
340       return PPCAMode_RR( am->Pam.RR.index, am->Pam.RR.base );
341    default:
342       vpanic("dopyPPCAMode");
343    }
344 }
345
346 void ppPPCAMode ( PPCAMode* am ) {
347    switch (am->tag) {
348    case Pam_IR: 
349       if (am->Pam.IR.index == 0)
350          vex_printf("0(");
351       else
352          vex_printf("%d(", (Int)am->Pam.IR.index);
353       ppHRegPPC(am->Pam.IR.base);
354       vex_printf(")");
355       return;
356    case Pam_RR:
357       ppHRegPPC(am->Pam.RR.base);
358       vex_printf(",");
359       ppHRegPPC(am->Pam.RR.index);
360       return;
361    default:
362       vpanic("ppPPCAMode");
363    }
364 }
365
366 static void addRegUsage_PPCAMode ( HRegUsage* u, PPCAMode* am ) {
367    switch (am->tag) {
368    case Pam_IR: 
369       addHRegUse(u, HRmRead, am->Pam.IR.base);
370       return;
371    case Pam_RR:
372       addHRegUse(u, HRmRead, am->Pam.RR.base);
373       addHRegUse(u, HRmRead, am->Pam.RR.index);
374       return;
375    default:
376       vpanic("addRegUsage_PPCAMode");
377    }
378 }
379
380 static void mapRegs_PPCAMode ( HRegRemap* m, PPCAMode* am ) {
381    switch (am->tag) {
382    case Pam_IR: 
383       am->Pam.IR.base = lookupHRegRemap(m, am->Pam.IR.base);
384       return;
385    case Pam_RR:
386       am->Pam.RR.base = lookupHRegRemap(m, am->Pam.RR.base);
387       am->Pam.RR.index = lookupHRegRemap(m, am->Pam.RR.index);
388       return;
389    default:
390       vpanic("mapRegs_PPCAMode");
391    }
392 }
393
394 /* --------- Operand, which can be a reg or a u16/s16. --------- */
395
396 PPCRH* PPCRH_Imm ( Bool syned, UShort imm16 ) {
397    PPCRH* op         = LibVEX_Alloc(sizeof(PPCRH));
398    op->tag           = Prh_Imm;
399    op->Prh.Imm.syned = syned;
400    op->Prh.Imm.imm16 = imm16;
401    /* If this is a signed value, ensure it's not -32768, so that we
402       are guaranteed always to be able to negate if needed. */
403    if (syned)
404       vassert(imm16 != 0x8000);
405    vassert(syned == True || syned == False);
406    return op;
407 }
408 PPCRH* PPCRH_Reg ( HReg reg ) {
409    PPCRH* op       = LibVEX_Alloc(sizeof(PPCRH));
410    op->tag         = Prh_Reg;
411    op->Prh.Reg.reg = reg;
412    return op;
413 }
414
415 void ppPPCRH ( PPCRH* op ) {
416    switch (op->tag) {
417    case Prh_Imm: 
418       if (op->Prh.Imm.syned)
419          vex_printf("%d", (Int)(Short)op->Prh.Imm.imm16);
420       else
421          vex_printf("%u", (UInt)(UShort)op->Prh.Imm.imm16);
422       return;
423    case Prh_Reg: 
424       ppHRegPPC(op->Prh.Reg.reg);
425       return;
426    default: 
427       vpanic("ppPPCRH");
428    }
429 }
430
431 /* An PPCRH can only be used in a "read" context (what would it mean
432    to write or modify a literal?) and so we enumerate its registers
433    accordingly. */
434 static void addRegUsage_PPCRH ( HRegUsage* u, PPCRH* op ) {
435    switch (op->tag) {
436    case Prh_Imm: 
437       return;
438    case Prh_Reg: 
439       addHRegUse(u, HRmRead, op->Prh.Reg.reg);
440       return;
441    default: 
442       vpanic("addRegUsage_PPCRH");
443    }
444 }
445
446 static void mapRegs_PPCRH ( HRegRemap* m, PPCRH* op ) {
447    switch (op->tag) {
448    case Prh_Imm: 
449       return;
450    case Prh_Reg: 
451       op->Prh.Reg.reg = lookupHRegRemap(m, op->Prh.Reg.reg);
452       return;
453    default: 
454       vpanic("mapRegs_PPCRH");
455    }
456 }
457
458
459 /* --------- Operand, which can be a reg or a u32/64. --------- */
460
461 PPCRI* PPCRI_Imm ( ULong imm64 ) {
462    PPCRI* op   = LibVEX_Alloc(sizeof(PPCRI));
463    op->tag     = Pri_Imm;
464    op->Pri.Imm = imm64;
465    return op;
466 }
467 PPCRI* PPCRI_Reg ( HReg reg ) {
468    PPCRI* op   = LibVEX_Alloc(sizeof(PPCRI));
469    op->tag     = Pri_Reg;
470    op->Pri.Reg = reg;
471    return op;
472 }
473
474 void ppPPCRI ( PPCRI* dst ) {
475    switch (dst->tag) {
476       case Pri_Imm: 
477          vex_printf("0x%llx", dst->Pri.Imm);
478          break;
479       case Pri_Reg: 
480          ppHRegPPC(dst->Pri.Reg);
481          break;
482       default: 
483          vpanic("ppPPCRI");
484    }
485 }
486
487 /* An PPCRI can only be used in a "read" context (what would it
488    mean to write or modify a literal?) and so we enumerate its
489    registers accordingly. */
490 static void addRegUsage_PPCRI ( HRegUsage* u, PPCRI* dst ) {
491    switch (dst->tag) {
492       case Pri_Imm: 
493          return;
494       case Pri_Reg: 
495          addHRegUse(u, HRmRead, dst->Pri.Reg);
496          return;
497       default: 
498          vpanic("addRegUsage_PPCRI");
499    }
500 }
501
502 static void mapRegs_PPCRI ( HRegRemap* m, PPCRI* dst ) {
503    switch (dst->tag) {
504       case Pri_Imm: 
505          return;
506       case Pri_Reg: 
507          dst->Pri.Reg = lookupHRegRemap(m, dst->Pri.Reg);
508          return;
509       default: 
510          vpanic("mapRegs_PPCRI");
511    }
512 }
513
514
515 /* --------- Operand, which can be a vector reg or a simm5. --------- */
516
517 PPCVI5s* PPCVI5s_Imm ( Char simm5 ) {
518    PPCVI5s* op   = LibVEX_Alloc(sizeof(PPCVI5s));
519    op->tag       = Pvi_Imm;
520    op->Pvi.Imm5s = simm5;
521    vassert(simm5 >= -16 && simm5 <= 15);
522    return op;
523 }
524 PPCVI5s* PPCVI5s_Reg ( HReg reg ) {
525    PPCVI5s* op = LibVEX_Alloc(sizeof(PPCVI5s));
526    op->tag     = Pvi_Reg;
527    op->Pvi.Reg = reg;
528    vassert(hregClass(reg) == HRcVec128);
529    return op;
530 }
531
532 void ppPPCVI5s ( PPCVI5s* src ) {
533    switch (src->tag) {
534       case Pvi_Imm: 
535          vex_printf("%d", (Int)src->Pvi.Imm5s);
536          break;
537       case Pvi_Reg: 
538          ppHRegPPC(src->Pvi.Reg);
539          break;
540       default: 
541          vpanic("ppPPCVI5s");
542    }
543 }
544
545 /* An PPCVI5s can only be used in a "read" context (what would it
546    mean to write or modify a literal?) and so we enumerate its
547    registers accordingly. */
548 static void addRegUsage_PPCVI5s ( HRegUsage* u, PPCVI5s* dst ) {
549    switch (dst->tag) {
550       case Pvi_Imm: 
551          return;
552       case Pvi_Reg: 
553          addHRegUse(u, HRmRead, dst->Pvi.Reg);
554          return;
555       default: 
556          vpanic("addRegUsage_PPCVI5s");
557    }
558 }
559
560 static void mapRegs_PPCVI5s ( HRegRemap* m, PPCVI5s* dst ) {
561    switch (dst->tag) {
562       case Pvi_Imm: 
563          return;
564       case Pvi_Reg: 
565          dst->Pvi.Reg = lookupHRegRemap(m, dst->Pvi.Reg);
566          return;
567       default: 
568          vpanic("mapRegs_PPCVI5s");
569    }
570 }
571
572
573 /* --------- Instructions. --------- */
574
575 HChar* showPPCUnaryOp ( PPCUnaryOp op ) {
576    switch (op) {
577    case Pun_NOT:   return "not";
578    case Pun_NEG:   return "neg";
579    case Pun_CLZ32: return "cntlzw";
580    case Pun_CLZ64: return "cntlzd";
581    case Pun_EXTSW: return "extsw";
582    default: vpanic("showPPCUnaryOp");
583    }
584 }
585
586 HChar* showPPCAluOp ( PPCAluOp op, Bool immR ) {
587    switch (op) {
588       case Palu_ADD: return immR ? "addi"  : "add";
589       case Palu_SUB: return immR ? "subi"  : "sub";
590       case Palu_AND: return immR ? "andi." : "and";
591       case Palu_OR:  return immR ? "ori"   : "or";
592       case Palu_XOR: return immR ? "xori"  : "xor";
593       default: vpanic("showPPCAluOp");
594    }
595 }
596
597 HChar* showPPCShftOp ( PPCShftOp op, Bool immR, Bool sz32 ) {
598    switch (op) {
599       case Pshft_SHL: return sz32 ? (immR ? "slwi"  : "slw") : 
600                                     (immR ? "sldi"  : "sld");
601       case Pshft_SHR: return sz32 ? (immR ? "srwi"  : "srw") :
602                                     (immR ? "srdi"  : "srd");
603       case Pshft_SAR: return sz32 ? (immR ? "srawi" : "sraw") :
604                                     (immR ? "sradi" : "srad");
605       default: vpanic("showPPCShftOp");
606    }
607 }
608
609 HChar* showPPCFpOp ( PPCFpOp op ) {
610    switch (op) {
611       case Pfp_ADDD:   return "fadd";
612       case Pfp_SUBD:   return "fsub";
613       case Pfp_MULD:   return "fmul";
614       case Pfp_DIVD:   return "fdiv";
615       case Pfp_MADDD:  return "fmadd";
616       case Pfp_MSUBD:  return "fmsub";
617       case Pfp_MADDS:  return "fmadds";
618       case Pfp_MSUBS:  return "fmsubs";
619       case Pfp_ADDS:   return "fadds";
620       case Pfp_SUBS:   return "fsubs";
621       case Pfp_MULS:   return "fmuls";
622       case Pfp_DIVS:   return "fdivs";
623       case Pfp_SQRT:   return "fsqrt";
624       case Pfp_ABS:    return "fabs";
625       case Pfp_NEG:    return "fneg";
626       case Pfp_MOV:    return "fmr";
627       case Pfp_RES:    return "fres";
628       case Pfp_RSQRTE: return "frsqrte";
629       case Pfp_FRIM:   return "frim";
630       case Pfp_FRIN:   return "frin";
631       case Pfp_FRIP:   return "frip";
632       case Pfp_FRIZ:   return "friz";
633       default: vpanic("showPPCFpOp");
634    }
635 }
636
637 HChar* showPPCAvOp ( PPCAvOp op ) {
638    switch (op) {
639
640    /* Unary */
641    case Pav_MOV:       return "vmr";      /* Mov */
642      
643    case Pav_AND:       return "vand";     /* Bitwise */
644    case Pav_OR:        return "vor";
645    case Pav_XOR:       return "vxor";
646    case Pav_NOT:       return "vnot";
647
648    case Pav_UNPCKH8S:  return "vupkhsb";  /* Unpack */
649    case Pav_UNPCKH16S: return "vupkhsh";
650    case Pav_UNPCKL8S:  return "vupklsb";
651    case Pav_UNPCKL16S: return "vupklsh";
652    case Pav_UNPCKHPIX: return "vupkhpx";
653    case Pav_UNPCKLPIX: return "vupklpx";
654
655    /* Integer binary */
656    case Pav_ADDU:      return "vaddu_m";  // b,h,w
657    case Pav_QADDU:     return "vaddu_s";  // b,h,w
658    case Pav_QADDS:     return "vadds_s";  // b,h,w
659      
660    case Pav_SUBU:      return "vsubu_m";  // b,h,w
661    case Pav_QSUBU:     return "vsubu_s";  // b,h,w
662    case Pav_QSUBS:     return "vsubs_s";  // b,h,w
663      
664    case Pav_OMULU:     return "vmulou";   // b,h
665    case Pav_OMULS:     return "vmulos";   // b,h
666    case Pav_EMULU:     return "vmuleu";   // b,h
667    case Pav_EMULS:     return "vmules";   // b,h
668   
669    case Pav_AVGU:      return "vavgu";    // b,h,w
670    case Pav_AVGS:      return "vavgs";    // b,h,w
671      
672    case Pav_MAXU:      return "vmaxu";    // b,h,w
673    case Pav_MAXS:      return "vmaxs";    // b,h,w
674      
675    case Pav_MINU:      return "vminu";    // b,h,w
676    case Pav_MINS:      return "vmins";    // b,h,w
677      
678    /* Compare (always affects CR field 6) */
679    case Pav_CMPEQU:    return "vcmpequ";  // b,h,w
680    case Pav_CMPGTU:    return "vcmpgtu";  // b,h,w
681    case Pav_CMPGTS:    return "vcmpgts";  // b,h,w
682
683    /* Shift */
684    case Pav_SHL:       return "vsl";      // ' ',b,h,w
685    case Pav_SHR:       return "vsr";      // ' ',b,h,w
686    case Pav_SAR:       return "vsra";     // b,h,w
687    case Pav_ROTL:      return "vrl";      // b,h,w
688
689    /* Pack */
690    case Pav_PACKUU:    return "vpku_um";  // h,w
691    case Pav_QPACKUU:   return "vpku_us";  // h,w
692    case Pav_QPACKSU:   return "vpks_us";  // h,w
693    case Pav_QPACKSS:   return "vpks_ss";  // h,w
694    case Pav_PACKPXL:   return "vpkpx";
695
696    /* Merge */
697    case Pav_MRGHI:     return "vmrgh";    // b,h,w
698    case Pav_MRGLO:     return "vmrgl";    // b,h,w
699
700    default: vpanic("showPPCAvOp");
701    }
702 }
703
704 HChar* showPPCAvFpOp ( PPCAvFpOp op ) {
705    switch (op) {
706    /* Floating Point Binary */
707    case Pavfp_ADDF:      return "vaddfp";
708    case Pavfp_SUBF:      return "vsubfp";
709    case Pavfp_MULF:      return "vmaddfp";
710    case Pavfp_MAXF:      return "vmaxfp";
711    case Pavfp_MINF:      return "vminfp";
712    case Pavfp_CMPEQF:    return "vcmpeqfp";
713    case Pavfp_CMPGTF:    return "vcmpgtfp";
714    case Pavfp_CMPGEF:    return "vcmpgefp";
715      
716    /* Floating Point Unary */
717    case Pavfp_RCPF:      return "vrefp";
718    case Pavfp_RSQRTF:    return "vrsqrtefp";
719    case Pavfp_CVTU2F:    return "vcfux";
720    case Pavfp_CVTS2F:    return "vcfsx";
721    case Pavfp_QCVTF2U:   return "vctuxs";
722    case Pavfp_QCVTF2S:   return "vctsxs";
723    case Pavfp_ROUNDM:    return "vrfim";
724    case Pavfp_ROUNDP:    return "vrfip";
725    case Pavfp_ROUNDN:    return "vrfin";
726    case Pavfp_ROUNDZ:    return "vrfiz";
727
728    default: vpanic("showPPCAvFpOp");
729    }
730 }
731
732 PPCInstr* PPCInstr_LI ( HReg dst, ULong imm64, Bool mode64 )
733 {
734    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
735    i->tag          = Pin_LI;
736    i->Pin.LI.dst   = dst;
737    i->Pin.LI.imm64 = imm64;
738    if (!mode64)
739       vassert( (Long)imm64 == (Long)(Int)(UInt)imm64 );
740    return i;
741 }
742 PPCInstr* PPCInstr_Alu ( PPCAluOp op, HReg dst, 
743                          HReg srcL, PPCRH* srcR ) {
744    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
745    i->tag          = Pin_Alu;
746    i->Pin.Alu.op   = op;
747    i->Pin.Alu.dst  = dst;
748    i->Pin.Alu.srcL = srcL;
749    i->Pin.Alu.srcR = srcR;
750    return i;
751 }
752 PPCInstr* PPCInstr_Shft ( PPCShftOp op, Bool sz32, 
753                           HReg dst, HReg srcL, PPCRH* srcR ) {
754    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
755    i->tag           = Pin_Shft;
756    i->Pin.Shft.op   = op;
757    i->Pin.Shft.sz32 = sz32;
758    i->Pin.Shft.dst  = dst;
759    i->Pin.Shft.srcL = srcL;
760    i->Pin.Shft.srcR = srcR;
761    return i;
762 }
763 PPCInstr* PPCInstr_AddSubC ( Bool isAdd, Bool setC,
764                              HReg dst, HReg srcL, HReg srcR ) {
765    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
766    i->tag               = Pin_AddSubC;
767    i->Pin.AddSubC.isAdd = isAdd;
768    i->Pin.AddSubC.setC  = setC;
769    i->Pin.AddSubC.dst   = dst;
770    i->Pin.AddSubC.srcL  = srcL;
771    i->Pin.AddSubC.srcR  = srcR;
772    return i;
773 }
774 PPCInstr* PPCInstr_Cmp ( Bool syned, Bool sz32, 
775                          UInt crfD, HReg srcL, PPCRH* srcR ) {
776    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
777    i->tag           = Pin_Cmp;
778    i->Pin.Cmp.syned = syned;
779    i->Pin.Cmp.sz32  = sz32;
780    i->Pin.Cmp.crfD  = crfD;
781    i->Pin.Cmp.srcL  = srcL;
782    i->Pin.Cmp.srcR  = srcR;
783    return i;
784 }
785 PPCInstr* PPCInstr_Unary ( PPCUnaryOp op, HReg dst, HReg src ) {
786    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
787    i->tag           = Pin_Unary;
788    i->Pin.Unary.op  = op;
789    i->Pin.Unary.dst = dst;
790    i->Pin.Unary.src = src;
791    return i;
792 }
793 PPCInstr* PPCInstr_MulL ( Bool syned, Bool hi, Bool sz32, 
794                           HReg dst, HReg srcL, HReg srcR ) {
795    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
796    i->tag            = Pin_MulL;
797    i->Pin.MulL.syned = syned;
798    i->Pin.MulL.hi    = hi;
799    i->Pin.MulL.sz32  = sz32;
800    i->Pin.MulL.dst   = dst;
801    i->Pin.MulL.srcL  = srcL;
802    i->Pin.MulL.srcR  = srcR;
803    /* if doing the low word, the signedness is irrelevant, but tie it
804       down anyway. */
805    if (!hi) vassert(!syned);
806    return i;
807 }
808 PPCInstr* PPCInstr_Div ( Bool syned, Bool sz32,
809                          HReg dst, HReg srcL, HReg srcR ) {
810    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
811    i->tag           = Pin_Div;
812    i->Pin.Div.syned = syned;
813    i->Pin.Div.sz32  = sz32;
814    i->Pin.Div.dst   = dst;
815    i->Pin.Div.srcL  = srcL;
816    i->Pin.Div.srcR  = srcR;
817    return i;
818 }
819 PPCInstr* PPCInstr_Call ( PPCCondCode cond, 
820                           Addr64 target, UInt argiregs ) {
821    UInt mask;
822    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
823    i->tag               = Pin_Call;
824    i->Pin.Call.cond     = cond;
825    i->Pin.Call.target   = target;
826    i->Pin.Call.argiregs = argiregs;
827    /* Only r3 .. r10 inclusive may be used as arg regs. Hence: */
828    mask = (1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10);
829    vassert(0 == (argiregs & ~mask));
830    return i;
831 }
832 PPCInstr* PPCInstr_Goto ( IRJumpKind jk, 
833                           PPCCondCode cond, PPCRI* dst ) {
834    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
835    i->tag           = Pin_Goto;
836    i->Pin.Goto.cond = cond;
837    i->Pin.Goto.dst  = dst;
838    i->Pin.Goto.jk   = jk;
839    return i;
840 }
841 PPCInstr* PPCInstr_CMov  ( PPCCondCode cond, 
842                            HReg dst, PPCRI* src ) {
843    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
844    i->tag           = Pin_CMov;
845    i->Pin.CMov.cond = cond;
846    i->Pin.CMov.src  = src;
847    i->Pin.CMov.dst  = dst;
848    vassert(cond.test != Pct_ALWAYS);
849    return i;
850 }
851 PPCInstr* PPCInstr_Load ( UChar sz,
852                           HReg dst, PPCAMode* src, Bool mode64 ) {
853    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
854    i->tag            = Pin_Load;
855    i->Pin.Load.sz    = sz;
856    i->Pin.Load.src   = src;
857    i->Pin.Load.dst   = dst;
858    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
859    if (sz == 8) vassert(mode64);
860    return i;
861 }
862 PPCInstr* PPCInstr_LoadL ( UChar sz,
863                            HReg dst, HReg src, Bool mode64 )
864 {
865    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
866    i->tag            = Pin_LoadL;
867    i->Pin.LoadL.sz   = sz;
868    i->Pin.LoadL.src  = src;
869    i->Pin.LoadL.dst  = dst;
870    vassert(sz == 4 || sz == 8);
871    if (sz == 8) vassert(mode64);
872    return i;
873 }
874 PPCInstr* PPCInstr_Store ( UChar sz, PPCAMode* dst, HReg src,
875                            Bool mode64 ) {
876    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
877    i->tag           = Pin_Store;
878    i->Pin.Store.sz  = sz;
879    i->Pin.Store.src = src;
880    i->Pin.Store.dst = dst;
881    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
882    if (sz == 8) vassert(mode64);
883    return i;
884 }
885 PPCInstr* PPCInstr_StoreC ( UChar sz, HReg dst, HReg src, Bool mode64 ) {
886    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
887    i->tag            = Pin_StoreC;
888    i->Pin.StoreC.sz  = sz;
889    i->Pin.StoreC.src = src;
890    i->Pin.StoreC.dst = dst;
891    vassert(sz == 4 || sz == 8);
892    if (sz == 8) vassert(mode64);
893    return i;
894 }
895 PPCInstr* PPCInstr_Set ( PPCCondCode cond, HReg dst ) {
896    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
897    i->tag          = Pin_Set;
898    i->Pin.Set.cond = cond;
899    i->Pin.Set.dst  = dst;
900    return i;
901 }
902 PPCInstr* PPCInstr_MfCR ( HReg dst )
903 {
904    PPCInstr* i     = LibVEX_Alloc(sizeof(PPCInstr));
905    i->tag          = Pin_MfCR;
906    i->Pin.MfCR.dst = dst;
907    return i;
908 }
909 PPCInstr* PPCInstr_MFence ( void )
910 {
911    PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr));
912    i->tag      = Pin_MFence;
913    return i;
914 }
915
916 PPCInstr* PPCInstr_FpUnary ( PPCFpOp op, HReg dst, HReg src ) {
917    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
918    i->tag             = Pin_FpUnary;
919    i->Pin.FpUnary.op  = op;
920    i->Pin.FpUnary.dst = dst;
921    i->Pin.FpUnary.src = src;
922    return i;
923 }
924 PPCInstr* PPCInstr_FpBinary ( PPCFpOp op, HReg dst,
925                               HReg srcL, HReg srcR ) {
926    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
927    i->tag               = Pin_FpBinary;
928    i->Pin.FpBinary.op   = op;
929    i->Pin.FpBinary.dst  = dst;
930    i->Pin.FpBinary.srcL = srcL;
931    i->Pin.FpBinary.srcR = srcR;
932    return i;
933 }
934 PPCInstr* PPCInstr_FpMulAcc ( PPCFpOp op, HReg dst, HReg srcML, 
935                                           HReg srcMR, HReg srcAcc )
936 {
937    PPCInstr* i            = LibVEX_Alloc(sizeof(PPCInstr));
938    i->tag                 = Pin_FpMulAcc;
939    i->Pin.FpMulAcc.op     = op;
940    i->Pin.FpMulAcc.dst    = dst;
941    i->Pin.FpMulAcc.srcML  = srcML;
942    i->Pin.FpMulAcc.srcMR  = srcMR;
943    i->Pin.FpMulAcc.srcAcc = srcAcc;
944    return i;
945 }
946 PPCInstr* PPCInstr_FpLdSt ( Bool isLoad, UChar sz,
947                             HReg reg, PPCAMode* addr ) {
948    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
949    i->tag               = Pin_FpLdSt;
950    i->Pin.FpLdSt.isLoad = isLoad;
951    i->Pin.FpLdSt.sz     = sz;
952    i->Pin.FpLdSt.reg    = reg;
953    i->Pin.FpLdSt.addr   = addr;
954    vassert(sz == 4 || sz == 8);
955    return i;
956 }
957 PPCInstr* PPCInstr_FpSTFIW ( HReg addr, HReg data )
958 {
959    PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
960    i->tag              = Pin_FpSTFIW;
961    i->Pin.FpSTFIW.addr = addr;
962    i->Pin.FpSTFIW.data = data;
963    return i;
964 }
965 PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src ) {
966    PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
967    i->tag           = Pin_FpRSP;
968    i->Pin.FpRSP.dst = dst;
969    i->Pin.FpRSP.src = src;
970    return i;
971 }
972
973 /*
974 Valid combo | fromI | int32 | syned | flt64 |
975 --------------------------------------------
976             |  n       n       n       n    |
977 --------------------------------------------
978  F64->I64U  |  n       n       n       y    |
979 --------------------------------------------
980             |  n       n       y       n    |
981 --------------------------------------------
982  F64->I64S  |  n       n       y       y    |
983 --------------------------------------------
984             |  n       y       n       n    |
985 --------------------------------------------
986  F64->I32U  |  n       y       n       y    |
987 --------------------------------------------
988             |  n       y       y       n    |
989 --------------------------------------------
990  F64->I32S  |  n       y       y       y    |
991 --------------------------------------------
992  I64U->F32  |  y       n       n       n    |
993 --------------------------------------------
994  I64U->F64  |  y       n       n       y    |
995 --------------------------------------------
996             |  y       n       y       n    |
997 --------------------------------------------
998  I64S->F64  |  y       n       y       y    |
999 --------------------------------------------
1000             |  y       y       n       n    |
1001 --------------------------------------------
1002             |  y       y       n       y    |
1003 --------------------------------------------
1004             |  y       y       y       n    |
1005 --------------------------------------------
1006             |  y       y       y       y    |
1007 --------------------------------------------
1008 */
1009 PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, Bool syned,
1010                             Bool flt64, HReg dst, HReg src ) {
1011    Bool tmp = fromI | int32 | syned | flt64;
1012    vassert(tmp == True || tmp == False); // iow, no high bits set
1013    UShort conversion = 0;
1014    conversion = (fromI << 3) | (int32 << 2) | (syned << 1) | flt64;
1015    switch (conversion) {
1016       // Supported conversion operations
1017       case 1: case 3: case 5: case 7:
1018       case 8: case 9: case 11:
1019          break;
1020       default:
1021          vpanic("PPCInstr_FpCftI(ppc_host)");
1022    }
1023    PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
1024    i->tag              = Pin_FpCftI;
1025    i->Pin.FpCftI.fromI = fromI;
1026    i->Pin.FpCftI.int32 = int32;
1027    i->Pin.FpCftI.syned = syned;
1028    i->Pin.FpCftI.flt64 = flt64;
1029    i->Pin.FpCftI.dst   = dst;
1030    i->Pin.FpCftI.src   = src;
1031    return i;
1032 }
1033 PPCInstr* PPCInstr_FpCMov ( PPCCondCode cond, HReg dst, HReg src ) {
1034    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
1035    i->tag             = Pin_FpCMov;
1036    i->Pin.FpCMov.cond = cond;
1037    i->Pin.FpCMov.dst  = dst;
1038    i->Pin.FpCMov.src  = src;
1039    vassert(cond.test != Pct_ALWAYS);
1040    return i;
1041 }
1042 PPCInstr* PPCInstr_FpLdFPSCR ( HReg src ) {
1043    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
1044    i->tag               = Pin_FpLdFPSCR;
1045    i->Pin.FpLdFPSCR.src = src;
1046    return i;
1047 }
1048 PPCInstr* PPCInstr_FpCmp ( HReg dst, HReg srcL, HReg srcR ) {
1049    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
1050    i->tag            = Pin_FpCmp;
1051    i->Pin.FpCmp.dst  = dst;
1052    i->Pin.FpCmp.srcL = srcL;
1053    i->Pin.FpCmp.srcR = srcR;
1054    return i;
1055 }
1056
1057 /* Read/Write Link Register */
1058 PPCInstr* PPCInstr_RdWrLR ( Bool wrLR, HReg gpr ) {
1059    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
1060    i->tag             = Pin_RdWrLR;
1061    i->Pin.RdWrLR.wrLR = wrLR;
1062    i->Pin.RdWrLR.gpr  = gpr;
1063    return i;
1064 }
1065
1066 /* AltiVec */
1067 PPCInstr* PPCInstr_AvLdSt ( Bool isLoad, UChar sz,
1068                             HReg reg, PPCAMode* addr ) {
1069    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
1070    i->tag               = Pin_AvLdSt;
1071    i->Pin.AvLdSt.isLoad = isLoad;
1072    i->Pin.AvLdSt.sz     = sz;
1073    i->Pin.AvLdSt.reg    = reg;
1074    i->Pin.AvLdSt.addr   = addr;
1075    return i;
1076 }
1077 PPCInstr* PPCInstr_AvUnary ( PPCAvOp op, HReg dst, HReg src ) {
1078    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
1079    i->tag             = Pin_AvUnary;
1080    i->Pin.AvUnary.op  = op;
1081    i->Pin.AvUnary.dst = dst;
1082    i->Pin.AvUnary.src = src;
1083    return i;
1084 }
1085 PPCInstr* PPCInstr_AvBinary ( PPCAvOp op, HReg dst,
1086                               HReg srcL, HReg srcR ) {
1087    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
1088    i->tag               = Pin_AvBinary;
1089    i->Pin.AvBinary.op   = op;
1090    i->Pin.AvBinary.dst  = dst;
1091    i->Pin.AvBinary.srcL = srcL;
1092    i->Pin.AvBinary.srcR = srcR;
1093    return i;
1094 }
1095 PPCInstr* PPCInstr_AvBin8x16 ( PPCAvOp op, HReg dst,
1096                                HReg srcL, HReg srcR ) {
1097    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
1098    i->tag                = Pin_AvBin8x16;
1099    i->Pin.AvBin8x16.op   = op;
1100    i->Pin.AvBin8x16.dst  = dst;
1101    i->Pin.AvBin8x16.srcL = srcL;
1102    i->Pin.AvBin8x16.srcR = srcR;
1103    return i;
1104 }
1105 PPCInstr* PPCInstr_AvBin16x8 ( PPCAvOp op, HReg dst,
1106                                HReg srcL, HReg srcR ) {
1107    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
1108    i->tag                = Pin_AvBin16x8;
1109    i->Pin.AvBin16x8.op   = op;
1110    i->Pin.AvBin16x8.dst  = dst;
1111    i->Pin.AvBin16x8.srcL = srcL;
1112    i->Pin.AvBin16x8.srcR = srcR;
1113    return i;
1114 }
1115 PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst,
1116                                HReg srcL, HReg srcR ) {
1117    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
1118    i->tag                = Pin_AvBin32x4;
1119    i->Pin.AvBin32x4.op   = op;
1120    i->Pin.AvBin32x4.dst  = dst;
1121    i->Pin.AvBin32x4.srcL = srcL;
1122    i->Pin.AvBin32x4.srcR = srcR;
1123    return i;
1124 }
1125 PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst,
1126                                 HReg srcL, HReg srcR ) {
1127    PPCInstr* i            = LibVEX_Alloc(sizeof(PPCInstr));
1128    i->tag                 = Pin_AvBin32Fx4;
1129    i->Pin.AvBin32Fx4.op   = op;
1130    i->Pin.AvBin32Fx4.dst  = dst;
1131    i->Pin.AvBin32Fx4.srcL = srcL;
1132    i->Pin.AvBin32Fx4.srcR = srcR;
1133    return i;
1134 }
1135 PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op, HReg dst, HReg src ) {
1136    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
1137    i->tag               = Pin_AvUn32Fx4;
1138    i->Pin.AvUn32Fx4.op  = op;
1139    i->Pin.AvUn32Fx4.dst = dst;
1140    i->Pin.AvUn32Fx4.src = src;
1141    return i;
1142 }
1143 PPCInstr* PPCInstr_AvPerm ( HReg dst, HReg srcL, HReg srcR, HReg ctl ) {
1144    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
1145    i->tag             = Pin_AvPerm;
1146    i->Pin.AvPerm.dst  = dst;
1147    i->Pin.AvPerm.srcL = srcL;
1148    i->Pin.AvPerm.srcR = srcR;
1149    i->Pin.AvPerm.ctl  = ctl;
1150    return i;
1151 }
1152 PPCInstr* PPCInstr_AvSel ( HReg ctl, HReg dst, HReg srcL, HReg srcR ) {
1153    PPCInstr* i       = LibVEX_Alloc(sizeof(PPCInstr));
1154    i->tag            = Pin_AvSel;
1155    i->Pin.AvSel.ctl  = ctl;
1156    i->Pin.AvSel.dst  = dst;
1157    i->Pin.AvSel.srcL = srcL;
1158    i->Pin.AvSel.srcR = srcR;
1159    return i;
1160 }
1161 PPCInstr* PPCInstr_AvShlDbl ( UChar shift, HReg dst,
1162                               HReg srcL, HReg srcR ) {
1163    PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
1164    i->tag                = Pin_AvShlDbl;
1165    i->Pin.AvShlDbl.shift = shift;
1166    i->Pin.AvShlDbl.dst   = dst;
1167    i->Pin.AvShlDbl.srcL  = srcL;
1168    i->Pin.AvShlDbl.srcR  = srcR;
1169    return i;
1170 }
1171 PPCInstr* PPCInstr_AvSplat ( UChar sz, HReg dst, PPCVI5s* src ) {
1172    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
1173    i->tag             = Pin_AvSplat;
1174    i->Pin.AvSplat.sz  = sz;
1175    i->Pin.AvSplat.dst = dst;
1176    i->Pin.AvSplat.src = src;
1177    return i;
1178 }
1179 PPCInstr* PPCInstr_AvCMov ( PPCCondCode cond, HReg dst, HReg src ) {
1180    PPCInstr* i        = LibVEX_Alloc(sizeof(PPCInstr));
1181    i->tag             = Pin_AvCMov;
1182    i->Pin.AvCMov.cond = cond;
1183    i->Pin.AvCMov.dst  = dst;
1184    i->Pin.AvCMov.src  = src;
1185    vassert(cond.test != Pct_ALWAYS);
1186    return i;
1187 }
1188 PPCInstr* PPCInstr_AvLdVSCR ( HReg src ) {
1189    PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
1190    i->tag              = Pin_AvLdVSCR;
1191    i->Pin.AvLdVSCR.src = src;
1192    return i;
1193 }
1194
1195
1196 /* Pretty Print instructions */
1197 static void ppLoadImm ( HReg dst, ULong imm, Bool mode64 ) {
1198    vex_printf("li_word ");
1199    ppHRegPPC(dst);
1200    if (!mode64) {
1201       vex_printf(",0x%08x", (UInt)imm);
1202    } else {
1203       vex_printf(",0x%016llx", imm);
1204    }
1205 }
1206
1207 static void ppMovReg ( HReg dst, HReg src ) {
1208    if (hregNumber(dst) != hregNumber(src)) {
1209       vex_printf("mr ");
1210       ppHRegPPC(dst);
1211       vex_printf(",");
1212       ppHRegPPC(src);
1213    }
1214 }
1215
1216 void ppPPCInstr ( PPCInstr* i, Bool mode64 )
1217 {
1218    switch (i->tag) {
1219    case Pin_LI:
1220       ppLoadImm(i->Pin.LI.dst, i->Pin.LI.imm64, mode64);
1221       break;
1222    case Pin_Alu: {
1223       HReg   r_srcL  = i->Pin.Alu.srcL;
1224       PPCRH* rh_srcR = i->Pin.Alu.srcR;
1225       /* special-case "mr" */
1226       if (i->Pin.Alu.op == Palu_OR &&   // or Rd,Rs,Rs == mr Rd,Rs
1227           rh_srcR->tag == Prh_Reg &&
1228           rh_srcR->Prh.Reg.reg == r_srcL) {
1229          vex_printf("mr ");
1230          ppHRegPPC(i->Pin.Alu.dst);
1231          vex_printf(",");
1232          ppHRegPPC(r_srcL);
1233          return;
1234       }
1235       /* special-case "li" */
1236       if (i->Pin.Alu.op == Palu_ADD &&   // addi Rd,0,imm == li Rd,imm
1237           rh_srcR->tag == Prh_Imm &&
1238           hregNumber(r_srcL) == 0) {
1239          vex_printf("li ");
1240          ppHRegPPC(i->Pin.Alu.dst);
1241          vex_printf(",");
1242          ppPPCRH(rh_srcR);
1243          return;
1244       }
1245       /* generic */
1246       vex_printf("%s ", showPPCAluOp(i->Pin.Alu.op,
1247                                      toBool(rh_srcR->tag == Prh_Imm)));
1248       ppHRegPPC(i->Pin.Alu.dst);
1249       vex_printf(",");
1250       ppHRegPPC(r_srcL);
1251       vex_printf(",");
1252       ppPPCRH(rh_srcR);
1253       return;
1254    }
1255    case Pin_Shft: {
1256       HReg   r_srcL  = i->Pin.Shft.srcL;
1257       PPCRH* rh_srcR = i->Pin.Shft.srcR;
1258       vex_printf("%s ", showPPCShftOp(i->Pin.Shft.op,
1259                                       toBool(rh_srcR->tag == Prh_Imm),
1260                                       i->Pin.Shft.sz32));
1261       ppHRegPPC(i->Pin.Shft.dst);
1262       vex_printf(",");
1263       ppHRegPPC(r_srcL);
1264       vex_printf(",");
1265       ppPPCRH(rh_srcR);
1266       return;
1267    }
1268    case Pin_AddSubC:
1269       vex_printf("%s%s ",
1270                  i->Pin.AddSubC.isAdd ? "add" : "sub",
1271                  i->Pin.AddSubC.setC ? "c" : "e");
1272       ppHRegPPC(i->Pin.AddSubC.dst);
1273       vex_printf(",");
1274       ppHRegPPC(i->Pin.AddSubC.srcL);
1275       vex_printf(",");
1276       ppHRegPPC(i->Pin.AddSubC.srcR);
1277       return;
1278    case Pin_Cmp:
1279       vex_printf("%s%c%s %%cr%u,",
1280                  i->Pin.Cmp.syned ? "cmp" : "cmpl",
1281                  i->Pin.Cmp.sz32 ? 'w' : 'd',
1282                  i->Pin.Cmp.srcR->tag == Prh_Imm ? "i" : "",
1283                  i->Pin.Cmp.crfD);
1284       ppHRegPPC(i->Pin.Cmp.srcL);
1285       vex_printf(",");
1286       ppPPCRH(i->Pin.Cmp.srcR);
1287       return;
1288    case Pin_Unary:
1289       vex_printf("%s ", showPPCUnaryOp(i->Pin.Unary.op));
1290       ppHRegPPC(i->Pin.Unary.dst);
1291       vex_printf(",");
1292       ppHRegPPC(i->Pin.Unary.src);
1293       return;
1294    case Pin_MulL:
1295       vex_printf("mul%c%c%s ",
1296                  i->Pin.MulL.hi ? 'h' : 'l',
1297                  i->Pin.MulL.sz32 ? 'w' : 'd',
1298                  i->Pin.MulL.hi ? (i->Pin.MulL.syned ? "s" : "u") : "");
1299       ppHRegPPC(i->Pin.MulL.dst);
1300       vex_printf(",");
1301       ppHRegPPC(i->Pin.MulL.srcL);
1302       vex_printf(",");
1303       ppHRegPPC(i->Pin.MulL.srcR);
1304       return;
1305    case Pin_Div:
1306       vex_printf("div%c%s ",
1307                  i->Pin.Div.sz32 ? 'w' : 'd',
1308                  i->Pin.Div.syned ? "" : "u");
1309       ppHRegPPC(i->Pin.Div.dst);
1310       vex_printf(",");
1311       ppHRegPPC(i->Pin.Div.srcL);
1312       vex_printf(",");
1313       ppHRegPPC(i->Pin.Div.srcR);
1314       return;
1315    case Pin_Call: {
1316       Int n;
1317       vex_printf("call: ");
1318       if (i->Pin.Call.cond.test != Pct_ALWAYS) {
1319          vex_printf("if (%s) ", showPPCCondCode(i->Pin.Call.cond));
1320       }
1321       vex_printf("{ ");
1322       ppLoadImm(hregPPC_GPR10(mode64), i->Pin.Call.target, mode64);
1323       vex_printf(" ; mtctr r10 ; bctrl [");
1324       for (n = 0; n < 32; n++) {
1325          if (i->Pin.Call.argiregs & (1<<n)) {
1326             vex_printf("r%d", n);
1327             if ((i->Pin.Call.argiregs >> n) > 1)
1328                vex_printf(",");
1329          }
1330       }
1331       vex_printf("] }");
1332       break;
1333    }
1334    case Pin_Goto:
1335       vex_printf("goto: ");
1336       if (i->Pin.Goto.cond.test != Pct_ALWAYS) {
1337          vex_printf("if (%s) ", showPPCCondCode(i->Pin.Goto.cond));
1338       }
1339       vex_printf("{ ");
1340       if (i->Pin.Goto.jk != Ijk_Boring
1341           && i->Pin.Goto.jk != Ijk_Call
1342           && i->Pin.Goto.jk != Ijk_Ret) {
1343          vex_printf("li %%r31,$");
1344          ppIRJumpKind(i->Pin.Goto.jk);
1345          vex_printf(" ; ");
1346       }
1347       if (i->Pin.Goto.dst->tag == Pri_Imm) {
1348          ppLoadImm(hregPPC_GPR3(mode64), i->Pin.Goto.dst->Pri.Imm,
1349                    mode64);
1350       } else {
1351          ppMovReg(hregPPC_GPR3(mode64), i->Pin.Goto.dst->Pri.Reg);
1352       }
1353       vex_printf(" ; blr }");
1354       return;
1355    case Pin_CMov:
1356       vex_printf("cmov (%s) ", showPPCCondCode(i->Pin.CMov.cond));
1357       ppHRegPPC(i->Pin.CMov.dst);
1358       vex_printf(",");
1359       ppPPCRI(i->Pin.CMov.src);
1360       vex_printf(": ");
1361       if (i->Pin.CMov.cond.test != Pct_ALWAYS) {
1362          vex_printf("if (%s) ", showPPCCondCode(i->Pin.CMov.cond));
1363       }
1364       vex_printf("{ ");
1365       if (i->Pin.CMov.src->tag == Pri_Imm) {
1366          ppLoadImm(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Imm, mode64);
1367       } else {
1368          ppMovReg(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Reg);
1369       }
1370       vex_printf(" }");
1371       return;
1372    case Pin_Load: {
1373       Bool idxd = toBool(i->Pin.Load.src->tag == Pam_RR);
1374       UChar sz = i->Pin.Load.sz;
1375       UChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd';
1376       vex_printf("l%c%s%s ", c_sz, sz==8 ? "" : "z", idxd ? "x" : "" );
1377       ppHRegPPC(i->Pin.Load.dst);
1378       vex_printf(",");
1379       ppPPCAMode(i->Pin.Load.src);
1380       return;
1381    }
1382    case Pin_LoadL:
1383       vex_printf("l%carx ", i->Pin.LoadL.sz==4 ? 'w' : 'd');
1384       ppHRegPPC(i->Pin.LoadL.dst);
1385       vex_printf(",%%r0,");
1386       ppHRegPPC(i->Pin.LoadL.src);
1387       return;
1388    case Pin_Store: {
1389       UChar sz = i->Pin.Store.sz;
1390       Bool idxd = toBool(i->Pin.Store.dst->tag == Pam_RR);
1391       UChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : /*8*/ 'd';
1392       vex_printf("st%c%s ", c_sz, idxd ? "x" : "" );
1393       ppHRegPPC(i->Pin.Store.src);
1394       vex_printf(",");
1395       ppPPCAMode(i->Pin.Store.dst);
1396       return;
1397    }
1398    case Pin_StoreC:
1399       vex_printf("st%ccx. ", i->Pin.StoreC.sz==4 ? 'w' : 'd');
1400       ppHRegPPC(i->Pin.StoreC.src);
1401       vex_printf(",%%r0,");
1402       ppHRegPPC(i->Pin.StoreC.dst);
1403       return;
1404    case Pin_Set: {
1405       PPCCondCode cc = i->Pin.Set.cond;
1406       vex_printf("set (%s),", showPPCCondCode(cc));
1407       ppHRegPPC(i->Pin.Set.dst);
1408       if (cc.test == Pct_ALWAYS) {
1409          vex_printf(": { li ");
1410          ppHRegPPC(i->Pin.Set.dst);
1411          vex_printf(",1 }");
1412       } else {
1413          vex_printf(": { mfcr r0 ; rlwinm ");
1414          ppHRegPPC(i->Pin.Set.dst);
1415          vex_printf(",r0,%u,31,31", cc.flag+1);
1416          if (cc.test == Pct_FALSE) {
1417             vex_printf("; xori ");
1418             ppHRegPPC(i->Pin.Set.dst);
1419             vex_printf(",");
1420             ppHRegPPC(i->Pin.Set.dst);
1421             vex_printf(",1");
1422          }
1423          vex_printf(" }");
1424       }
1425       return;
1426    }
1427    case Pin_MfCR:
1428       vex_printf("mfcr ");
1429       ppHRegPPC(i->Pin.MfCR.dst);
1430       break;
1431    case Pin_MFence:
1432       vex_printf("mfence (=sync)");
1433       return;
1434
1435    case Pin_FpUnary:
1436       vex_printf("%s ", showPPCFpOp(i->Pin.FpUnary.op));
1437       ppHRegPPC(i->Pin.FpUnary.dst);
1438       vex_printf(",");
1439       ppHRegPPC(i->Pin.FpUnary.src);
1440       return;
1441    case Pin_FpBinary:
1442       vex_printf("%s ", showPPCFpOp(i->Pin.FpBinary.op));
1443       ppHRegPPC(i->Pin.FpBinary.dst);
1444       vex_printf(",");
1445       ppHRegPPC(i->Pin.FpBinary.srcL);
1446       vex_printf(",");
1447       ppHRegPPC(i->Pin.FpBinary.srcR);
1448       return;
1449    case Pin_FpMulAcc:
1450       vex_printf("%s ", showPPCFpOp(i->Pin.FpMulAcc.op));
1451       ppHRegPPC(i->Pin.FpMulAcc.dst);
1452       vex_printf(",");
1453       ppHRegPPC(i->Pin.FpMulAcc.srcML);
1454       vex_printf(",");
1455       ppHRegPPC(i->Pin.FpMulAcc.srcMR);
1456       vex_printf(",");
1457       ppHRegPPC(i->Pin.FpMulAcc.srcAcc);
1458       return;
1459    case Pin_FpLdSt: {
1460       UChar sz = i->Pin.FpLdSt.sz;
1461       Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR);
1462       if (i->Pin.FpLdSt.isLoad) {
1463          vex_printf("lf%c%s ",
1464                     (sz==4 ? 's' : 'd'),
1465                     idxd ? "x" : "" );
1466          ppHRegPPC(i->Pin.FpLdSt.reg);
1467          vex_printf(",");
1468          ppPPCAMode(i->Pin.FpLdSt.addr);
1469       } else {
1470          vex_printf("stf%c%s ",
1471                     (sz==4 ? 's' : 'd'),
1472                     idxd ? "x" : "" );
1473          ppHRegPPC(i->Pin.FpLdSt.reg);
1474          vex_printf(",");
1475          ppPPCAMode(i->Pin.FpLdSt.addr);
1476       }
1477       return;
1478    }
1479    case Pin_FpSTFIW:
1480       vex_printf("stfiwz ");
1481       ppHRegPPC(i->Pin.FpSTFIW.data);
1482       vex_printf(",0(");
1483       ppHRegPPC(i->Pin.FpSTFIW.addr);
1484       vex_printf(")");
1485       return;
1486    case Pin_FpRSP:
1487       vex_printf("frsp ");
1488       ppHRegPPC(i->Pin.FpRSP.dst);
1489       vex_printf(",");
1490       ppHRegPPC(i->Pin.FpRSP.src);
1491       return;
1492    case Pin_FpCftI: {
1493       HChar* str = "fc?????";
1494       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False)
1495          str = "fctid";
1496       else
1497       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True)
1498          str = "fctiw";
1499       else
1500       if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
1501          if (i->Pin.FpCftI.syned == True)
1502             str = "fcfid";
1503          else if (i->Pin.FpCftI.flt64 == True)
1504             str = "fcfidu";
1505          else
1506             str = "fcfidus";
1507       }
1508       vex_printf("%s ", str);
1509       ppHRegPPC(i->Pin.FpCftI.dst);
1510       vex_printf(",");
1511       ppHRegPPC(i->Pin.FpCftI.src);
1512       return;
1513    }
1514    case Pin_FpCMov:
1515       vex_printf("fpcmov (%s) ", showPPCCondCode(i->Pin.FpCMov.cond));
1516       ppHRegPPC(i->Pin.FpCMov.dst);
1517       vex_printf(",");
1518       ppHRegPPC(i->Pin.FpCMov.src);
1519       vex_printf(": ");
1520       vex_printf("if (fr_dst != fr_src) { ");
1521       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS) {
1522          vex_printf("if (%s) { ", showPPCCondCode(i->Pin.FpCMov.cond));
1523       }
1524       vex_printf("fmr ");
1525       ppHRegPPC(i->Pin.FpCMov.dst);
1526       vex_printf(",");
1527       ppHRegPPC(i->Pin.FpCMov.src);
1528       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS)
1529          vex_printf(" }");
1530       vex_printf(" }");
1531       return;
1532    case Pin_FpLdFPSCR:
1533       vex_printf("mtfsf 0xFF,");
1534       ppHRegPPC(i->Pin.FpLdFPSCR.src);
1535       return;
1536    case Pin_FpCmp:
1537       vex_printf("fcmpo %%cr1,");
1538       ppHRegPPC(i->Pin.FpCmp.srcL);
1539       vex_printf(",");
1540       ppHRegPPC(i->Pin.FpCmp.srcR);
1541       vex_printf("; mfcr ");
1542       ppHRegPPC(i->Pin.FpCmp.dst);
1543       vex_printf("; rlwinm ");
1544       ppHRegPPC(i->Pin.FpCmp.dst);
1545       vex_printf(",");
1546       ppHRegPPC(i->Pin.FpCmp.dst);
1547       vex_printf(",8,28,31");
1548       return;
1549
1550    case Pin_RdWrLR:
1551       vex_printf("%s ", i->Pin.RdWrLR.wrLR ? "mtlr" : "mflr");
1552       ppHRegPPC(i->Pin.RdWrLR.gpr);
1553       return;
1554
1555    case Pin_AvLdSt: {
1556       UChar  sz = i->Pin.AvLdSt.sz;
1557       HChar* str_size;
1558       if (i->Pin.AvLdSt.addr->tag == Pam_IR) {
1559          ppLoadImm(hregPPC_GPR30(mode64),
1560                    i->Pin.AvLdSt.addr->Pam.RR.index, mode64);
1561          vex_printf(" ; ");
1562       }
1563       str_size = sz==1 ? "eb" : sz==2 ? "eh" : sz==4 ? "ew" : "";
1564       if (i->Pin.AvLdSt.isLoad)
1565          vex_printf("lv%sx ", str_size);
1566       else
1567          vex_printf("stv%sx ", str_size);
1568       ppHRegPPC(i->Pin.AvLdSt.reg);
1569       vex_printf(",");
1570       if (i->Pin.AvLdSt.addr->tag == Pam_IR)
1571          vex_printf("%%r30");
1572       else 
1573          ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.index);
1574       vex_printf(",");
1575       ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.base);
1576       return;
1577    }
1578    case Pin_AvUnary:
1579       vex_printf("%s ", showPPCAvOp(i->Pin.AvUnary.op));
1580       ppHRegPPC(i->Pin.AvUnary.dst);
1581       vex_printf(",");
1582       ppHRegPPC(i->Pin.AvUnary.src);
1583       return;
1584    case Pin_AvBinary:
1585       vex_printf("%s ", showPPCAvOp(i->Pin.AvBinary.op));
1586       ppHRegPPC(i->Pin.AvBinary.dst);
1587       vex_printf(",");
1588       ppHRegPPC(i->Pin.AvBinary.srcL);
1589       vex_printf(",");
1590       ppHRegPPC(i->Pin.AvBinary.srcR);
1591       return;
1592    case Pin_AvBin8x16:
1593       vex_printf("%s(b) ", showPPCAvOp(i->Pin.AvBin8x16.op));
1594       ppHRegPPC(i->Pin.AvBin8x16.dst);
1595       vex_printf(",");
1596       ppHRegPPC(i->Pin.AvBin8x16.srcL);
1597       vex_printf(",");
1598       ppHRegPPC(i->Pin.AvBin8x16.srcR);
1599       return;
1600    case Pin_AvBin16x8:
1601       vex_printf("%s(h) ", showPPCAvOp(i->Pin.AvBin16x8.op));
1602       ppHRegPPC(i->Pin.AvBin16x8.dst);
1603       vex_printf(",");
1604       ppHRegPPC(i->Pin.AvBin16x8.srcL);
1605       vex_printf(",");
1606       ppHRegPPC(i->Pin.AvBin16x8.srcR);
1607       return;
1608    case Pin_AvBin32x4:
1609       vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin32x4.op));
1610       ppHRegPPC(i->Pin.AvBin32x4.dst);
1611       vex_printf(",");
1612       ppHRegPPC(i->Pin.AvBin32x4.srcL);
1613       vex_printf(",");
1614       ppHRegPPC(i->Pin.AvBin32x4.srcR);
1615       return;
1616    case Pin_AvBin32Fx4:
1617       vex_printf("%s ", showPPCAvFpOp(i->Pin.AvBin32Fx4.op));
1618       ppHRegPPC(i->Pin.AvBin32Fx4.dst);
1619       vex_printf(",");
1620       ppHRegPPC(i->Pin.AvBin32Fx4.srcL);
1621       vex_printf(",");
1622       ppHRegPPC(i->Pin.AvBin32Fx4.srcR);
1623       return;
1624    case Pin_AvUn32Fx4:
1625       vex_printf("%s ", showPPCAvFpOp(i->Pin.AvUn32Fx4.op));
1626       ppHRegPPC(i->Pin.AvUn32Fx4.dst);
1627       vex_printf(",");
1628       ppHRegPPC(i->Pin.AvUn32Fx4.src);
1629       return;
1630    case Pin_AvPerm:
1631       vex_printf("vperm ");
1632       ppHRegPPC(i->Pin.AvPerm.dst);
1633       vex_printf(",");
1634       ppHRegPPC(i->Pin.AvPerm.srcL);
1635       vex_printf(",");
1636       ppHRegPPC(i->Pin.AvPerm.srcR);
1637       vex_printf(",");
1638       ppHRegPPC(i->Pin.AvPerm.ctl);
1639       return;
1640
1641    case Pin_AvSel:
1642       vex_printf("vsel ");
1643       ppHRegPPC(i->Pin.AvSel.dst);
1644       vex_printf(",");
1645       ppHRegPPC(i->Pin.AvSel.srcL);
1646       vex_printf(",");
1647       ppHRegPPC(i->Pin.AvSel.srcR);
1648       vex_printf(",");
1649       ppHRegPPC(i->Pin.AvSel.ctl);
1650       return;
1651
1652    case Pin_AvShlDbl:
1653       vex_printf("vsldoi ");
1654       ppHRegPPC(i->Pin.AvShlDbl.dst);
1655       vex_printf(",");
1656       ppHRegPPC(i->Pin.AvShlDbl.srcL);
1657       vex_printf(",");
1658       ppHRegPPC(i->Pin.AvShlDbl.srcR);
1659       vex_printf(",%d", i->Pin.AvShlDbl.shift);
1660       return;
1661
1662    case Pin_AvSplat: {
1663       UChar sz = i->Pin.AvSplat.sz;
1664       UChar ch_sz = toUChar( (sz == 8) ? 'b' : (sz == 16) ? 'h' : 'w' );
1665       vex_printf("vsplt%s%c ",
1666                  i->Pin.AvSplat.src->tag == Pvi_Imm ? "is" : "", ch_sz);
1667       ppHRegPPC(i->Pin.AvSplat.dst);
1668       vex_printf(",");
1669       ppPPCVI5s(i->Pin.AvSplat.src);
1670       if (i->Pin.AvSplat.src->tag == Pvi_Reg)
1671          vex_printf(", %d", (128/sz)-1);   /* louis lane */
1672       return;
1673    }
1674
1675    case Pin_AvCMov:
1676       vex_printf("avcmov (%s) ", showPPCCondCode(i->Pin.AvCMov.cond));
1677       ppHRegPPC(i->Pin.AvCMov.dst);
1678       vex_printf(",");
1679       ppHRegPPC(i->Pin.AvCMov.src);
1680       vex_printf(": ");
1681       vex_printf("if (v_dst != v_src) { ");
1682       if (i->Pin.AvCMov.cond.test != Pct_ALWAYS) {
1683          vex_printf("if (%s) { ", showPPCCondCode(i->Pin.AvCMov.cond));
1684       }
1685       vex_printf("vmr ");
1686       ppHRegPPC(i->Pin.AvCMov.dst);
1687       vex_printf(",");
1688       ppHRegPPC(i->Pin.AvCMov.src);
1689       if (i->Pin.FpCMov.cond.test != Pct_ALWAYS)
1690          vex_printf(" }");
1691       vex_printf(" }");
1692       return;
1693
1694    case Pin_AvLdVSCR:
1695       vex_printf("mtvscr ");
1696       ppHRegPPC(i->Pin.AvLdVSCR.src);
1697       return;
1698
1699    default:
1700       vex_printf("\nppPPCInstr: No such tag(%d)\n", (Int)i->tag);
1701       vpanic("ppPPCInstr");
1702    }
1703 }
1704
1705 /* --------- Helpers for register allocation. --------- */
1706
1707 void getRegUsage_PPCInstr ( HRegUsage* u, PPCInstr* i, Bool mode64 )
1708 {
1709    initHRegUsage(u);
1710    switch (i->tag) {
1711    case Pin_LI:
1712       addHRegUse(u, HRmWrite, i->Pin.LI.dst);
1713       break;
1714    case Pin_Alu:
1715       addHRegUse(u, HRmRead,  i->Pin.Alu.srcL);
1716       addRegUsage_PPCRH(u,    i->Pin.Alu.srcR);
1717       addHRegUse(u, HRmWrite, i->Pin.Alu.dst);
1718       return;
1719    case Pin_Shft:
1720       addHRegUse(u, HRmRead,  i->Pin.Shft.srcL);
1721       addRegUsage_PPCRH(u,    i->Pin.Shft.srcR);
1722       addHRegUse(u, HRmWrite, i->Pin.Shft.dst);
1723       return;
1724    case Pin_AddSubC:
1725       addHRegUse(u, HRmWrite, i->Pin.AddSubC.dst);
1726       addHRegUse(u, HRmRead,  i->Pin.AddSubC.srcL);
1727       addHRegUse(u, HRmRead,  i->Pin.AddSubC.srcR);
1728       return;
1729    case Pin_Cmp:
1730       addHRegUse(u, HRmRead, i->Pin.Cmp.srcL);
1731       addRegUsage_PPCRH(u,   i->Pin.Cmp.srcR);
1732       return;
1733    case Pin_Unary:
1734       addHRegUse(u, HRmWrite, i->Pin.Unary.dst);
1735       addHRegUse(u, HRmRead,  i->Pin.Unary.src);
1736       return;
1737    case Pin_MulL:
1738       addHRegUse(u, HRmWrite, i->Pin.MulL.dst);
1739       addHRegUse(u, HRmRead,  i->Pin.MulL.srcL);
1740       addHRegUse(u, HRmRead,  i->Pin.MulL.srcR);
1741       return;
1742    case Pin_Div:
1743       addHRegUse(u, HRmWrite, i->Pin.Div.dst);
1744       addHRegUse(u, HRmRead,  i->Pin.Div.srcL);
1745       addHRegUse(u, HRmRead,  i->Pin.Div.srcR);
1746       return;
1747    case Pin_Call: {
1748       UInt argir;
1749       /* This is a bit subtle. */
1750       /* First off, claim it trashes all the caller-saved regs
1751          which fall within the register allocator's jurisdiction.
1752          These I believe to be:
1753          mode32: r3 to r12
1754          mode64: r3 to r10
1755       */
1756       /* XXXXXXXXXXXXXXXXX BUG! This doesn't say anything about the FP
1757          or Altivec registers.  We get away with this ONLY because
1758          getAllocatableRegs_PPC gives the allocator callee-saved fp
1759          and Altivec regs, and no caller-save ones. */
1760       addHRegUse(u, HRmWrite, hregPPC_GPR3(mode64));
1761       addHRegUse(u, HRmWrite, hregPPC_GPR4(mode64));
1762       addHRegUse(u, HRmWrite, hregPPC_GPR5(mode64));
1763       addHRegUse(u, HRmWrite, hregPPC_GPR6(mode64));
1764       addHRegUse(u, HRmWrite, hregPPC_GPR7(mode64));
1765       addHRegUse(u, HRmWrite, hregPPC_GPR8(mode64));
1766       addHRegUse(u, HRmWrite, hregPPC_GPR9(mode64));
1767       addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64));
1768       if (!mode64) {
1769          addHRegUse(u, HRmWrite, hregPPC_GPR11(mode64));
1770          addHRegUse(u, HRmWrite, hregPPC_GPR12(mode64));
1771       }
1772
1773       /* Now we have to state any parameter-carrying registers
1774          which might be read.  This depends on the argiregs field. */
1775       argir = i->Pin.Call.argiregs;
1776       if (argir &(1<<10)) addHRegUse(u, HRmRead, hregPPC_GPR10(mode64));
1777       if (argir & (1<<9)) addHRegUse(u, HRmRead, hregPPC_GPR9(mode64));
1778       if (argir & (1<<8)) addHRegUse(u, HRmRead, hregPPC_GPR8(mode64));
1779       if (argir & (1<<7)) addHRegUse(u, HRmRead, hregPPC_GPR7(mode64));
1780       if (argir & (1<<6)) addHRegUse(u, HRmRead, hregPPC_GPR6(mode64));
1781       if (argir & (1<<5)) addHRegUse(u, HRmRead, hregPPC_GPR5(mode64));
1782       if (argir & (1<<4)) addHRegUse(u, HRmRead, hregPPC_GPR4(mode64));
1783       if (argir & (1<<3)) addHRegUse(u, HRmRead, hregPPC_GPR3(mode64));
1784
1785       vassert(0 == (argir & ~((1<<3)|(1<<4)|(1<<5)|(1<<6)
1786                               |(1<<7)|(1<<8)|(1<<9)|(1<<10))));
1787
1788       /* Finally, there is the issue that the insn trashes a
1789          register because the literal target address has to be
1790          loaded into a register.  %r10 seems a suitable victim.
1791          (Can't use %r0, as some insns interpret it as value zero). */
1792       addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64));
1793       /* Upshot of this is that the assembler really must use %r10,
1794          and no other, as a destination temporary. */
1795       return;
1796    }
1797    case Pin_Goto:
1798       addRegUsage_PPCRI(u, i->Pin.Goto.dst);
1799       /* GPR3 holds destination address from Pin_Goto */
1800       addHRegUse(u, HRmWrite, hregPPC_GPR3(mode64));
1801       if (i->Pin.Goto.jk != Ijk_Boring
1802           && i->Pin.Goto.jk != Ijk_Call
1803           && i->Pin.Goto.jk != Ijk_Ret)
1804             /* note, this is irrelevant since the guest state pointer
1805                register is not actually available to the allocator.
1806                But still .. */
1807          addHRegUse(u, HRmWrite, GuestStatePtr(mode64));
1808       return;
1809    case Pin_CMov:
1810       addRegUsage_PPCRI(u,  i->Pin.CMov.src);
1811       addHRegUse(u, HRmWrite, i->Pin.CMov.dst);
1812       return;
1813    case Pin_Load:
1814       addRegUsage_PPCAMode(u, i->Pin.Load.src);
1815       addHRegUse(u, HRmWrite, i->Pin.Load.dst);
1816       return;
1817    case Pin_LoadL:
1818       addHRegUse(u, HRmRead,  i->Pin.LoadL.src);
1819       addHRegUse(u, HRmWrite, i->Pin.LoadL.dst);
1820       return;
1821    case Pin_Store:
1822       addHRegUse(u, HRmRead,  i->Pin.Store.src);
1823       addRegUsage_PPCAMode(u, i->Pin.Store.dst);
1824       return;
1825    case Pin_StoreC:
1826       addHRegUse(u, HRmRead, i->Pin.StoreC.src);
1827       addHRegUse(u, HRmRead, i->Pin.StoreC.dst);
1828       return;
1829    case Pin_Set:
1830       addHRegUse(u, HRmWrite, i->Pin.Set.dst);
1831       return;
1832    case Pin_MfCR:
1833       addHRegUse(u, HRmWrite, i->Pin.MfCR.dst);
1834       return;
1835    case Pin_MFence:
1836       return;
1837
1838    case Pin_FpUnary:
1839       addHRegUse(u, HRmWrite, i->Pin.FpUnary.dst);
1840       addHRegUse(u, HRmRead,  i->Pin.FpUnary.src);
1841       return;
1842    case Pin_FpBinary:
1843       addHRegUse(u, HRmWrite, i->Pin.FpBinary.dst);
1844       addHRegUse(u, HRmRead,  i->Pin.FpBinary.srcL);
1845       addHRegUse(u, HRmRead,  i->Pin.FpBinary.srcR);
1846       return;
1847    case Pin_FpMulAcc:
1848       addHRegUse(u, HRmWrite, i->Pin.FpMulAcc.dst);
1849       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcML);
1850       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcMR);
1851       addHRegUse(u, HRmRead,  i->Pin.FpMulAcc.srcAcc);
1852       return;
1853    case Pin_FpLdSt:
1854       addHRegUse(u, (i->Pin.FpLdSt.isLoad ? HRmWrite : HRmRead),
1855                  i->Pin.FpLdSt.reg);
1856       addRegUsage_PPCAMode(u, i->Pin.FpLdSt.addr);
1857       return;
1858    case Pin_FpSTFIW:
1859       addHRegUse(u, HRmRead, i->Pin.FpSTFIW.addr);
1860       addHRegUse(u, HRmRead, i->Pin.FpSTFIW.data);
1861       return;
1862    case Pin_FpRSP:
1863       addHRegUse(u, HRmWrite, i->Pin.FpRSP.dst);
1864       addHRegUse(u, HRmRead,  i->Pin.FpRSP.src);
1865       return;
1866    case Pin_FpCftI:
1867       addHRegUse(u, HRmWrite, i->Pin.FpCftI.dst);
1868       addHRegUse(u, HRmRead,  i->Pin.FpCftI.src);
1869       return;
1870    case Pin_FpCMov:
1871       addHRegUse(u, HRmModify, i->Pin.FpCMov.dst);
1872       addHRegUse(u, HRmRead,   i->Pin.FpCMov.src);
1873       return;
1874    case Pin_FpLdFPSCR:
1875       addHRegUse(u, HRmRead, i->Pin.FpLdFPSCR.src);
1876       return;
1877    case Pin_FpCmp:
1878       addHRegUse(u, HRmWrite, i->Pin.FpCmp.dst);
1879       addHRegUse(u, HRmRead,  i->Pin.FpCmp.srcL);
1880       addHRegUse(u, HRmRead,  i->Pin.FpCmp.srcR);
1881       return;
1882
1883    case Pin_RdWrLR:
1884       addHRegUse(u, (i->Pin.RdWrLR.wrLR ? HRmRead : HRmWrite),
1885                  i->Pin.RdWrLR.gpr);
1886       return;
1887
1888    case Pin_AvLdSt:
1889       addHRegUse(u, (i->Pin.AvLdSt.isLoad ? HRmWrite : HRmRead),
1890                  i->Pin.AvLdSt.reg);
1891       if (i->Pin.AvLdSt.addr->tag == Pam_IR)
1892          addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64));
1893       addRegUsage_PPCAMode(u, i->Pin.AvLdSt.addr);
1894       return;
1895    case Pin_AvUnary:
1896       addHRegUse(u, HRmWrite, i->Pin.AvUnary.dst);
1897       addHRegUse(u, HRmRead,  i->Pin.AvUnary.src);
1898       return;
1899    case Pin_AvBinary:
1900       if (i->Pin.AvBinary.op == Pav_XOR
1901           && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcL
1902           && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcR) {
1903          /* reg-alloc needs to understand 'xor r,r,r' as a write of r */
1904          /* (as opposed to a rite of passage :-) */
1905          addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
1906       } else {
1907          addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
1908          addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcL);
1909          addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcR);
1910       }
1911       return;
1912    case Pin_AvBin8x16:
1913       addHRegUse(u, HRmWrite, i->Pin.AvBin8x16.dst);
1914       addHRegUse(u, HRmRead,  i->Pin.AvBin8x16.srcL);
1915       addHRegUse(u, HRmRead,  i->Pin.AvBin8x16.srcR);
1916       return;
1917    case Pin_AvBin16x8:
1918       addHRegUse(u, HRmWrite, i->Pin.AvBin16x8.dst);
1919       addHRegUse(u, HRmRead,  i->Pin.AvBin16x8.srcL);
1920       addHRegUse(u, HRmRead,  i->Pin.AvBin16x8.srcR);
1921       return;
1922    case Pin_AvBin32x4:
1923       addHRegUse(u, HRmWrite, i->Pin.AvBin32x4.dst);
1924       addHRegUse(u, HRmRead,  i->Pin.AvBin32x4.srcL);
1925       addHRegUse(u, HRmRead,  i->Pin.AvBin32x4.srcR);
1926       return;
1927    case Pin_AvBin32Fx4:
1928       addHRegUse(u, HRmWrite, i->Pin.AvBin32Fx4.dst);
1929       addHRegUse(u, HRmRead,  i->Pin.AvBin32Fx4.srcL);
1930       addHRegUse(u, HRmRead,  i->Pin.AvBin32Fx4.srcR);
1931       if (i->Pin.AvBin32Fx4.op == Pavfp_MULF)
1932          addHRegUse(u, HRmWrite, hregPPC_VR29());
1933       return;
1934    case Pin_AvUn32Fx4:
1935       addHRegUse(u, HRmWrite, i->Pin.AvUn32Fx4.dst);
1936       addHRegUse(u, HRmRead,  i->Pin.AvUn32Fx4.src);
1937       return;
1938    case Pin_AvPerm:
1939       addHRegUse(u, HRmWrite, i->Pin.AvPerm.dst);
1940       addHRegUse(u, HRmRead,  i->Pin.AvPerm.srcL);
1941       addHRegUse(u, HRmRead,  i->Pin.AvPerm.srcR);
1942       addHRegUse(u, HRmRead,  i->Pin.AvPerm.ctl);
1943       return;
1944    case Pin_AvSel:
1945       addHRegUse(u, HRmWrite, i->Pin.AvSel.dst);
1946       addHRegUse(u, HRmRead,  i->Pin.AvSel.ctl);
1947       addHRegUse(u, HRmRead,  i->Pin.AvSel.srcL);
1948       addHRegUse(u, HRmRead,  i->Pin.AvSel.srcR);
1949       return;
1950    case Pin_AvShlDbl:
1951       addHRegUse(u, HRmWrite, i->Pin.AvShlDbl.dst);
1952       addHRegUse(u, HRmRead,  i->Pin.AvShlDbl.srcL);
1953       addHRegUse(u, HRmRead,  i->Pin.AvShlDbl.srcR);
1954       return;
1955    case Pin_AvSplat:
1956       addHRegUse(u, HRmWrite, i->Pin.AvSplat.dst);
1957       addRegUsage_PPCVI5s(u,  i->Pin.AvSplat.src);
1958       return;
1959    case Pin_AvCMov:
1960       addHRegUse(u, HRmModify, i->Pin.AvCMov.dst);
1961       addHRegUse(u, HRmRead,   i->Pin.AvCMov.src);
1962       return;
1963    case Pin_AvLdVSCR:
1964       addHRegUse(u, HRmRead, i->Pin.AvLdVSCR.src);
1965       return;
1966
1967    default:
1968       ppPPCInstr(i, mode64);
1969       vpanic("getRegUsage_PPCInstr");
1970    }
1971 }
1972
1973 /* local helper */
1974 static void mapReg( HRegRemap* m, HReg* r )
1975 {
1976    *r = lookupHRegRemap(m, *r);
1977 }
1978
1979 void mapRegs_PPCInstr ( HRegRemap* m, PPCInstr* i, Bool mode64 )
1980 {
1981    switch (i->tag) {
1982    case Pin_LI:
1983       mapReg(m, &i->Pin.LI.dst);
1984       return;
1985    case Pin_Alu:
1986       mapReg(m, &i->Pin.Alu.dst);
1987       mapReg(m, &i->Pin.Alu.srcL);
1988       mapRegs_PPCRH(m, i->Pin.Alu.srcR);
1989       return;
1990    case Pin_Shft:
1991       mapReg(m, &i->Pin.Shft.dst);
1992       mapReg(m, &i->Pin.Shft.srcL);
1993       mapRegs_PPCRH(m, i->Pin.Shft.srcR);
1994       return;
1995    case Pin_AddSubC:
1996       mapReg(m, &i->Pin.AddSubC.dst);
1997       mapReg(m, &i->Pin.AddSubC.srcL);
1998       mapReg(m, &i->Pin.AddSubC.srcR);
1999       return;
2000    case Pin_Cmp:
2001       mapReg(m, &i->Pin.Cmp.srcL);
2002       mapRegs_PPCRH(m, i->Pin.Cmp.srcR);
2003       return;
2004    case Pin_Unary:
2005       mapReg(m, &i->Pin.Unary.dst);
2006       mapReg(m, &i->Pin.Unary.src);
2007       return;
2008    case Pin_MulL:
2009       mapReg(m, &i->Pin.MulL.dst);
2010       mapReg(m, &i->Pin.MulL.srcL);
2011       mapReg(m, &i->Pin.MulL.srcR);
2012       return;
2013    case Pin_Div:
2014       mapReg(m, &i->Pin.Div.dst);
2015       mapReg(m, &i->Pin.Div.srcL);
2016       mapReg(m, &i->Pin.Div.srcR);
2017       return;
2018    case Pin_Call:
2019       return;
2020    case Pin_Goto:
2021       mapRegs_PPCRI(m, i->Pin.Goto.dst);
2022       return;
2023    case Pin_CMov:
2024       mapRegs_PPCRI(m, i->Pin.CMov.src);
2025       mapReg(m, &i->Pin.CMov.dst);
2026       return;
2027    case Pin_Load:
2028       mapRegs_PPCAMode(m, i->Pin.Load.src);
2029       mapReg(m, &i->Pin.Load.dst);
2030       return;
2031    case Pin_LoadL:
2032       mapReg(m, &i->Pin.LoadL.src);
2033       mapReg(m, &i->Pin.LoadL.dst);
2034       return;
2035    case Pin_Store:
2036       mapReg(m, &i->Pin.Store.src);
2037       mapRegs_PPCAMode(m, i->Pin.Store.dst);
2038       return;
2039    case Pin_StoreC:
2040       mapReg(m, &i->Pin.StoreC.src);
2041       mapReg(m, &i->Pin.StoreC.dst);
2042       return;
2043    case Pin_Set:
2044       mapReg(m, &i->Pin.Set.dst);
2045       return;
2046    case Pin_MfCR:
2047       mapReg(m, &i->Pin.MfCR.dst);
2048       return;
2049    case Pin_MFence:
2050       return;
2051    case Pin_FpUnary:
2052       mapReg(m, &i->Pin.FpUnary.dst);
2053       mapReg(m, &i->Pin.FpUnary.src);
2054       return;
2055    case Pin_FpBinary:
2056       mapReg(m, &i->Pin.FpBinary.dst);
2057       mapReg(m, &i->Pin.FpBinary.srcL);
2058       mapReg(m, &i->Pin.FpBinary.srcR);
2059       return;
2060    case Pin_FpMulAcc:
2061       mapReg(m, &i->Pin.FpMulAcc.dst);
2062       mapReg(m, &i->Pin.FpMulAcc.srcML);
2063       mapReg(m, &i->Pin.FpMulAcc.srcMR);
2064       mapReg(m, &i->Pin.FpMulAcc.srcAcc);
2065       return;
2066    case Pin_FpLdSt:
2067       mapReg(m, &i->Pin.FpLdSt.reg);
2068       mapRegs_PPCAMode(m, i->Pin.FpLdSt.addr);
2069       return;
2070    case Pin_FpSTFIW:
2071       mapReg(m, &i->Pin.FpSTFIW.addr);
2072       mapReg(m, &i->Pin.FpSTFIW.data);
2073       return;
2074    case Pin_FpRSP:
2075       mapReg(m, &i->Pin.FpRSP.dst);
2076       mapReg(m, &i->Pin.FpRSP.src);
2077       return;
2078    case Pin_FpCftI:
2079       mapReg(m, &i->Pin.FpCftI.dst);
2080       mapReg(m, &i->Pin.FpCftI.src);
2081       return;
2082    case Pin_FpCMov:
2083       mapReg(m, &i->Pin.FpCMov.dst);
2084       mapReg(m, &i->Pin.FpCMov.src);
2085       return;
2086    case Pin_FpLdFPSCR:
2087       mapReg(m, &i->Pin.FpLdFPSCR.src);
2088       return;
2089    case Pin_FpCmp:
2090       mapReg(m, &i->Pin.FpCmp.dst);
2091       mapReg(m, &i->Pin.FpCmp.srcL);
2092       mapReg(m, &i->Pin.FpCmp.srcR);
2093       return;
2094    case Pin_RdWrLR:
2095       mapReg(m, &i->Pin.RdWrLR.gpr);
2096       return;
2097    case Pin_AvLdSt:
2098       mapReg(m, &i->Pin.AvLdSt.reg);
2099       mapRegs_PPCAMode(m, i->Pin.AvLdSt.addr);
2100       return;
2101    case Pin_AvUnary:
2102       mapReg(m, &i->Pin.AvUnary.dst);
2103       mapReg(m, &i->Pin.AvUnary.src);
2104       return;
2105    case Pin_AvBinary:
2106       mapReg(m, &i->Pin.AvBinary.dst);
2107       mapReg(m, &i->Pin.AvBinary.srcL);
2108       mapReg(m, &i->Pin.AvBinary.srcR);
2109       return;
2110    case Pin_AvBin8x16:
2111       mapReg(m, &i->Pin.AvBin8x16.dst);
2112       mapReg(m, &i->Pin.AvBin8x16.srcL);
2113       mapReg(m, &i->Pin.AvBin8x16.srcR);
2114       return;
2115    case Pin_AvBin16x8:
2116       mapReg(m, &i->Pin.AvBin16x8.dst);
2117       mapReg(m, &i->Pin.AvBin16x8.srcL);
2118       mapReg(m, &i->Pin.AvBin16x8.srcR);
2119       return;
2120    case Pin_AvBin32x4:
2121       mapReg(m, &i->Pin.AvBin32x4.dst);
2122       mapReg(m, &i->Pin.AvBin32x4.srcL);
2123       mapReg(m, &i->Pin.AvBin32x4.srcR);
2124       return;
2125    case Pin_AvBin32Fx4:
2126       mapReg(m, &i->Pin.AvBin32Fx4.dst);
2127       mapReg(m, &i->Pin.AvBin32Fx4.srcL);
2128       mapReg(m, &i->Pin.AvBin32Fx4.srcR);
2129       return;
2130    case Pin_AvUn32Fx4:
2131       mapReg(m, &i->Pin.AvUn32Fx4.dst);
2132       mapReg(m, &i->Pin.AvUn32Fx4.src);
2133       return;
2134    case Pin_AvPerm:
2135       mapReg(m, &i->Pin.AvPerm.dst);
2136       mapReg(m, &i->Pin.AvPerm.srcL);
2137       mapReg(m, &i->Pin.AvPerm.srcR);
2138       mapReg(m, &i->Pin.AvPerm.ctl);
2139       return;
2140    case Pin_AvSel:
2141       mapReg(m, &i->Pin.AvSel.dst);
2142       mapReg(m, &i->Pin.AvSel.srcL);
2143       mapReg(m, &i->Pin.AvSel.srcR);
2144       mapReg(m, &i->Pin.AvSel.ctl);
2145       return;
2146    case Pin_AvShlDbl:
2147       mapReg(m, &i->Pin.AvShlDbl.dst);
2148       mapReg(m, &i->Pin.AvShlDbl.srcL);
2149       mapReg(m, &i->Pin.AvShlDbl.srcR);
2150       return;
2151    case Pin_AvSplat:
2152       mapReg(m, &i->Pin.AvSplat.dst);
2153       mapRegs_PPCVI5s(m, i->Pin.AvSplat.src);
2154       return;
2155    case Pin_AvCMov:
2156      mapReg(m, &i->Pin.AvCMov.dst);
2157      mapReg(m, &i->Pin.AvCMov.src);
2158      return;
2159    case Pin_AvLdVSCR:
2160       mapReg(m, &i->Pin.AvLdVSCR.src);
2161       return;
2162
2163    default:
2164       ppPPCInstr(i, mode64);
2165       vpanic("mapRegs_PPCInstr");
2166    }
2167 }
2168
2169 /* Figure out if i represents a reg-reg move, and if so assign the
2170    source and destination to *src and *dst.  If in doubt say No.  Used
2171    by the register allocator to do move coalescing. 
2172 */
2173 Bool isMove_PPCInstr ( PPCInstr* i, HReg* src, HReg* dst )
2174 {
2175    /* Moves between integer regs */
2176    if (i->tag == Pin_Alu) {
2177       // or Rd,Rs,Rs == mr Rd,Rs
2178       if (i->Pin.Alu.op != Palu_OR)
2179          return False;
2180       if (i->Pin.Alu.srcR->tag != Prh_Reg)
2181          return False;
2182       if (i->Pin.Alu.srcR->Prh.Reg.reg != i->Pin.Alu.srcL)
2183          return False;
2184       *src = i->Pin.Alu.srcL;
2185       *dst = i->Pin.Alu.dst;
2186       return True;
2187    }
2188    /* Moves between FP regs */
2189    if (i->tag == Pin_FpUnary) {
2190       if (i->Pin.FpUnary.op != Pfp_MOV)
2191          return False;
2192       *src = i->Pin.FpUnary.src;
2193       *dst = i->Pin.FpUnary.dst;
2194       return True;
2195    }
2196    return False;
2197 }
2198
2199
2200 /* Generate ppc spill/reload instructions under the direction of the
2201    register allocator.  Note it's critical these don't write the
2202    condition codes. */
2203
2204 void genSpill_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
2205                     HReg rreg, Int offsetB, Bool mode64 )
2206 {
2207    PPCAMode* am;
2208    vassert(!hregIsVirtual(rreg));
2209    *i1 = *i2 = NULL;
2210    am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) );
2211    switch (hregClass(rreg)) {
2212       case HRcInt64:
2213          vassert(mode64);
2214          *i1 = PPCInstr_Store( 8, am, rreg, mode64 );
2215          return;
2216       case HRcInt32:
2217          vassert(!mode64);
2218          *i1 = PPCInstr_Store( 4, am, rreg, mode64 );
2219          return;
2220       case HRcFlt64:
2221          *i1 = PPCInstr_FpLdSt ( False/*store*/, 8, rreg, am );
2222          return;
2223       case HRcVec128:
2224          // XXX: GPR30 used as spill register to kludge AltiVec
2225          // AMode_IR
2226          *i1 = PPCInstr_AvLdSt ( False/*store*/, 16, rreg, am );
2227          return;
2228       default: 
2229          ppHRegClass(hregClass(rreg));
2230          vpanic("genSpill_PPC: unimplemented regclass");
2231    }
2232 }
2233
2234 void genReload_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
2235                      HReg rreg, Int offsetB, Bool mode64 )
2236 {
2237    PPCAMode* am;
2238    vassert(!hregIsVirtual(rreg));
2239    *i1 = *i2 = NULL;
2240    am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) );
2241    switch (hregClass(rreg)) {
2242       case HRcInt64:
2243          vassert(mode64);
2244          *i1 = PPCInstr_Load( 8, rreg, am, mode64 );
2245          return;
2246       case HRcInt32:
2247          vassert(!mode64);
2248          *i1 = PPCInstr_Load( 4, rreg, am, mode64 );
2249          return;
2250       case HRcFlt64:
2251          *i1 = PPCInstr_FpLdSt ( True/*load*/, 8, rreg, am );
2252          return;
2253       case HRcVec128:
2254          // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR
2255          *i1 = PPCInstr_AvLdSt ( True/*load*/, 16, rreg, am );
2256          return;
2257       default: 
2258          ppHRegClass(hregClass(rreg));
2259          vpanic("genReload_PPC: unimplemented regclass");
2260    }
2261 }
2262
2263
2264 /* --------- The ppc assembler (bleh.) --------- */
2265
2266 static UInt iregNo ( HReg r, Bool mode64 )
2267 {
2268    UInt n;
2269    vassert(hregClass(r) == mode64 ? HRcInt64 : HRcInt32);
2270    vassert(!hregIsVirtual(r));
2271    n = hregNumber(r);
2272    vassert(n <= 32);
2273    return n;
2274 }
2275
2276 static UInt fregNo ( HReg fr )
2277 {
2278    UInt n;
2279    vassert(hregClass(fr) == HRcFlt64);
2280    vassert(!hregIsVirtual(fr));
2281    n = hregNumber(fr);
2282    vassert(n <= 32);
2283    return n;
2284 }
2285
2286 static UInt vregNo ( HReg v )
2287 {
2288    UInt n;
2289    vassert(hregClass(v) == HRcVec128);
2290    vassert(!hregIsVirtual(v));
2291    n = hregNumber(v);
2292    vassert(n <= 32);
2293    return n;
2294 }
2295
2296 /* Emit 32bit instruction big-endianly */
2297 static UChar* emit32 ( UChar* p, UInt w32 )
2298 {
2299    *p++ = toUChar((w32 >> 24) & 0x000000FF);
2300    *p++ = toUChar((w32 >> 16) & 0x000000FF);
2301    *p++ = toUChar((w32 >>  8) & 0x000000FF);
2302    *p++ = toUChar((w32)       & 0x000000FF);
2303    return p;
2304 }
2305
2306 /* The following mkForm[...] functions refer to ppc instruction forms
2307    as per PPC32 p576
2308  */
2309
2310 static UChar* mkFormD ( UChar* p, UInt opc1,
2311                         UInt r1, UInt r2, UInt imm )
2312 {
2313    UInt theInstr;
2314    vassert(opc1 < 0x40);
2315    vassert(r1   < 0x20);
2316    vassert(r2   < 0x20);
2317    imm = imm & 0xFFFF;
2318    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (imm));
2319    return emit32(p, theInstr);
2320 }
2321
2322 static UChar* mkFormMD ( UChar* p, UInt opc1, UInt r1, UInt r2,
2323                          UInt imm1, UInt imm2, UInt opc2 )
2324 {
2325    UInt theInstr;
2326    vassert(opc1 < 0x40);
2327    vassert(r1   < 0x20);
2328    vassert(r2   < 0x20);
2329    vassert(imm1 < 0x40);
2330    vassert(imm2 < 0x40);
2331    vassert(opc2 < 0x08);
2332    imm2 = ((imm2 & 0x1F) << 1) | (imm2 >> 5);
2333    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2334                ((imm1 & 0x1F)<<11) | (imm2<<5) |
2335                (opc2<<2) | ((imm1 >> 5)<<1));
2336    return emit32(p, theInstr);
2337 }
2338
2339 static UChar* mkFormX ( UChar* p, UInt opc1, UInt r1, UInt r2,
2340                         UInt r3, UInt opc2, UInt b0 )
2341 {
2342    UInt theInstr;
2343    vassert(opc1 < 0x40);
2344    vassert(r1   < 0x20);
2345    vassert(r2   < 0x20);
2346    vassert(r3   < 0x20);
2347    vassert(opc2 < 0x400);
2348    vassert(b0   < 0x2);
2349    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2350                (r3<<11) | (opc2<<1) | (b0));
2351    return emit32(p, theInstr);
2352 }
2353
2354 static UChar* mkFormXO ( UChar* p, UInt opc1, UInt r1, UInt r2,
2355                          UInt r3, UInt b10, UInt opc2, UInt b0 )
2356 {
2357    UInt theInstr;
2358    vassert(opc1 < 0x40);
2359    vassert(r1   < 0x20);
2360    vassert(r2   < 0x20);
2361    vassert(r3   < 0x20);
2362    vassert(b10  < 0x2);
2363    vassert(opc2 < 0x200);
2364    vassert(b0   < 0x2);
2365    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2366                (r3<<11) | (b10 << 10) | (opc2<<1) | (b0));
2367    return emit32(p, theInstr);
2368 }
2369
2370 static UChar* mkFormXL ( UChar* p, UInt opc1, UInt f1, UInt f2,
2371                          UInt f3, UInt opc2, UInt b0 )
2372 {
2373    UInt theInstr;
2374    vassert(opc1 < 0x40);
2375    vassert(f1   < 0x20);
2376    vassert(f2   < 0x20);
2377    vassert(f3   < 0x20);
2378    vassert(opc2 < 0x400);
2379    vassert(b0   < 0x2);
2380    theInstr = ((opc1<<26) | (f1<<21) | (f2<<16) |
2381                (f3<<11) | (opc2<<1) | (b0));
2382    return emit32(p, theInstr);
2383 }
2384
2385 // Note: for split field ops, give mnemonic arg
2386 static UChar* mkFormXFX ( UChar* p, UInt r1, UInt f2, UInt opc2 )
2387 {
2388    UInt theInstr;
2389    vassert(r1   < 0x20);
2390    vassert(f2   < 0x20);
2391    vassert(opc2 < 0x400);
2392    switch (opc2) {
2393    case 144:  // mtcrf
2394       vassert(f2 < 0x100);
2395       f2 = f2 << 1;
2396       break;
2397    case 339:  // mfspr
2398    case 371:  // mftb
2399    case 467:  // mtspr
2400       vassert(f2 < 0x400);
2401       // re-arrange split field
2402       f2 = ((f2>>5) & 0x1F) | ((f2 & 0x1F)<<5);
2403       break;
2404    default: vpanic("mkFormXFX(ppch)");
2405    }
2406    theInstr = ((31<<26) | (r1<<21) | (f2<<11) | (opc2<<1));
2407    return emit32(p, theInstr);
2408 }
2409
2410 // Only used by mtfsf
2411 static UChar* mkFormXFL ( UChar* p, UInt FM, UInt freg )
2412 {
2413    UInt theInstr;
2414    vassert(FM   < 0x100);
2415    vassert(freg < 0x20);
2416    theInstr = ((63<<26) | (FM<<17) | (freg<<11) | (711<<1));
2417    return emit32(p, theInstr);
2418 }
2419
2420 static UChar* mkFormXS ( UChar* p, UInt opc1, UInt r1, UInt r2,
2421                          UInt imm, UInt opc2, UInt b0 )
2422 {
2423    UInt theInstr;
2424    vassert(opc1 < 0x40);
2425    vassert(r1   < 0x20);
2426    vassert(r2   < 0x20);
2427    vassert(imm  < 0x40);
2428    vassert(opc2 < 0x400);
2429    vassert(b0   < 0x2);
2430    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2431                ((imm & 0x1F)<<11) | (opc2<<2) | ((imm>>5)<<1) | (b0));
2432    return emit32(p, theInstr);
2433 }
2434
2435
2436 #if 0
2437 // 'b'
2438 static UChar* mkFormI ( UChar* p, UInt LI, UInt AA, UInt LK )
2439 {
2440    UInt theInstr;
2441    vassert(LI  < 0x1000000);
2442    vassert(AA  < 0x2);
2443    vassert(LK  < 0x2);
2444    theInstr = ((18<<26) | (LI<<2) | (AA<<1) | (LK));
2445    return emit32(p, theInstr);
2446 }
2447 #endif
2448
2449 // 'bc'
2450 static UChar* mkFormB ( UChar* p, UInt BO, UInt BI,
2451                         UInt BD, UInt AA, UInt LK )
2452 {
2453    UInt theInstr;
2454    vassert(BO  < 0x20);
2455    vassert(BI  < 0x20);
2456    vassert(BD  < 0x4000);
2457    vassert(AA  < 0x2);
2458    vassert(LK  < 0x2);
2459    theInstr = ((16<<26) | (BO<<21) | (BI<<16) |
2460                (BD<<2) | (AA<<1) | (LK));
2461    return emit32(p, theInstr);
2462 }
2463
2464 // rotates
2465 static UChar* mkFormM ( UChar* p, UInt opc1, UInt r1, UInt r2,
2466                         UInt f3, UInt MB, UInt ME, UInt Rc )
2467 {
2468    UInt theInstr;
2469    vassert(opc1 < 0x40);
2470    vassert(r1   < 0x20);
2471    vassert(r2   < 0x20);
2472    vassert(f3   < 0x20);
2473    vassert(MB   < 0x20);
2474    vassert(ME   < 0x20);
2475    vassert(Rc   < 0x2);
2476    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2477                (f3<<11) | (MB<<6) | (ME<<1) | (Rc));
2478    return emit32(p, theInstr);
2479 }
2480
2481 static UChar* mkFormA ( UChar* p, UInt opc1, UInt r1, UInt r2,
2482                         UInt r3, UInt r4, UInt opc2, UInt b0 )
2483 {
2484    UInt theInstr;
2485    vassert(opc1 < 0x40);
2486    vassert(r1   < 0x20);
2487    vassert(r2   < 0x20);
2488    vassert(r3   < 0x20);
2489    vassert(r4   < 0x20);
2490    vassert(opc2 < 0x20);
2491    vassert(b0   < 0x2 );
2492    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) |
2493                (r4<<6) | (opc2<<1) | (b0));
2494    return emit32(p, theInstr);
2495 }
2496
2497 static UChar* doAMode_IR ( UChar* p, UInt opc1, UInt rSD,
2498                            PPCAMode* am, Bool mode64 )
2499 {
2500    UInt rA, idx;
2501    vassert(am->tag == Pam_IR);
2502    vassert(am->Pam.IR.index < 0x10000);
2503
2504    rA  = iregNo(am->Pam.IR.base, mode64);
2505    idx = am->Pam.IR.index;
2506
2507    if (opc1 == 58 || opc1 == 62) { // ld/std: mode64 only
2508       vassert(mode64);
2509       /* stay sane with DS form: lowest 2 bits must be 00.  This
2510          should be guaranteed to us by iselWordExpr_AMode. */
2511       vassert(0 == (idx & 3));
2512    }
2513    p = mkFormD(p, opc1, rSD, rA, idx);
2514    return p;
2515 }
2516
2517 static UChar* doAMode_RR ( UChar* p, UInt opc1, UInt opc2,
2518                            UInt rSD, PPCAMode* am, Bool mode64 )
2519 {
2520    UInt rA, rB;
2521    vassert(am->tag == Pam_RR);
2522
2523    rA  = iregNo(am->Pam.RR.base, mode64);
2524    rB  = iregNo(am->Pam.RR.index, mode64);
2525    
2526    p = mkFormX(p, opc1, rSD, rA, rB, opc2, 0);
2527    return p;
2528 }
2529
2530
2531 /* Load imm to r_dst */
2532 static UChar* mkLoadImm ( UChar* p, UInt r_dst, ULong imm, Bool mode64 )
2533 {
2534    vassert(r_dst < 0x20);
2535
2536    if (!mode64) {
2537       /* In 32-bit mode, make sure the top 32 bits of imm are a sign
2538          extension of the bottom 32 bits, so that the range tests
2539          below work correctly. */
2540       UInt u32 = (UInt)imm;
2541       Int  s32 = (Int)u32;
2542       Long s64 = (Long)s32;
2543       imm = (ULong)s64;
2544    }
2545
2546    if (imm >= 0xFFFFFFFFFFFF8000ULL || imm < 0x8000) {
2547       // sign-extendable from 16 bits
2548
2549       // addi r_dst,0,imm  => li r_dst,imm
2550       p = mkFormD(p, 14, r_dst, 0, imm & 0xFFFF);
2551    } else {
2552       if (imm >= 0xFFFFFFFF80000000ULL || imm < 0x80000000ULL) {
2553          // sign-extendable from 32 bits
2554
2555          // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
2556          p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF);
2557          // ori r_dst, r_dst, (imm & 0xFFFF)
2558          p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF);
2559       } else {
2560          // full 64bit immediate load: 5 (five!) insns.
2561          vassert(mode64);
2562
2563          // load high word
2564
2565          // lis r_dst, (imm>>48) & 0xFFFF
2566          p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF);
2567
2568          // ori r_dst, r_dst, (imm>>32) & 0xFFFF
2569          if ((imm>>32) & 0xFFFF)
2570             p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF);
2571          
2572          // shift r_dst low word to high word => rldicr
2573          p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1);
2574
2575          // load low word
2576
2577          // oris r_dst, r_dst, (imm>>16) & 0xFFFF
2578          if ((imm>>16) & 0xFFFF)
2579             p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF);
2580
2581          // ori r_dst, r_dst, (imm) & 0xFFFF
2582          if (imm & 0xFFFF)
2583             p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF);
2584       }
2585    }
2586    return p;
2587 }
2588
2589 /* Move r_dst to r_src */
2590 static UChar* mkMoveReg ( UChar* p, UInt r_dst, UInt r_src )
2591 {
2592    vassert(r_dst < 0x20);
2593    vassert(r_src < 0x20);
2594
2595    if (r_dst != r_src) {
2596       /* or r_dst, r_src, r_src */
2597       p = mkFormX(p, 31, r_src, r_dst, r_src, 444, 0 );
2598    }
2599    return p;
2600 }
2601
2602 static UChar* mkFormVX ( UChar* p, UInt opc1, UInt r1, UInt r2,
2603                          UInt r3, UInt opc2 )
2604 {
2605    UInt theInstr;
2606    vassert(opc1 < 0x40);
2607    vassert(r1   < 0x20);
2608    vassert(r2   < 0x20);
2609    vassert(r3   < 0x20);
2610    vassert(opc2 < 0x800);
2611    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | opc2);
2612    return emit32(p, theInstr);
2613 }
2614
2615 static UChar* mkFormVXR ( UChar* p, UInt opc1, UInt r1, UInt r2,
2616                           UInt r3, UInt Rc, UInt opc2 )
2617 {
2618    UInt theInstr;
2619    vassert(opc1 < 0x40);
2620    vassert(r1   < 0x20);
2621    vassert(r2   < 0x20);
2622    vassert(r3   < 0x20);
2623    vassert(Rc   < 0x2);
2624    vassert(opc2 < 0x400);
2625    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2626                (r3<<11) | (Rc<<10) | opc2);
2627    return emit32(p, theInstr);
2628 }
2629
2630 static UChar* mkFormVA ( UChar* p, UInt opc1, UInt r1, UInt r2,
2631                          UInt r3, UInt r4, UInt opc2 )
2632 {
2633    UInt theInstr;
2634    vassert(opc1 < 0x40);
2635    vassert(r1   < 0x20);
2636    vassert(r2   < 0x20);
2637    vassert(r3   < 0x20);
2638    vassert(r4   < 0x20);
2639    vassert(opc2 < 0x40);
2640    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
2641                (r3<<11) | (r4<<6) | opc2);
2642    return emit32(p, theInstr);
2643 }
2644
2645
2646
2647 /* Emit an instruction into buf and return the number of bytes used.
2648    Note that buf is not the insn's final place, and therefore it is
2649    imperative to emit position-independent code. 
2650
2651    Note, dispatch should always be NULL since ppc32/64 backends
2652    use a call-return scheme to get from the dispatcher to generated
2653    code and back.
2654 */
2655 Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, 
2656                     Bool mode64, void* dispatch )
2657 {
2658    UChar* p = &buf[0];
2659    UChar* ptmp = p;
2660    vassert(nbuf >= 32);
2661
2662    if (0) {
2663       vex_printf("asm  ");ppPPCInstr(i, mode64); vex_printf("\n");
2664    }
2665
2666    switch (i->tag) {
2667
2668    case Pin_LI:
2669       p = mkLoadImm(p, iregNo(i->Pin.LI.dst, mode64),
2670                     i->Pin.LI.imm64, mode64);
2671       goto done;
2672
2673    case Pin_Alu: {
2674       PPCRH* srcR   = i->Pin.Alu.srcR;
2675       Bool   immR   = toBool(srcR->tag == Prh_Imm);
2676       UInt   r_dst  = iregNo(i->Pin.Alu.dst, mode64);
2677       UInt   r_srcL = iregNo(i->Pin.Alu.srcL, mode64);
2678       UInt   r_srcR = immR ? (-1)/*bogus*/ :
2679                              iregNo(srcR->Prh.Reg.reg, mode64);
2680
2681       switch (i->Pin.Alu.op) {
2682       case Palu_ADD:
2683          if (immR) {
2684             /* addi (PPC32 p350) */
2685             vassert(srcR->Prh.Imm.syned);
2686             vassert(srcR->Prh.Imm.imm16 != 0x8000);
2687             p = mkFormD(p, 14, r_dst, r_srcL, srcR->Prh.Imm.imm16);
2688          } else {
2689             /* add (PPC32 p347) */
2690             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 266, 0);
2691          }
2692          break;
2693
2694       case Palu_SUB:
2695          if (immR) {
2696             /* addi (PPC32 p350), but with negated imm */
2697             vassert(srcR->Prh.Imm.syned);
2698             vassert(srcR->Prh.Imm.imm16 != 0x8000);
2699             p = mkFormD(p, 14, r_dst, r_srcL, (- srcR->Prh.Imm.imm16));
2700          } else {
2701             /* subf (PPC32 p537), with args the "wrong" way round */
2702             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 40, 0);
2703          }
2704          break;
2705
2706       case Palu_AND:
2707          if (immR) {
2708             /* andi. (PPC32 p358) */
2709             vassert(!srcR->Prh.Imm.syned);
2710             p = mkFormD(p, 28, r_srcL, r_dst, srcR->Prh.Imm.imm16);
2711          } else {
2712             /* and (PPC32 p356) */
2713             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 28, 0);
2714          }
2715          break;
2716
2717       case Palu_OR:
2718          if (immR) {
2719             /* ori (PPC32 p497) */
2720             vassert(!srcR->Prh.Imm.syned);
2721             p = mkFormD(p, 24, r_srcL, r_dst, srcR->Prh.Imm.imm16);
2722          } else {
2723             /* or (PPC32 p495) */
2724             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 444, 0);
2725          }
2726          break;
2727
2728       case Palu_XOR:
2729          if (immR) {
2730             /* xori (PPC32 p550) */
2731             vassert(!srcR->Prh.Imm.syned);
2732             p = mkFormD(p, 26, r_srcL, r_dst, srcR->Prh.Imm.imm16);
2733          } else {
2734             /* xor (PPC32 p549) */
2735             p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 316, 0);
2736          }
2737          break;
2738
2739       default:
2740          goto bad;
2741       }
2742       goto done;
2743    }
2744
2745    case Pin_Shft: {
2746       PPCRH* srcR   = i->Pin.Shft.srcR;
2747       Bool   sz32   = i->Pin.Shft.sz32;
2748       Bool   immR   = toBool(srcR->tag == Prh_Imm);
2749       UInt   r_dst  = iregNo(i->Pin.Shft.dst, mode64);
2750       UInt   r_srcL = iregNo(i->Pin.Shft.srcL, mode64);
2751       UInt   r_srcR = immR ? (-1)/*bogus*/ :
2752                              iregNo(srcR->Prh.Reg.reg, mode64);
2753       if (!mode64)
2754          vassert(sz32);
2755
2756       switch (i->Pin.Shft.op) {
2757       case Pshft_SHL:
2758          if (sz32) {
2759             if (immR) {
2760                /* rd = rs << n, 1 <= n <= 31
2761                   is
2762                   rlwinm rd,rs,n,0,31-n  (PPC32 p501)
2763                */
2764                UInt n = srcR->Prh.Imm.imm16;
2765                vassert(!srcR->Prh.Imm.syned);
2766                vassert(n > 0 && n < 32);
2767                p = mkFormM(p, 21, r_srcL, r_dst, n, 0, 31-n, 0);
2768             } else {
2769                /* slw (PPC32 p505) */
2770                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 24, 0);
2771             }
2772          } else {
2773             if (immR) {
2774                /* rd = rs << n, 1 <= n <= 63
2775                   is
2776                   rldicr rd,rs,n,63-n  (PPC64 p559)
2777                */
2778                UInt n = srcR->Prh.Imm.imm16;
2779                vassert(!srcR->Prh.Imm.syned);
2780                vassert(n > 0 && n < 64);
2781                p = mkFormMD(p, 30, r_srcL, r_dst, n, 63-n, 1);
2782             } else {
2783                /* sld (PPC64 p568) */
2784                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 27, 0);
2785             }
2786          }
2787          break;
2788
2789       case Pshft_SHR:
2790          if (sz32) {
2791              if (immR) {
2792                /* rd = rs >>u n, 1 <= n <= 31
2793                   is
2794                   rlwinm rd,rs,32-n,n,31  (PPC32 p501)
2795                */
2796                UInt n = srcR->Prh.Imm.imm16;
2797                vassert(!srcR->Prh.Imm.syned);
2798                vassert(n > 0 && n < 32);
2799                p = mkFormM(p, 21, r_srcL, r_dst, 32-n, n, 31, 0);
2800             } else {
2801                /* srw (PPC32 p508) */
2802                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 536, 0);
2803             }
2804          } else {
2805             if (immR) {
2806                /* rd = rs >>u n, 1 <= n <= 63
2807                   is
2808                   rldicl rd,rs,64-n,n  (PPC64 p558)
2809                */
2810                UInt n = srcR->Prh.Imm.imm16;
2811                vassert(!srcR->Prh.Imm.syned);
2812                vassert(n > 0 && n < 64);
2813                p = mkFormMD(p, 30, r_srcL, r_dst, 64-n, n, 0);
2814             } else {
2815                /* srd (PPC64 p574) */
2816                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 539, 0);
2817             }
2818          }
2819          break;
2820
2821       case Pshft_SAR:
2822          if (sz32) {
2823             if (immR) {
2824                /* srawi (PPC32 p507) */
2825                UInt n = srcR->Prh.Imm.imm16;
2826                vassert(!srcR->Prh.Imm.syned);
2827                /* In 64-bit mode, we allow right shifts by zero bits
2828                   as that is a handy way to sign extend the lower 32
2829                   bits into the upper 32 bits. */
2830                if (mode64)
2831                   vassert(n >= 0 && n < 32);
2832                else 
2833                   vassert(n > 0 && n < 32);
2834                p = mkFormX(p, 31, r_srcL, r_dst, n, 824, 0);
2835             } else {
2836                /* sraw (PPC32 p506) */
2837                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 792, 0);
2838             }
2839          } else {
2840             if (immR) {
2841                /* sradi (PPC64 p571) */
2842                UInt n = srcR->Prh.Imm.imm16;
2843                vassert(!srcR->Prh.Imm.syned);
2844                vassert(n > 0 && n < 64);
2845                p = mkFormXS(p, 31, r_srcL, r_dst, n, 413, 0);
2846             } else {
2847                /* srad (PPC32 p570) */
2848                p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 794, 0);
2849             }
2850          }
2851          break;
2852
2853       default:
2854          goto bad;
2855       }
2856       goto done;
2857    }
2858
2859    case Pin_AddSubC: {
2860       Bool isAdd  = i->Pin.AddSubC.isAdd;
2861       Bool setC   = i->Pin.AddSubC.setC;
2862       UInt r_srcL = iregNo(i->Pin.AddSubC.srcL, mode64);
2863       UInt r_srcR = iregNo(i->Pin.AddSubC.srcR, mode64);
2864       UInt r_dst  = iregNo(i->Pin.AddSubC.dst, mode64);
2865       
2866       if (isAdd) {
2867          if (setC) /* addc (PPC32 p348) */
2868             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 10, 0);
2869          else          /* adde (PPC32 p349) */
2870             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 138, 0);
2871       } else {
2872          /* subfX, with args the "wrong" way round */
2873          if (setC) /* subfc (PPC32 p538) */
2874             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 8, 0);
2875          else          /* subfe (PPC32 p539) */
2876             p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 136, 0);
2877       }
2878       goto done;
2879    }
2880
2881    case Pin_Cmp: {
2882       Bool syned  = i->Pin.Cmp.syned;
2883       Bool sz32   = i->Pin.Cmp.sz32;
2884       UInt fld1   = i->Pin.Cmp.crfD << 2;
2885       UInt r_srcL = iregNo(i->Pin.Cmp.srcL, mode64);
2886       UInt r_srcR, imm_srcR;
2887       PPCRH* srcR = i->Pin.Cmp.srcR;
2888
2889       if (!mode64)        // cmp double word invalid for mode32
2890          vassert(sz32);      
2891       else if (!sz32)     // mode64 && cmp64: set L=1
2892          fld1 |= 1;
2893  
2894       switch (srcR->tag) {
2895       case Prh_Imm:
2896          vassert(syned == srcR->Prh.Imm.syned);
2897          imm_srcR = srcR->Prh.Imm.imm16;
2898          if (syned) {  // cmpw/di  (signed)   (PPC32 p368)
2899             vassert(imm_srcR != 0x8000);
2900             p = mkFormD(p, 11, fld1, r_srcL, imm_srcR);
2901          } else {      // cmplw/di (unsigned) (PPC32 p370)
2902             p = mkFormD(p, 10, fld1, r_srcL, imm_srcR);
2903          }
2904          break;
2905       case Prh_Reg:
2906          r_srcR = iregNo(srcR->Prh.Reg.reg, mode64);
2907          if (syned)  // cmpwi  (signed)   (PPC32 p367)
2908             p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 0, 0);
2909          else        // cmplwi (unsigned) (PPC32 p379)
2910             p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 32, 0);
2911          break;
2912       default: 
2913          goto bad;
2914       }        
2915       goto done;
2916    }
2917
2918    case Pin_Unary: {
2919       UInt r_dst = iregNo(i->Pin.Unary.dst, mode64);
2920       UInt r_src = iregNo(i->Pin.Unary.src, mode64);
2921
2922       switch (i->Pin.Unary.op) {
2923       case Pun_NOT:  // nor r_dst,r_src,r_src
2924          p = mkFormX(p, 31, r_src, r_dst, r_src, 124, 0);
2925          break;
2926       case Pun_NEG:  // neg r_dst,r_src
2927          p = mkFormXO(p, 31, r_dst, r_src, 0, 0, 104, 0);
2928          break;
2929       case Pun_CLZ32:  // cntlzw r_dst, r_src
2930          p = mkFormX(p, 31, r_src, r_dst, 0, 26, 0);
2931          break;
2932       case Pun_CLZ64:  // cntlzd r_dst, r_src
2933          vassert(mode64);
2934          p = mkFormX(p, 31, r_src, r_dst, 0, 58, 0);
2935          break;
2936       case Pun_EXTSW:  // extsw r_dst, r_src
2937          vassert(mode64);
2938          p = mkFormX(p, 31, r_src, r_dst, 0, 986, 0);
2939          break;
2940       default: goto bad;
2941       }
2942       goto done;
2943    }
2944
2945    case Pin_MulL: {
2946       Bool syned  = i->Pin.MulL.syned;
2947       Bool sz32   = i->Pin.MulL.sz32;
2948       UInt r_dst  = iregNo(i->Pin.MulL.dst, mode64);
2949       UInt r_srcL = iregNo(i->Pin.MulL.srcL, mode64);
2950       UInt r_srcR = iregNo(i->Pin.MulL.srcR, mode64);
2951
2952       if (!mode64)
2953          vassert(sz32);
2954
2955       if (i->Pin.MulL.hi) {
2956          // mul hi words, must consider sign
2957          if (sz32) {
2958             if (syned)  // mulhw r_dst,r_srcL,r_srcR
2959                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 75, 0);
2960             else        // mulhwu r_dst,r_srcL,r_srcR
2961                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 11, 0);
2962          } else {
2963             if (syned)  // mulhd r_dst,r_srcL,r_srcR
2964                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 73, 0);
2965             else        // mulhdu r_dst,r_srcL,r_srcR
2966                p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 9, 0);
2967          }
2968       } else {
2969          // mul low word, sign is irrelevant
2970          vassert(!i->Pin.MulL.syned);
2971          if (sz32)      // mullw r_dst,r_srcL,r_srcR
2972             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 235, 0);
2973          else           // mulld r_dst,r_srcL,r_srcR
2974             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 233, 0);
2975       }
2976       goto done;
2977    }
2978
2979    case Pin_Div: {
2980       Bool syned  = i->Pin.Div.syned;
2981       Bool sz32   = i->Pin.Div.sz32;
2982       UInt r_dst  = iregNo(i->Pin.Div.dst, mode64);
2983       UInt r_srcL = iregNo(i->Pin.Div.srcL, mode64);
2984       UInt r_srcR = iregNo(i->Pin.Div.srcR, mode64);
2985
2986       if (!mode64)
2987          vassert(sz32);
2988
2989       if (sz32) {
2990          if (syned)  // divw r_dst,r_srcL,r_srcR
2991             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 491, 0);
2992          else        // divwu r_dst,r_srcL,r_srcR
2993             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 459, 0);
2994       } else {
2995          if (syned)  // divd r_dst,r_srcL,r_srcR
2996             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 489, 0);
2997          else        // divdu r_dst,r_srcL,r_srcR
2998             p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 457, 0);
2999       }
3000       goto done;
3001    }
3002
3003    case Pin_Call: {
3004       PPCCondCode cond  = i->Pin.Call.cond;
3005       UInt        r_dst = 10;
3006       /* As per detailed comment for Pin_Call in
3007          getRegUsage_PPCInstr above, %r10 is used as an address temp */
3008
3009       /* jump over the following insns if condition does not hold */
3010       if (cond.test != Pct_ALWAYS) {
3011          /* jmp fwds if !condition */
3012          /* don't know how many bytes to jump over yet...
3013             make space for a jump instruction and fill in later. */
3014          ptmp = p; /* fill in this bit later */
3015          p += 4;                                          // p += 4
3016       }
3017
3018       /* load target to r_dst */                          // p += 4|8|20
3019       p = mkLoadImm(p, r_dst, i->Pin.Call.target, mode64);
3020
3021       /* mtspr 9,r_dst => move r_dst to count register */
3022       p = mkFormXFX(p, r_dst, 9, 467);                    // p += 4
3023       
3024       /* bctrl => branch to count register (and save to lr) */
3025       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 1);      // p += 4
3026
3027       /* Fix up the conditional jump, if there was one. */
3028       if (cond.test != Pct_ALWAYS) {
3029          Int delta = p - ptmp;
3030          vassert(delta >= 16 && delta <= 32);
3031          /* bc !ct,cf,delta */
3032          mkFormB(ptmp, invertCondTest(cond.test),
3033                  cond.flag, (delta>>2), 0, 0);
3034       }
3035       goto done;
3036    }
3037
3038    case Pin_Goto: {
3039       UInt        trc   = 0;
3040       UChar       r_ret = 3;        /* Put target addr into %r3 */
3041       PPCCondCode cond  = i->Pin.Goto.cond;
3042       UInt r_dst;
3043       ULong imm_dst;
3044
3045       vassert(dispatch == NULL);
3046       
3047       /* First off, if this is conditional, create a conditional
3048          jump over the rest of it. */
3049       if (cond.test != Pct_ALWAYS) {
3050          /* jmp fwds if !condition */
3051          /* don't know how many bytes to jump over yet...
3052             make space for a jump instruction and fill in later. */
3053          ptmp = p; /* fill in this bit later */
3054          p += 4;
3055       }
3056
3057       // cond succeeds...
3058       
3059       /* If a non-boring, set GuestStatePtr appropriately. */
3060       switch (i->Pin.Goto.jk) {
3061          case Ijk_ClientReq:   trc = VEX_TRC_JMP_CLIENTREQ;   break;
3062          case Ijk_Sys_syscall: trc = VEX_TRC_JMP_SYS_SYSCALL; break;
3063          case Ijk_Yield:       trc = VEX_TRC_JMP_YIELD;       break;
3064          case Ijk_EmWarn:      trc = VEX_TRC_JMP_EMWARN;      break;
3065          case Ijk_EmFail:      trc = VEX_TRC_JMP_EMFAIL;      break;
3066          case Ijk_MapFail:     trc = VEX_TRC_JMP_MAPFAIL;     break;
3067          case Ijk_NoDecode:    trc = VEX_TRC_JMP_NODECODE;    break;
3068          case Ijk_TInval:      trc = VEX_TRC_JMP_TINVAL;      break;
3069          case Ijk_NoRedir:     trc = VEX_TRC_JMP_NOREDIR;     break;
3070          case Ijk_SigTRAP:     trc = VEX_TRC_JMP_SIGTRAP;     break;
3071          case Ijk_SigBUS:      trc = VEX_TRC_JMP_SIGBUS;      break;
3072          case Ijk_Ret:
3073          case Ijk_Call:
3074          case Ijk_Boring:
3075             break;
3076          default: 
3077             ppIRJumpKind(i->Pin.Goto.jk);
3078             vpanic("emit_PPCInstr.Pin_Goto: unknown jump kind");
3079       }
3080       if (trc !=0) {
3081          vassert(trc < 0x10000);
3082          /* addi r31,0,trc */
3083          p = mkFormD(p, 14, 31, 0, trc);               // p += 4
3084       }
3085
3086       /* Get the destination address into %r_ret */
3087       if (i->Pin.Goto.dst->tag == Pri_Imm) {
3088          imm_dst = i->Pin.Goto.dst->Pri.Imm;
3089          p = mkLoadImm(p, r_ret, imm_dst, mode64);     // p += 4|8|20
3090       } else {
3091          vassert(i->Pin.Goto.dst->tag == Pri_Reg);
3092          r_dst = iregNo(i->Pin.Goto.dst->Pri.Reg, mode64);
3093          p = mkMoveReg(p, r_ret, r_dst);               // p += 4
3094       }
3095       
3096       /* blr */
3097       p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 16, 0);    // p += 4
3098
3099       /* Fix up the conditional jump, if there was one. */
3100       if (cond.test != Pct_ALWAYS) {
3101          Int delta = p - ptmp;
3102          vassert(delta >= 12 && delta <= 32);
3103          /* bc !ct,cf,delta */
3104          mkFormB(ptmp, invertCondTest(cond.test),
3105                  cond.flag, delta>>2, 0, 0);
3106       }
3107       goto done;
3108    }
3109
3110    case Pin_CMov: {
3111       UInt  r_dst, r_src;
3112       ULong imm_src;
3113       PPCCondCode cond;
3114       vassert(i->Pin.CMov.cond.test != Pct_ALWAYS);
3115
3116       r_dst = iregNo(i->Pin.CMov.dst, mode64);
3117       cond = i->Pin.CMov.cond;
3118
3119       /* branch (if cond fails) over move instrs */
3120       if (cond.test != Pct_ALWAYS) {
3121          /* don't know how many bytes to jump over yet...
3122             make space for a jump instruction and fill in later. */
3123          ptmp = p; /* fill in this bit later */
3124          p += 4;
3125       }
3126
3127       // cond true: move src => dst
3128       switch (i->Pin.CMov.src->tag) {
3129       case Pri_Imm:
3130          imm_src = i->Pin.CMov.src->Pri.Imm;
3131          p = mkLoadImm(p, r_dst, imm_src, mode64);  // p += 4|8|20
3132          break;
3133       case Pri_Reg:
3134          r_src = iregNo(i->Pin.CMov.src->Pri.Reg, mode64);
3135          p = mkMoveReg(p, r_dst, r_src);            // p += 4
3136          break;
3137       default: goto bad;
3138       }
3139
3140       /* Fix up the conditional jump, if there was one. */
3141       if (cond.test != Pct_ALWAYS) {
3142          Int delta = p - ptmp;
3143          vassert(delta >= 8 && delta <= 24);
3144          /* bc !ct,cf,delta */
3145          mkFormB(ptmp, invertCondTest(cond.test),
3146                  cond.flag, (delta>>2), 0, 0);
3147       }
3148       goto done;
3149    }
3150
3151    case Pin_Load: {
3152       PPCAMode* am_addr = i->Pin.Load.src;
3153       UInt r_dst = iregNo(i->Pin.Load.dst, mode64);
3154       UInt opc1, opc2, sz = i->Pin.Load.sz;
3155       switch (am_addr->tag) {
3156       case Pam_IR:
3157          if (mode64 && (sz == 4 || sz == 8)) {
3158             /* should be guaranteed to us by iselWordExpr_AMode */
3159             vassert(0 == (am_addr->Pam.IR.index & 3));
3160          }
3161          switch(sz) {
3162             case 1:  opc1 = 34; break;
3163             case 2:  opc1 = 40; break;
3164             case 4:  opc1 = 32; break;
3165             case 8:  opc1 = 58; vassert(mode64); break;
3166             default: goto bad;
3167          }
3168          p = doAMode_IR(p, opc1, r_dst, am_addr, mode64);
3169          goto done;
3170       case Pam_RR:
3171          switch(sz) {
3172             case 1:  opc2 = 87;  break;
3173             case 2:  opc2 = 279; break;
3174             case 4:  opc2 = 23;  break;
3175             case 8:  opc2 = 21; vassert(mode64); break;
3176             default: goto bad;
3177          }
3178          p = doAMode_RR(p, 31, opc2, r_dst, am_addr, mode64);
3179          goto done;
3180       default:
3181          goto bad;
3182       }
3183    }
3184
3185    case Pin_LoadL: {
3186       if (i->Pin.LoadL.sz == 4) {
3187          p = mkFormX(p, 31, iregNo(i->Pin.LoadL.dst, mode64),
3188                      0, iregNo(i->Pin.LoadL.src, mode64), 20, 0);
3189          goto done;
3190       }
3191       if (i->Pin.LoadL.sz == 8 && mode64) {
3192          p = mkFormX(p, 31, iregNo(i->Pin.LoadL.dst, mode64),
3193                      0, iregNo(i->Pin.LoadL.src, mode64), 84, 0);
3194          goto done;
3195       }
3196       goto bad;
3197    }
3198
3199    case Pin_Set: {
3200       /* Make the destination register be 1 or 0, depending on whether
3201          the relevant condition holds. */
3202       UInt        r_dst = iregNo(i->Pin.Set.dst, mode64);
3203       PPCCondCode cond  = i->Pin.Set.cond;
3204       UInt rot_imm, r_tmp;
3205
3206       if (cond.test == Pct_ALWAYS) {
3207          // Just load 1 to dst => li dst,1
3208          p = mkFormD(p, 14, r_dst, 0, 1);
3209       } else {
3210          vassert(cond.flag != Pcf_NONE);
3211          rot_imm = 1 + cond.flag;
3212          r_tmp = 0;  // Not set in getAllocable, so no need to declare.
3213
3214          // r_tmp = CR  => mfcr r_tmp
3215          p = mkFormX(p, 31, r_tmp, 0, 0, 19, 0);
3216
3217          // r_dst = flag (rotate left and mask)
3218          //  => rlwinm r_dst,r_tmp,rot_imm,31,31
3219          p = mkFormM(p, 21, r_tmp, r_dst, rot_imm, 31, 31, 0);
3220
3221          if (cond.test == Pct_FALSE) {
3222             // flip bit  => xori r_dst,r_dst,1
3223             p = mkFormD(p, 26, r_dst, r_dst, 1);
3224          }
3225       }
3226       goto done;
3227    }
3228
3229    case Pin_MfCR:
3230       // mfcr dst
3231       p = mkFormX(p, 31, iregNo(i->Pin.MfCR.dst, mode64), 0, 0, 19, 0);
3232       goto done;
3233
3234    case Pin_MFence: {
3235       p = mkFormX(p, 31, 0, 0, 0, 598, 0);   // sync, PPC32 p616
3236       // CAB: Should this be isync?
3237       //    p = mkFormXL(p, 19, 0, 0, 0, 150, 0);  // isync, PPC32 p467
3238       goto done;
3239    }
3240
3241    case Pin_Store: {
3242       PPCAMode* am_addr = i->Pin.Store.dst;
3243       UInt r_src = iregNo(i->Pin.Store.src, mode64);
3244       UInt opc1, opc2, sz = i->Pin.Store.sz;
3245       switch (i->Pin.Store.dst->tag) {
3246       case Pam_IR:
3247          if (mode64 && (sz == 4 || sz == 8)) {
3248             /* should be guaranteed to us by iselWordExpr_AMode */
3249             vassert(0 == (am_addr->Pam.IR.index & 3));
3250          }
3251          switch(sz) {
3252          case 1: opc1 = 38; break;
3253          case 2: opc1 = 44; break;
3254          case 4: opc1 = 36; break;
3255          case 8: vassert(mode64);
3256                  opc1 = 62; break;
3257          default:
3258             goto bad;
3259          }
3260          p = doAMode_IR(p, opc1, r_src, am_addr, mode64);
3261          goto done;
3262       case Pam_RR:
3263          switch(sz) {
3264          case 1: opc2 = 215; break;
3265          case 2: opc2 = 407; break;
3266          case 4: opc2 = 151; break;
3267          case 8: vassert(mode64);
3268                  opc2 = 149; break;
3269          default:
3270             goto bad;
3271          }
3272          p = doAMode_RR(p, 31, opc2, r_src, am_addr, mode64);
3273          goto done;
3274       default:
3275          goto bad;
3276       }
3277       goto done;
3278    }
3279
3280    case Pin_StoreC: {
3281       if (i->Pin.StoreC.sz == 4) {
3282          p = mkFormX(p, 31, iregNo(i->Pin.StoreC.src, mode64),
3283                      0, iregNo(i->Pin.StoreC.dst, mode64), 150, 1);
3284          goto done;
3285       }
3286       if (i->Pin.StoreC.sz == 8 && mode64) {
3287          p = mkFormX(p, 31, iregNo(i->Pin.StoreC.src, mode64),
3288                      0, iregNo(i->Pin.StoreC.dst, mode64), 214, 1);
3289          goto done;
3290       }
3291       goto bad;
3292    }
3293
3294    case Pin_FpUnary: {
3295       UInt fr_dst = fregNo(i->Pin.FpUnary.dst);
3296       UInt fr_src = fregNo(i->Pin.FpUnary.src);
3297       switch (i->Pin.FpUnary.op) {
3298       case Pfp_RSQRTE: // frsqrtre, PPC32 p424
3299          p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 26, 0 );
3300          break;
3301       case Pfp_RES:   // fres, PPC32 p421
3302          p = mkFormA( p, 59, fr_dst, 0, fr_src, 0, 24, 0 );
3303          break;
3304       case Pfp_SQRT:  // fsqrt, PPC32 p427
3305          p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 22, 0 );
3306          break;
3307       case Pfp_ABS:   // fabs, PPC32 p399
3308          p = mkFormX(p, 63, fr_dst, 0, fr_src, 264, 0);
3309          break;
3310       case Pfp_NEG:   // fneg, PPC32 p416
3311          p = mkFormX(p, 63, fr_dst, 0, fr_src, 40, 0);
3312          break;
3313       case Pfp_MOV:   // fmr, PPC32 p410
3314          p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0);
3315          break;
3316       case Pfp_FRIM:  // frim, PPC ISA 2.05 p137
3317          p = mkFormX(p, 63, fr_dst, 0, fr_src, 488, 0);
3318          break;
3319       case Pfp_FRIP:  // frip, PPC ISA 2.05 p137
3320          p = mkFormX(p, 63, fr_dst, 0, fr_src, 456, 0);
3321          break;
3322       case Pfp_FRIN:  // frin, PPC ISA 2.05 p137
3323          p = mkFormX(p, 63, fr_dst, 0, fr_src, 392, 0);
3324          break;
3325       case Pfp_FRIZ:  // friz, PPC ISA 2.05 p137
3326          p = mkFormX(p, 63, fr_dst, 0, fr_src, 424, 0);
3327          break;
3328       default:
3329          goto bad;
3330       }
3331       goto done;
3332    }
3333
3334    case Pin_FpBinary: {
3335       UInt fr_dst  = fregNo(i->Pin.FpBinary.dst);
3336       UInt fr_srcL = fregNo(i->Pin.FpBinary.srcL);
3337       UInt fr_srcR = fregNo(i->Pin.FpBinary.srcR);
3338       switch (i->Pin.FpBinary.op) {
3339       case Pfp_ADDD:   // fadd, PPC32 p400
3340          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 21, 0 );
3341          break;
3342       case Pfp_ADDS:   // fadds, PPC32 p401
3343          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 21, 0 );
3344          break;
3345       case Pfp_SUBD:   // fsub, PPC32 p429
3346          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 20, 0 );
3347          break;
3348       case Pfp_SUBS:   // fsubs, PPC32 p430
3349          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 20, 0 );
3350          break;
3351       case Pfp_MULD:   // fmul, PPC32 p413
3352          p = mkFormA( p, 63, fr_dst, fr_srcL, 0, fr_srcR, 25, 0 );
3353          break;
3354       case Pfp_MULS:   // fmuls, PPC32 p414
3355          p = mkFormA( p, 59, fr_dst, fr_srcL, 0, fr_srcR, 25, 0 );
3356          break;
3357       case Pfp_DIVD:   // fdiv, PPC32 p406
3358          p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 18, 0 );
3359          break;
3360       case Pfp_DIVS:   // fdivs, PPC32 p407
3361          p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 18, 0 );
3362          break;
3363       default:
3364          goto bad;
3365       }
3366       goto done;
3367    }
3368
3369    case Pin_FpMulAcc: {
3370       UInt fr_dst    = fregNo(i->Pin.FpMulAcc.dst);
3371       UInt fr_srcML  = fregNo(i->Pin.FpMulAcc.srcML);
3372       UInt fr_srcMR  = fregNo(i->Pin.FpMulAcc.srcMR);
3373       UInt fr_srcAcc = fregNo(i->Pin.FpMulAcc.srcAcc);
3374       switch (i->Pin.FpMulAcc.op) {
3375       case Pfp_MADDD:   // fmadd, PPC32 p408
3376          p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0 );
3377          break;
3378       case Pfp_MADDS:   // fmadds, PPC32 p409
3379          p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0 );
3380          break;
3381       case Pfp_MSUBD:   // fmsub, PPC32 p411
3382          p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0 );
3383          break;
3384       case Pfp_MSUBS:   // fmsubs, PPC32 p412
3385          p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0 );
3386          break;
3387       default:
3388          goto bad;
3389       }
3390       goto done;
3391    }
3392
3393    case Pin_FpLdSt: {
3394       PPCAMode* am_addr = i->Pin.FpLdSt.addr;
3395       UInt f_reg = fregNo(i->Pin.FpLdSt.reg);
3396       Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR);
3397       UChar sz = i->Pin.FpLdSt.sz;
3398       UInt opc;
3399       vassert(sz == 4 || sz == 8);
3400
3401       if (i->Pin.FpLdSt.isLoad) {   // Load from memory
3402          if (idxd) {  // lf[s|d]x, PPC32 p444|440
3403             opc = (sz == 4) ? 535 : 599;
3404             p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64);
3405          } else {     // lf[s|d], PPC32 p441|437
3406             opc = (sz == 4) ? 48 : 50;
3407             p = doAMode_IR(p, opc, f_reg, am_addr, mode64);
3408          }
3409       } else {                      // Store to memory
3410          if (idxd) { // stf[s|d]x, PPC32 p521|516
3411             opc = (sz == 4) ? 663 : 727;
3412             p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64);
3413          } else {    // stf[s|d], PPC32 p518|513
3414             opc = (sz == 4) ? 52 : 54;
3415             p = doAMode_IR(p, opc, f_reg, am_addr, mode64);
3416          }
3417       }
3418       goto done;
3419    }
3420
3421    case Pin_FpSTFIW: {
3422       UInt ir_addr = iregNo(i->Pin.FpSTFIW.addr, mode64);
3423       UInt fr_data = fregNo(i->Pin.FpSTFIW.data);
3424       // stfiwx (store fp64[lo32] as int32), PPC32 p517
3425       // Use rA==0, so that EA == rB == ir_addr
3426       p = mkFormX(p, 31, fr_data, 0/*rA=0*/, ir_addr, 983, 0);
3427       goto done;
3428    }
3429
3430    case Pin_FpRSP: {
3431       UInt fr_dst = fregNo(i->Pin.FpRSP.dst);
3432       UInt fr_src = fregNo(i->Pin.FpRSP.src);
3433       // frsp, PPC32 p423
3434       p = mkFormX(p, 63, fr_dst, 0, fr_src, 12, 0);
3435       goto done;
3436    }
3437
3438    case Pin_FpCftI: {
3439       UInt fr_dst = fregNo(i->Pin.FpCftI.dst);
3440       UInt fr_src = fregNo(i->Pin.FpCftI.src);
3441       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True) {
3442          // fctiw (conv f64 to i32), PPC32 p404
3443          p = mkFormX(p, 63, fr_dst, 0, fr_src, 14, 0);
3444          goto done;
3445       }
3446       if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False) {
3447          // fctid (conv f64 to i64), PPC64 p437
3448          p = mkFormX(p, 63, fr_dst, 0, fr_src, 814, 0);
3449          goto done;
3450       }
3451       if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
3452          if (i->Pin.FpCftI.syned == True) {
3453             // fcfid (conv i64 to f64), PPC64 p434
3454             p = mkFormX(p, 63, fr_dst, 0, fr_src, 846, 0);
3455             goto done;
3456          } else if (i->Pin.FpCftI.flt64 == True) {
3457             // fcfidu (conv u64 to f64)
3458             p = mkFormX(p, 63, fr_dst, 0, fr_src, 974, 0);
3459             goto done;
3460          } else {
3461             // fcfidus (conv u64 to f32)
3462             p = mkFormX(p, 59, fr_dst, 0, fr_src, 974, 0);
3463             goto done;
3464          }
3465       }
3466       goto bad;
3467    }
3468
3469    case Pin_FpCMov: {
3470       UInt        fr_dst = fregNo(i->Pin.FpCMov.dst);
3471       UInt        fr_src = fregNo(i->Pin.FpCMov.src);
3472       PPCCondCode cc     = i->Pin.FpCMov.cond;
3473
3474       if (fr_dst == fr_src) goto done;
3475       
3476       vassert(cc.test != Pct_ALWAYS);
3477
3478       /* jmp fwds if !condition */
3479       if (cc.test != Pct_ALWAYS) {
3480          /* bc !ct,cf,n_bytes>>2 */
3481          p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0);
3482       }
3483
3484       // fmr, PPC32 p410
3485       p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0);
3486       goto done;
3487    }
3488
3489    case Pin_FpLdFPSCR: {
3490       UInt fr_src = fregNo(i->Pin.FpLdFPSCR.src);
3491       p = mkFormXFL(p, 0xFF, fr_src);     // mtfsf, PPC32 p480
3492       goto done;
3493    }
3494
3495    case Pin_FpCmp: {
3496       UChar crfD    = 1;
3497       UInt  r_dst   = iregNo(i->Pin.FpCmp.dst, mode64);
3498       UInt  fr_srcL = fregNo(i->Pin.FpCmp.srcL);
3499       UInt  fr_srcR = fregNo(i->Pin.FpCmp.srcR);
3500       vassert(crfD < 8);
3501       // fcmpo, PPC32 p402
3502       p = mkFormX(p, 63, crfD<<2, fr_srcL, fr_srcR, 32, 0);
3503
3504       // mfcr (mv CR to r_dst), PPC32 p467
3505       p = mkFormX(p, 31, r_dst, 0, 0, 19, 0);
3506       
3507       // rlwinm r_dst,r_dst,8,28,31, PPC32 p501
3508       //  => rotate field 1 to bottomw of word, masking out upper 28
3509       p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0);
3510       goto done;
3511    }
3512
3513    case Pin_RdWrLR: {
3514       UInt reg = iregNo(i->Pin.RdWrLR.gpr, mode64);
3515       /* wrLR==True ? mtlr r4 : mflr r4 */
3516       p = mkFormXFX(p, reg, 8, (i->Pin.RdWrLR.wrLR==True) ? 467 : 339);
3517       goto done;
3518    }
3519
3520
3521    /* AltiVec */
3522    case Pin_AvLdSt: {
3523       UInt opc2, v_reg, r_idx, r_base;
3524       UChar sz   = i->Pin.AvLdSt.sz;
3525       Bool  idxd = toBool(i->Pin.AvLdSt.addr->tag == Pam_RR);
3526       vassert(sz == 1 || sz == 2 || sz == 4 || sz == 16);
3527
3528       v_reg  = vregNo(i->Pin.AvLdSt.reg);
3529       r_base = iregNo(i->Pin.AvLdSt.addr->Pam.RR.base, mode64);
3530
3531       // Only have AltiVec AMode_RR: kludge AMode_IR
3532       if (!idxd) {
3533          r_idx = 30;                       // XXX: Using r30 as temp
3534          p = mkLoadImm(p, r_idx,
3535                        i->Pin.AvLdSt.addr->Pam.IR.index, mode64);
3536       } else {
3537          r_idx  = iregNo(i->Pin.AvLdSt.addr->Pam.RR.index, mode64);
3538       }
3539
3540       if (i->Pin.FpLdSt.isLoad) {  // Load from memory (1,2,4,16)
3541          opc2 = (sz==1) ?   7 : (sz==2) ?  39 : (sz==4) ?  71 : 103;
3542          p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0);
3543       } else {                      // Store to memory (1,2,4,16)
3544          opc2 = (sz==1) ? 135 : (sz==2) ? 167 : (sz==4) ? 199 : 231;
3545          p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0);
3546       }
3547       goto done;
3548    }
3549
3550    case Pin_AvUnary: {
3551       UInt v_dst = vregNo(i->Pin.AvUnary.dst);
3552       UInt v_src = vregNo(i->Pin.AvUnary.src);
3553       UInt opc2;
3554       switch (i->Pin.AvUnary.op) {
3555       case Pav_MOV:       opc2 = 1156; break; // vor vD,vS,vS
3556       case Pav_NOT:       opc2 = 1284; break; // vnor vD,vS,vS
3557       case Pav_UNPCKH8S:  opc2 =  526; break; // vupkhsb
3558       case Pav_UNPCKH16S: opc2 =  590; break; // vupkhsh
3559       case Pav_UNPCKL8S:  opc2 =  654; break; // vupklsb
3560       case Pav_UNPCKL16S: opc2 =  718; break; // vupklsh
3561       case Pav_UNPCKHPIX: opc2 =  846; break; // vupkhpx
3562       case Pav_UNPCKLPIX: opc2 =  974; break; // vupklpx
3563       default:
3564          goto bad;
3565       }
3566       switch (i->Pin.AvUnary.op) {
3567       case Pav_MOV:
3568       case Pav_NOT:
3569          p = mkFormVX( p, 4, v_dst, v_src, v_src, opc2 );
3570          break;
3571       default:
3572          p = mkFormVX( p, 4, v_dst, 0, v_src, opc2 );
3573          break;
3574       }
3575       goto done;
3576    }
3577
3578    case Pin_AvBinary: {
3579       UInt v_dst  = vregNo(i->Pin.AvBinary.dst);
3580       UInt v_srcL = vregNo(i->Pin.AvBinary.srcL);
3581       UInt v_srcR = vregNo(i->Pin.AvBinary.srcR);
3582       UInt opc2;
3583       if (i->Pin.AvBinary.op == Pav_SHL) {
3584          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1036 ); // vslo
3585          p = mkFormVX( p, 4, v_dst, v_dst,  v_srcR, 452 );  // vsl
3586          goto done;
3587       }
3588       if (i->Pin.AvBinary.op == Pav_SHR) {
3589          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1100 ); // vsro
3590          p = mkFormVX( p, 4, v_dst, v_dst,  v_srcR, 708 );  // vsr
3591          goto done;
3592       }
3593       switch (i->Pin.AvBinary.op) {
3594       /* Bitwise */
3595       case Pav_AND:       opc2 = 1028; break; // vand
3596       case Pav_OR:        opc2 = 1156; break; // vor
3597       case Pav_XOR:       opc2 = 1220; break; // vxor
3598       default:
3599          goto bad;
3600       }
3601       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
3602       goto done;
3603    }
3604
3605    case Pin_AvBin8x16: {
3606       UInt v_dst  = vregNo(i->Pin.AvBin8x16.dst);
3607       UInt v_srcL = vregNo(i->Pin.AvBin8x16.srcL);
3608       UInt v_srcR = vregNo(i->Pin.AvBin8x16.srcR);
3609       UInt opc2;
3610       switch (i->Pin.AvBin8x16.op) {
3611
3612       case Pav_ADDU:     opc2 =    0; break; // vaddubm
3613       case Pav_QADDU:    opc2 =  512; break; // vaddubs
3614       case Pav_QADDS:    opc2 =  768; break; // vaddsbs
3615
3616       case Pav_SUBU:     opc2 = 1024; break; // vsububm
3617       case Pav_QSUBU:    opc2 = 1536; break; // vsububs
3618       case Pav_QSUBS:    opc2 = 1792; break; // vsubsbs
3619
3620       case Pav_OMULU:   opc2 =    8; break; // vmuloub
3621       case Pav_OMULS:   opc2 =  264; break; // vmulosb
3622       case Pav_EMULU:   opc2 =  520; break; // vmuleub
3623       case Pav_EMULS:   opc2 =  776; break; // vmulesb
3624
3625       case Pav_AVGU:     opc2 = 1026; break; // vavgub
3626       case Pav_AVGS:     opc2 = 1282; break; // vavgsb
3627       case Pav_MAXU:     opc2 =    2; break; // vmaxub
3628       case Pav_MAXS:     opc2 =  258; break; // vmaxsb
3629       case Pav_MINU:     opc2 =  514; break; // vminub
3630       case Pav_MINS:     opc2 =  770; break; // vminsb
3631
3632       case Pav_CMPEQU:   opc2 =    6; break; // vcmpequb
3633       case Pav_CMPGTU:   opc2 =  518; break; // vcmpgtub
3634       case Pav_CMPGTS:   opc2 =  774; break; // vcmpgtsb
3635
3636       case Pav_SHL:      opc2 =  260; break; // vslb
3637       case Pav_SHR:      opc2 =  516; break; // vsrb
3638       case Pav_SAR:      opc2 =  772; break; // vsrab
3639       case Pav_ROTL:     opc2 =    4; break; // vrlb
3640
3641       case Pav_MRGHI:    opc2 =   12; break; // vmrghb
3642       case Pav_MRGLO:    opc2 =  268; break; // vmrglb
3643
3644       default:
3645          goto bad;
3646       }
3647       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
3648       goto done;
3649    }
3650
3651    case Pin_AvBin16x8: {
3652       UInt v_dst  = vregNo(i->Pin.AvBin16x8.dst);
3653       UInt v_srcL = vregNo(i->Pin.AvBin16x8.srcL);
3654       UInt v_srcR = vregNo(i->Pin.AvBin16x8.srcR);
3655       UInt opc2;
3656       switch (i->Pin.AvBin16x8.op) {
3657
3658       case Pav_ADDU:    opc2 =   64; break; // vadduhm
3659       case Pav_QADDU:   opc2 =  576; break; // vadduhs
3660       case Pav_QADDS:   opc2 =  832; break; // vaddshs
3661
3662       case Pav_SUBU:    opc2 = 1088; break; // vsubuhm
3663       case Pav_QSUBU:   opc2 = 1600; break; // vsubuhs
3664       case Pav_QSUBS:   opc2 = 1856; break; // vsubshs
3665
3666       case Pav_OMULU:   opc2 =   72; break; // vmulouh
3667       case Pav_OMULS:   opc2 =  328; break; // vmulosh
3668       case Pav_EMULU:   opc2 =  584; break; // vmuleuh
3669       case Pav_EMULS:   opc2 =  840; break; // vmulesh
3670
3671       case Pav_AVGU:    opc2 = 1090; break; // vavguh
3672       case Pav_AVGS:    opc2 = 1346; break; // vavgsh
3673       case Pav_MAXU:    opc2 =   66; break; // vmaxuh
3674       case Pav_MAXS:    opc2 =  322; break; // vmaxsh
3675       case Pav_MINS:    opc2 =  834; break; // vminsh
3676       case Pav_MINU:    opc2 =  578; break; // vminuh
3677
3678       case Pav_CMPEQU:  opc2 =   70; break; // vcmpequh
3679       case Pav_CMPGTU:  opc2 =  582; break; // vcmpgtuh
3680       case Pav_CMPGTS:  opc2 =  838; break; // vcmpgtsh
3681
3682       case Pav_SHL:     opc2 =  324; break; // vslh
3683       case Pav_SHR:     opc2 =  580; break; // vsrh
3684       case Pav_SAR:     opc2 =  836; break; // vsrah
3685       case Pav_ROTL:    opc2 =   68; break; // vrlh
3686
3687       case Pav_PACKUU:  opc2 =   14; break; // vpkuhum
3688       case Pav_QPACKUU: opc2 =  142; break; // vpkuhus
3689       case Pav_QPACKSU: opc2 =  270; break; // vpkshus
3690       case Pav_QPACKSS: opc2 =  398; break; // vpkshss
3691       case Pav_PACKPXL: opc2 =  782; break; // vpkpx
3692
3693       case Pav_MRGHI:   opc2 =   76; break; // vmrghh
3694       case Pav_MRGLO:   opc2 =  332; break; // vmrglh
3695
3696       default:
3697          goto bad;
3698       }
3699       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
3700       goto done;
3701    }
3702
3703    case Pin_AvBin32x4: {
3704       UInt v_dst  = vregNo(i->Pin.AvBin32x4.dst);
3705       UInt v_srcL = vregNo(i->Pin.AvBin32x4.srcL);
3706       UInt v_srcR = vregNo(i->Pin.AvBin32x4.srcR);
3707       UInt opc2;
3708       switch (i->Pin.AvBin32x4.op) {
3709
3710       case Pav_ADDU:    opc2 =  128; break; // vadduwm
3711       case Pav_QADDU:   opc2 =  640; break; // vadduws
3712       case Pav_QADDS:   opc2 =  896; break; // vaddsws
3713
3714       case Pav_SUBU:    opc2 = 1152; break; // vsubuwm
3715       case Pav_QSUBU:   opc2 = 1664; break; // vsubuws
3716       case Pav_QSUBS:   opc2 = 1920; break; // vsubsws
3717
3718       case Pav_AVGU:    opc2 = 1154; break; // vavguw
3719       case Pav_AVGS:    opc2 = 1410; break; // vavgsw
3720
3721       case Pav_MAXU:    opc2 =  130; break; // vmaxuw
3722       case Pav_MAXS:    opc2 =  386; break; // vmaxsw
3723
3724       case Pav_MINS:    opc2 =  898; break; // vminsw
3725       case Pav_MINU:    opc2 =  642; break; // vminuw
3726
3727       case Pav_CMPEQU:  opc2 =  134; break; // vcmpequw
3728       case Pav_CMPGTS:  opc2 =  902; break; // vcmpgtsw
3729       case Pav_CMPGTU:  opc2 =  646; break; // vcmpgtuw
3730
3731       case Pav_SHL:     opc2 =  388; break; // vslw
3732       case Pav_SHR:     opc2 =  644; break; // vsrw
3733       case Pav_SAR:     opc2 =  900; break; // vsraw
3734       case Pav_ROTL:    opc2 =  132; break; // vrlw
3735
3736       case Pav_PACKUU:  opc2 =   78; break; // vpkuwum
3737       case Pav_QPACKUU: opc2 =  206; break; // vpkuwus
3738       case Pav_QPACKSU: opc2 =  334; break; // vpkswus
3739       case Pav_QPACKSS: opc2 =  462; break; // vpkswss
3740
3741       case Pav_MRGHI:   opc2 =  140; break; // vmrghw
3742       case Pav_MRGLO:   opc2 =  396; break; // vmrglw
3743
3744       default:
3745          goto bad;
3746       }
3747       p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 );
3748       goto done;
3749    }
3750
3751    case Pin_AvBin32Fx4: {
3752       UInt v_dst  = vregNo(i->Pin.AvBin32Fx4.dst);
3753       UInt v_srcL = vregNo(i->Pin.AvBin32Fx4.srcL);
3754       UInt v_srcR = vregNo(i->Pin.AvBin32Fx4.srcR);
3755       switch (i->Pin.AvBin32Fx4.op) {
3756
3757       case Pavfp_ADDF:
3758          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 10 );   // vaddfp
3759          break;
3760       case Pavfp_SUBF:
3761          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 74 );   // vsubfp
3762          break;
3763       case Pavfp_MAXF:
3764          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1034 ); // vmaxfp
3765          break;
3766       case Pavfp_MINF:
3767          p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1098 ); // vminfp
3768          break;
3769
3770       case Pavfp_MULF: {
3771          /* Make a vmulfp from a vmaddfp:
3772             load -0.0 (0x8000_0000) to each 32-bit word of vB
3773             this makes the add a noop.
3774          */
3775          UInt vB = 29;  // XXX: Using v29 for temp do not change
3776                         // without also changing
3777                         // getRegUsage_PPCInstr
3778          UInt konst = 0x1F;
3779
3780          // Better way to load -0.0 (0x80000000) ?
3781          // vspltisw vB,0x1F   (0x1F => each word of vB)
3782          p = mkFormVX( p, 4, vB, konst, 0, 908 );
3783
3784          // vslw vB,vB,vB (each word of vB = (0x1F << 0x1F) = 0x80000000
3785          p = mkFormVX( p, 4, vB, vB, vB, 388 );
3786
3787          // Finally, do the multiply:
3788          p = mkFormVA( p, 4, v_dst, v_srcL, vB, v_srcR, 46 );
3789          break;
3790       }
3791       case Pavfp_CMPEQF:  // vcmpeqfp
3792          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 198 );
3793          break;
3794       case Pavfp_CMPGTF:  // vcmpgtfp
3795          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 710 );
3796          break;
3797       case Pavfp_CMPGEF:  // vcmpgefp
3798          p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 454 );
3799          break;
3800
3801       default:
3802          goto bad;
3803       }
3804       goto done;
3805    }
3806
3807    case Pin_AvUn32Fx4: {
3808       UInt v_dst = vregNo(i->Pin.AvUn32Fx4.dst);
3809       UInt v_src = vregNo(i->Pin.AvUn32Fx4.src);
3810       UInt opc2;
3811       switch (i->Pin.AvUn32Fx4.op) {
3812       case Pavfp_RCPF:    opc2 =  266; break; // vrefp
3813       case Pavfp_RSQRTF:  opc2 =  330; break; // vrsqrtefp
3814       case Pavfp_CVTU2F:  opc2 =  778; break; // vcfux
3815       case Pavfp_CVTS2F:  opc2 =  842; break; // vcfsx
3816       case Pavfp_QCVTF2U: opc2 =  906; break; // vctuxs
3817       case Pavfp_QCVTF2S: opc2 =  970; break; // vctsxs
3818       case Pavfp_ROUNDM:  opc2 =  714; break; // vrfim
3819       case Pavfp_ROUNDP:  opc2 =  650; break; // vrfip
3820       case Pavfp_ROUNDN:  opc2 =  522; break; // vrfin
3821       case Pavfp_ROUNDZ:  opc2 =  586; break; // vrfiz
3822       default:
3823          goto bad;
3824       }
3825       p = mkFormVX( p, 4, v_dst, 0, v_src, opc2 );
3826       goto done;
3827    }
3828
3829    case Pin_AvPerm: {  // vperm
3830       UInt v_dst  = vregNo(i->Pin.AvPerm.dst);
3831       UInt v_srcL = vregNo(i->Pin.AvPerm.srcL);
3832       UInt v_srcR = vregNo(i->Pin.AvPerm.srcR);
3833       UInt v_ctl  = vregNo(i->Pin.AvPerm.ctl);
3834       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 43 );
3835       goto done;
3836    }
3837
3838    case Pin_AvSel: {  // vsel
3839       UInt v_ctl  = vregNo(i->Pin.AvSel.ctl);
3840       UInt v_dst  = vregNo(i->Pin.AvSel.dst);
3841       UInt v_srcL = vregNo(i->Pin.AvSel.srcL);
3842       UInt v_srcR = vregNo(i->Pin.AvSel.srcR);
3843       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 42 );
3844       goto done;
3845    }
3846
3847    case Pin_AvShlDbl: {  // vsldoi
3848       UInt shift  = i->Pin.AvShlDbl.shift;
3849       UInt v_dst  = vregNo(i->Pin.AvShlDbl.dst);
3850       UInt v_srcL = vregNo(i->Pin.AvShlDbl.srcL);
3851       UInt v_srcR = vregNo(i->Pin.AvShlDbl.srcR);
3852       vassert(shift <= 0xF);
3853       p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, shift, 44 );
3854       goto done;
3855    }
3856
3857    case Pin_AvSplat: { // vsplt(is)(b,h,w)
3858       UInt v_dst = vregNo(i->Pin.AvShlDbl.dst);
3859       UChar sz   = i->Pin.AvSplat.sz;
3860       UInt v_src, opc2;
3861       vassert(sz == 8 || sz == 16 || sz == 32);
3862
3863       if (i->Pin.AvSplat.src->tag == Pvi_Imm) {
3864          Char simm5;
3865          opc2 = (sz == 8) ? 780 : (sz == 16) ? 844 : 908;   // 8,16,32
3866          /* expects 5-bit-signed-imm */
3867          simm5 = i->Pin.AvSplat.src->Pvi.Imm5s;
3868          vassert(simm5 >= -16 && simm5 <= 15);
3869          simm5 = simm5 & 0x1F;
3870          p = mkFormVX( p, 4, v_dst, (UInt)simm5, 0, opc2 );
3871       }
3872       else {  // Pri_Reg
3873          UInt lowest_lane;
3874          opc2 = (sz == 8) ? 524 : (sz == 16) ? 588 : 652;  // 8,16,32
3875          vassert(hregClass(i->Pin.AvSplat.src->Pvi.Reg) == HRcVec128);
3876          v_src = vregNo(i->Pin.AvSplat.src->Pvi.Reg);
3877          lowest_lane = (128/sz)-1;
3878          p = mkFormVX( p, 4, v_dst, lowest_lane, v_src, opc2 );
3879       }
3880       goto done;
3881    }
3882
3883    case Pin_AvCMov: {
3884       UInt v_dst     = vregNo(i->Pin.AvCMov.dst);
3885       UInt v_src     = vregNo(i->Pin.AvCMov.src);
3886       PPCCondCode cc = i->Pin.AvCMov.cond;
3887
3888       if (v_dst == v_src) goto done;
3889       
3890       vassert(cc.test != Pct_ALWAYS);
3891
3892       /* jmp fwds 2 insns if !condition */
3893       if (cc.test != Pct_ALWAYS) {
3894          /* bc !ct,cf,n_bytes>>2 */
3895          p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0);
3896       }
3897       /* vmr */
3898       p = mkFormVX( p, 4, v_dst, v_src, v_src, 1156 );
3899       goto done;
3900    }
3901
3902    case Pin_AvLdVSCR: {  // mtvscr
3903       UInt v_src = vregNo(i->Pin.AvLdVSCR.src);
3904       p = mkFormVX( p, 4, 0, 0, v_src, 1604 );
3905       goto done;
3906    }
3907
3908    default: 
3909       goto bad;
3910    }
3911
3912   bad:
3913    vex_printf("\n=> ");
3914    ppPPCInstr(i, mode64);
3915    vpanic("emit_PPCInstr");
3916    /*NOTREACHED*/
3917    
3918   done:
3919    vassert(p - &buf[0] <= 32);
3920    return p - &buf[0];
3921 }
3922
3923 /*---------------------------------------------------------------*/
3924 /*--- end                                     host_ppc_defs.c ---*/
3925 /*---------------------------------------------------------------*/