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