1bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
2bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------------*/
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin                                   host_ppc_isel.c ---*/
4bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------------*/
5bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj   framework.
9bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
1089ae8477745fd2a15453557d729a50e627325ee2sewardj   Copyright (C) 2004-2013 OpenWorks LLP
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj      info@open-works.net
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is free software; you can redistribute it and/or
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj   modify it under the terms of the GNU General Public License as
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj   published by the Free Software Foundation; either version 2 of the
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj   License, or (at your option) any later version.
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is distributed in the hope that it will be useful, but
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj   General Public License for more details.
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj   You should have received a copy of the GNU General Public License
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj   along with this program; if not, write to the Free Software
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj   The GNU General Public License is contained in the file COPYING.
29bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
30bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   Neither the names of the U.S. Department of Energy nor the
31bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   University of California nor the names of its contributors may be
32bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   used to endorse or promote products derived from this software
33bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   without prior written permission.
34bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion*/
35bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
36bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion#include "libvex_basictypes.h"
37bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion#include "libvex_ir.h"
38bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion#include "libvex.h"
39bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
40cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "ir_match.h"
41cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h"
42cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_globals.h"
43cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_generic_regs.h"
444c96e61dd85c172b999d6afc88ce6640aeba9962sewardj#include "host_generic_simd64.h"
45cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_ppc_defs.h"
46b4a632abca53a38f081968ddbe9cfeb971635b90cerion
474628ccd1bafb946378f91849b92ffcfea0267b2ecerion/* GPR register class for ppc32/64 */
48a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj#define HRcGPR(_mode64) ((_mode64) ? HRcInt64 : HRcInt32)
49f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
50f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
51b4a632abca53a38f081968ddbe9cfeb971635b90cerion/*---------------------------------------------------------*/
52b4a632abca53a38f081968ddbe9cfeb971635b90cerion/*--- Register Usage Conventions                        ---*/
53b4a632abca53a38f081968ddbe9cfeb971635b90cerion/*---------------------------------------------------------*/
54b4a632abca53a38f081968ddbe9cfeb971635b90cerion/*
55b4a632abca53a38f081968ddbe9cfeb971635b90cerion  Integer Regs
56b4a632abca53a38f081968ddbe9cfeb971635b90cerion  ------------
57b4a632abca53a38f081968ddbe9cfeb971635b90cerion  GPR0       Reserved
58b4a632abca53a38f081968ddbe9cfeb971635b90cerion  GPR1       Stack Pointer
59f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  GPR2       not used - TOC pointer
60f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  GPR3:10    Allocateable
61f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  GPR11      if mode64: not used - calls by ptr / env ptr for some langs
62f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  GPR12      if mode64: not used - exceptions / global linkage code
63f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  GPR13      not used - Thread-specific pointer
64a5e5f5f4a474e67d2734d4d4129ffea745dfa1d2sewardj  GPR14:28   Allocateable
65a5e5f5f4a474e67d2734d4d4129ffea745dfa1d2sewardj  GPR29      Unused by us (reserved for the dispatcher)
66e21595a704c11ce19b8cd73df03fdcbe483517eecerion  GPR30      AltiVec temp spill register
67b4a632abca53a38f081968ddbe9cfeb971635b90cerion  GPR31      GuestStatePointer
68b4a632abca53a38f081968ddbe9cfeb971635b90cerion
69b4a632abca53a38f081968ddbe9cfeb971635b90cerion  Of Allocateable regs:
70f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  if (mode64)
71f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion    GPR3:10  Caller-saved regs
72f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  else
73f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion    GPR3:12  Caller-saved regs
74e21595a704c11ce19b8cd73df03fdcbe483517eecerion  GPR14:29   Callee-saved regs
75b4a632abca53a38f081968ddbe9cfeb971635b90cerion
76a56e9cc23be921deeebd9df13b427b63aa661aaccerion  GPR3       [Return | Parameter] - carrying reg
77a56e9cc23be921deeebd9df13b427b63aa661aaccerion  GPR4:10    Parameter-carrying regs
78b4a632abca53a38f081968ddbe9cfeb971635b90cerion
79b4a632abca53a38f081968ddbe9cfeb971635b90cerion
80b4a632abca53a38f081968ddbe9cfeb971635b90cerion  Floating Point Regs
81b4a632abca53a38f081968ddbe9cfeb971635b90cerion  -------------------
82b4a632abca53a38f081968ddbe9cfeb971635b90cerion  FPR0:31    Allocateable
83b4a632abca53a38f081968ddbe9cfeb971635b90cerion
84f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  FPR0       Caller-saved - scratch reg
85f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  if (mode64)
86f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion    FPR1:13  Caller-saved - param & return regs
87f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  else
88f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion    FPR1:8   Caller-saved - param & return regs
89f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion    FPR9:13  Caller-saved regs
90f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  FPR14:31   Callee-saved regs
91f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
92f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
93f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  Vector Regs (on processors with the VMX feature)
94f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  -----------
95f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  VR0-VR1    Volatile scratch registers
96f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  VR2-VR13   Volatile vector parameters registers
97f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  VR14-VR19  Volatile scratch registers
98f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  VR20-VR31  Non-volatile registers
99f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion  VRSAVE     Non-volatile 32-bit register
100b4a632abca53a38f081968ddbe9cfeb971635b90cerion*/
101b4a632abca53a38f081968ddbe9cfeb971635b90cerion
102094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
103094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
1045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion/*--- PPC FP Status & Control Register Conventions      ---*/
105094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
106094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*
107094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion  Vex-generated code expects to run with the FPU set as follows: all
108fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  exceptions masked.  The rounding mode is set appropriately before
109fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  each floating point insn emitted (or left unchanged if known to be
110fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  correct already).  There are a few fp insns (fmr,fneg,fabs,fnabs),
111fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  which are unaffected by the rm and so the rounding mode is not set
112fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  prior to them.
113fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
114fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  At least on MPC7447A (Mac Mini), frsqrte is also not affected by
115fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  rounding mode.  At some point the ppc docs get sufficiently vague
116fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj  that the only way to find out is to write test programs.
117fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj*/
118fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj/* Notes on the FP instruction set, 6 Feb 06.
119fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
120fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjWhat                 exns -> CR1 ?   Sets FPRF ?   Observes RM ?
121fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj-------------------------------------------------------------
122fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
123fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmr[.]                   if .             n             n
124fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfneg[.]                  if .             n             n
125fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfabs[.]                  if .             n             n
126fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfnabs[.]                 if .             n             n
127fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
128fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfadd[.]                  if .             y             y
129fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfadds[.]                 if .             y             y
13066d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardjfcfid[.] (Si64->dbl)     if .             y             y
13166d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardjfcfidU[.] (Ui64->dbl)    if .             y             y
13266d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardjfcfids[.] (Si64->sngl)   if .             Y             Y
13366d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardjfcfidus[.] (Ui64->sngl)  if .             Y             Y
134fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfcmpo (cmp, result       n                n             n
135fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfcmpu  to crfD)          n                n             n
136fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfctid[.]  (dbl->i64)     if .       ->undef             y
137fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfctidz[.] (dbl->i64)     if .       ->undef    rounds-to-zero
138fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfctiw[.]  (dbl->i32)     if .       ->undef             y
139fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfctiwz[.] (dbl->i32)     if .       ->undef    rounds-to-zero
140fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfdiv[.]                  if .             y             y
141fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfdivs[.]                 if .             y             y
142fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmadd[.]                 if .             y             y
143fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmadds[.]                if .             y             y
144fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmsub[.]                 if .             y             y
145fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmsubs[.]                if .             y             y
146fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmul[.]                  if .             y             y
147fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfmuls[.]                 if .             y             y
148fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
149fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj(note: for fnm*, rounding happens before final negation)
150fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfnmadd[.]                if .             y             y
151fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfnmadds[.]               if .             y             y
152fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfnmsub[.]                if .             y             y
153fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfnmsubs[.]               if .             y             y
154fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
155fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfre[.]                   if .             y             y
156fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfres[.]                  if .             y             y
157fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
158fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfrsqrte[.]               if .             y       apparently not
159fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
160fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfsqrt[.]                 if .             y             y
161fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfsqrts[.]                if .             y             y
162fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfsub[.]                  if .             y             y
163fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfsubs[.]                 if .             y             y
164fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
165fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
166fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjfpscr: bits 30-31 (ibm) is RM
167fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj            24-29 (ibm) are exnmasks/non-IEEE bit, all zero
168fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj	    15-19 (ibm) is FPRF: class, <, =, >, UNord
169fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
170fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjppc fe(guest) makes fpscr read as all zeros except RM (and maybe FPRF
171fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjin future)
172fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
173fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmcrfs     - move fpscr field to CR field
174fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmtfsfi[.] - 4 bit imm moved to fpscr field
175fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmtfsf[.]  - move frS[low 1/2] to fpscr but using 8-bit field mask
176fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmtfsb1[.] - set given fpscr bit
177fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmtfsb0[.] - clear given fpscr bit
178fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmffs[.]   - move all fpscr to frD[low 1/2]
179fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
180fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjFor [.] presumably cr1 is set with exn summary bits, as per
181fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjmain FP insns
182fa7fc6b6054d36758da783cc9f8e8bb3539620absewardj
183fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjA single precision store truncates/denormalises the in-register value,
184fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjbut does not round it.  This is so that flds followed by fsts is
185fa7fc6b6054d36758da783cc9f8e8bb3539620absewardjalways the identity.
186094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion*/
187cd304497d9d869f9b24a002299d3953ee072229bcerion
188cd304497d9d869f9b24a002299d3953ee072229bcerion
189cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
190cd304497d9d869f9b24a002299d3953ee072229bcerion/*--- misc helpers                                      ---*/
191cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
192cd304497d9d869f9b24a002299d3953ee072229bcerion
193d0eae2d5b6d8224bf1f075098e044b23ecffd9aecerion/* These are duplicated in guest-ppc/toIR.c */
194cd304497d9d869f9b24a002299d3953ee072229bcerionstatic IRExpr* unop ( IROp op, IRExpr* a )
195cd304497d9d869f9b24a002299d3953ee072229bcerion{
196cd304497d9d869f9b24a002299d3953ee072229bcerion   return IRExpr_Unop(op, a);
197cd304497d9d869f9b24a002299d3953ee072229bcerion}
198cd304497d9d869f9b24a002299d3953ee072229bcerion
1998ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerionstatic IRExpr* mkU32 ( UInt i )
2008ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion{
2018ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion   return IRExpr_Const(IRConst_U32(i));
2028ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion}
203cd304497d9d869f9b24a002299d3953ee072229bcerion
204cd304497d9d869f9b24a002299d3953ee072229bcerionstatic IRExpr* bind ( Int binder )
205cd304497d9d869f9b24a002299d3953ee072229bcerion{
206cd304497d9d869f9b24a002299d3953ee072229bcerion   return IRExpr_Binder(binder);
207cd304497d9d869f9b24a002299d3953ee072229bcerion}
208cd304497d9d869f9b24a002299d3953ee072229bcerion
209009230b9758291b594e60d7c0243a73d53e81854sewardjstatic Bool isZeroU8 ( IRExpr* e )
210009230b9758291b594e60d7c0243a73d53e81854sewardj{
211009230b9758291b594e60d7c0243a73d53e81854sewardj   return e->tag == Iex_Const
212009230b9758291b594e60d7c0243a73d53e81854sewardj          && e->Iex.Const.con->tag == Ico_U8
213009230b9758291b594e60d7c0243a73d53e81854sewardj          && e->Iex.Const.con->Ico.U8 == 0;
214009230b9758291b594e60d7c0243a73d53e81854sewardj}
215009230b9758291b594e60d7c0243a73d53e81854sewardj
216cd304497d9d869f9b24a002299d3953ee072229bcerion
217bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
218bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- ISelEnv                                           ---*/
219bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
220bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
221bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/* This carries around:
222bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
223bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   - A mapping from IRTemp to IRType, giving the type of any IRTemp we
224bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion     might encounter.  This is computed before insn selection starts,
225bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion     and does not change.
226bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
227bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   - A mapping from IRTemp to HReg.  This tells the insn selector
228bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion     which virtual register(s) are associated with each IRTemp
2293dee849ec7c38746749065e67dc53b75daa7617dsewardj     temporary.  This is computed before insn selection starts, and
2303dee849ec7c38746749065e67dc53b75daa7617dsewardj     does not change.  We expect this mapping to map precisely the
2313dee849ec7c38746749065e67dc53b75daa7617dsewardj     same set of IRTemps as the type mapping does.
232bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
2333dee849ec7c38746749065e67dc53b75daa7617dsewardj         - vregmapLo    holds the primary register for the IRTemp.
2343dee849ec7c38746749065e67dc53b75daa7617dsewardj         - vregmapMedLo holds the secondary register for the IRTemp,
2357c6dbff15934256b028a69e906cd3f80275c84absewardj              if any is needed.  That's only for Ity_I64 temps
2367c6dbff15934256b028a69e906cd3f80275c84absewardj              in 32 bit mode or Ity_I128 temps in 64-bit mode.
2373dee849ec7c38746749065e67dc53b75daa7617dsewardj         - vregmapMedHi is only for dealing with Ity_I128 temps in
2383dee849ec7c38746749065e67dc53b75daa7617dsewardj              32 bit mode.  It holds bits 95:64 (Intel numbering)
2393dee849ec7c38746749065e67dc53b75daa7617dsewardj              of the IRTemp.
2403dee849ec7c38746749065e67dc53b75daa7617dsewardj         - vregmapHi is also only for dealing with Ity_I128 temps
2413dee849ec7c38746749065e67dc53b75daa7617dsewardj              in 32 bit mode.  It holds the most significant bits
2423dee849ec7c38746749065e67dc53b75daa7617dsewardj              (127:96 in Intel numbering) of the IRTemp.
2437f000af9c21e3b5059e0b2d26bcb9ca378ae0e54cerion
244bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion    - The code array, that is, the insns selected so far.
245bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
246bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion    - A counter, for generating new virtual registers.
247bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
248bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion    - The host subarchitecture we are selecting insns for.
249bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      This is set at the start and does not change.
250bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
2514628ccd1bafb946378f91849b92ffcfea0267b2ecerion    - A Bool to tell us if the host is 32 or 64bit.
2524628ccd1bafb946378f91849b92ffcfea0267b2ecerion      This is set at the start and does not change.
2534628ccd1bafb946378f91849b92ffcfea0267b2ecerion
254b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    - An IRExpr*, which may be NULL, holding the IR expression (an
255b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      IRRoundingMode-encoded value) to which the FPU's rounding mode
256b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      was most recently set.  Setting to NULL is always safe.  Used to
257b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      avoid redundant settings of the FPU's rounding mode, as
258b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      described in set_FPU_rounding_mode below.
259aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj
260aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj    - A VexMiscInfo*, needed for knowing how to generate
2613dee849ec7c38746749065e67dc53b75daa7617dsewardj      function calls for this target.
2623dee849ec7c38746749065e67dc53b75daa7617dsewardj
2633dee849ec7c38746749065e67dc53b75daa7617dsewardj    - The maximum guest address of any guest insn in this block.
2643dee849ec7c38746749065e67dc53b75daa7617dsewardj      Actually, the address of the highest-addressed byte from any
2653dee849ec7c38746749065e67dc53b75daa7617dsewardj      insn in this block.  Is set at the start and does not change.
2663dee849ec7c38746749065e67dc53b75daa7617dsewardj      This is used for detecting jumps which are definitely
2673dee849ec7c38746749065e67dc53b75daa7617dsewardj      forward-edges from this block, and therefore can be made
2683dee849ec7c38746749065e67dc53b75daa7617dsewardj      (chained) to the fast entry point of the destination, thereby
2693dee849ec7c38746749065e67dc53b75daa7617dsewardj      avoiding the destination's event check.
270bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion*/
271bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
272bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fceriontypedef
273bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   struct {
2743dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Constant -- are set at the start and do not change. */
275c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      IRTypeEnv* type_env;
276c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                              //    64-bit mode              32-bit mode
277c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg*    vregmapLo;     // Low 64-bits [63:0]    Low 32-bits     [31:0]
278c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg*    vregmapMedLo;  // high 64-bits[127:64]  Next 32-bits    [63:32]
279c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg*    vregmapMedHi;  // unused                Next 32-bits    [95:64]
280c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg*    vregmapHi;     // unused                highest 32-bits [127:96]
281c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      Int      n_vregmap;
282c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
2835117ce116f47141cb23d1b49cc826e19323add97sewardj      /* 27 Jan 06: Not currently used, but should be */
2845117ce116f47141cb23d1b49cc826e19323add97sewardj      UInt         hwcaps;
2854628ccd1bafb946378f91849b92ffcfea0267b2ecerion
2864628ccd1bafb946378f91849b92ffcfea0267b2ecerion      Bool         mode64;
287b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
288d8c64e082224b2e688abdef9219cc76fd82b373bflorian      const VexAbiInfo*  vbi;   // unused
2893dee849ec7c38746749065e67dc53b75daa7617dsewardj
2903dee849ec7c38746749065e67dc53b75daa7617dsewardj      Bool         chainingAllowed;
2913dee849ec7c38746749065e67dc53b75daa7617dsewardj      Addr64       max_ga;
2923dee849ec7c38746749065e67dc53b75daa7617dsewardj
2933dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* These are modified as we go along. */
2943dee849ec7c38746749065e67dc53b75daa7617dsewardj      HInstrArray* code;
2953dee849ec7c38746749065e67dc53b75daa7617dsewardj      Int          vreg_ctr;
2963dee849ec7c38746749065e67dc53b75daa7617dsewardj
2973dee849ec7c38746749065e67dc53b75daa7617dsewardj      IRExpr*      previous_rm;
298bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
299bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   ISelEnv;
300bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
301bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
302bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerionstatic HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp )
303bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion{
304bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   vassert(tmp >= 0);
305bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   vassert(tmp < env->n_vregmap);
306c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   return env->vregmapLo[tmp];
307bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
308cd304497d9d869f9b24a002299d3953ee072229bcerion
3092bb062db199d9799e1259ab608e8a1aea3bb29a3sewardjstatic void lookupIRTempPair ( HReg* vrHI, HReg* vrLO,
3102bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                               ISelEnv* env, IRTemp tmp )
311b536af93912b69421440c27aa0533ad77d678f85cerion{
312c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(tmp >= 0);
313c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(tmp < env->n_vregmap);
31479efdc6ea93db174395af845d4e21a4a7ad600ccflorian   vassert(! hregIsInvalid(env->vregmapMedLo[tmp]));
315c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   *vrLO = env->vregmapLo[tmp];
316c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   *vrHI = env->vregmapMedLo[tmp];
317c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
318c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
319c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* Only for used in 32-bit mode */
320c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void lookupIRTempQuad ( HReg* vrHi, HReg* vrMedHi, HReg* vrMedLo,
321c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                               HReg* vrLo, ISelEnv* env, IRTemp tmp )
322c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
3234628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(!env->mode64);
324f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(tmp >= 0);
325f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(tmp < env->n_vregmap);
32679efdc6ea93db174395af845d4e21a4a7ad600ccflorian   vassert(! hregIsInvalid(env->vregmapMedLo[tmp]));
327c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   *vrHi    = env->vregmapHi[tmp];
328c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   *vrMedHi = env->vregmapMedHi[tmp];
329c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   *vrMedLo = env->vregmapMedLo[tmp];
330c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   *vrLo    = env->vregmapLo[tmp];
331f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
332f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3335b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void addInstr ( ISelEnv* env, PPCInstr* instr )
334cd304497d9d869f9b24a002299d3953ee072229bcerion{
335cd304497d9d869f9b24a002299d3953ee072229bcerion   addHInstr(env->code, instr);
336cd304497d9d869f9b24a002299d3953ee072229bcerion   if (vex_traceflags & VEX_TRACE_VCODE) {
3374628ccd1bafb946378f91849b92ffcfea0267b2ecerion      ppPPCInstr(instr, env->mode64);
338cd304497d9d869f9b24a002299d3953ee072229bcerion      vex_printf("\n");
339cd304497d9d869f9b24a002299d3953ee072229bcerion   }
340cd304497d9d869f9b24a002299d3953ee072229bcerion}
341cd304497d9d869f9b24a002299d3953ee072229bcerion
342cd304497d9d869f9b24a002299d3953ee072229bcerionstatic HReg newVRegI ( ISelEnv* env )
343a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{
344a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   HReg reg
345a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      = mkHReg(True/*vreg*/, HRcGPR(env->mode64), 0/*enc*/, env->vreg_ctr);
346cd304497d9d869f9b24a002299d3953ee072229bcerion   env->vreg_ctr++;
347cd304497d9d869f9b24a002299d3953ee072229bcerion   return reg;
348cd304497d9d869f9b24a002299d3953ee072229bcerion}
349cd304497d9d869f9b24a002299d3953ee072229bcerion
350094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerionstatic HReg newVRegF ( ISelEnv* env )
351094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
352a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   HReg reg = mkHReg(True/*vreg*/, HRcFlt64, 0/*enc*/, env->vreg_ctr);
353094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   env->vreg_ctr++;
354094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   return reg;
355094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
356094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
357e21595a704c11ce19b8cd73df03fdcbe483517eecerionstatic HReg newVRegV ( ISelEnv* env )
358e21595a704c11ce19b8cd73df03fdcbe483517eecerion{
359a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   HReg reg = mkHReg(True/*vreg*/, HRcVec128, 0/*enc*/, env->vreg_ctr);
360e21595a704c11ce19b8cd73df03fdcbe483517eecerion   env->vreg_ctr++;
361e21595a704c11ce19b8cd73df03fdcbe483517eecerion   return reg;
362e21595a704c11ce19b8cd73df03fdcbe483517eecerion}
363cd304497d9d869f9b24a002299d3953ee072229bcerion
364cd304497d9d869f9b24a002299d3953ee072229bcerion
365cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
366cd304497d9d869f9b24a002299d3953ee072229bcerion/*--- ISEL: Forward declarations                        ---*/
367cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
368cd304497d9d869f9b24a002299d3953ee072229bcerion
369cd304497d9d869f9b24a002299d3953ee072229bcerion/* These are organised as iselXXX and iselXXX_wrk pairs.  The
370cd304497d9d869f9b24a002299d3953ee072229bcerion   iselXXX_wrk do the real work, but are not to be called directly.
371cd304497d9d869f9b24a002299d3953ee072229bcerion   For each XXX, iselXXX calls its iselXXX_wrk counterpart, then
372cd304497d9d869f9b24a002299d3953ee072229bcerion   checks that all returned registers are virtual.  You should not
373cd304497d9d869f9b24a002299d3953ee072229bcerion   call the _wrk version directly.
374b51f0f4f33256638ed953156a2635aa739b232f1sewardj
3752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   'Word' refers to the size of the native machine word, that is,
3762bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   32-bit int in 32-bit mode and 64-bit int in 64-bit mode.  '2Word'
3772bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   therefore refers to a double-width (64/128-bit) quantity in two
3782bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   integer registers.
3792bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj*/
3802bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode: compute an I8/I16/I32 into a GPR.
3812bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   64-bit mode: compute an I8/I16/I32/I64 into a GPR. */
3821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e,
3831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          IREndness IEndianess );
3841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselWordExpr_R     ( ISelEnv* env, IRExpr* e,
3851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          IREndness IEndianess );
3862bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
3872bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode: Compute an I8/I16/I32 into a RH
3882bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                (reg-or-halfword-immediate).
3892bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   64-bit mode: Compute an I8/I16/I32/I64 into a RH
3902bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                (reg-or-halfword-immediate).
3912bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   It's important to specify whether the immediate is to be regarded
3922bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   as signed or not.  If yes, this will never return -32768 as an
393b51f0f4f33256638ed953156a2635aa739b232f1sewardj   immediate; this guaranteed that all signed immediates that are
3942bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   return can have their sign inverted if need be.
3952bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj*/
3962bb062db199d9799e1259ab608e8a1aea3bb29a3sewardjstatic PPCRH*        iselWordExpr_RH_wrk ( ISelEnv* env,
3971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           Bool syned, IRExpr* e,
3981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           IREndness IEndianess );
3992bb062db199d9799e1259ab608e8a1aea3bb29a3sewardjstatic PPCRH*        iselWordExpr_RH     ( ISelEnv* env,
4001f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           Bool syned, IRExpr* e,
4011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           IREndness IEndianess );
4022bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
4032bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode: compute an I32 into a RI (reg or 32-bit immediate).
4042bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   64-bit mode: compute an I64 into a RI (reg or 64-bit immediate). */
4051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRI*        iselWordExpr_RI_wrk ( ISelEnv* env, IRExpr* e,
4061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           IREndness IEndianess );
4071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRI*        iselWordExpr_RI     ( ISelEnv* env, IRExpr* e,
4081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           IREndness IEndianess );
4092bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
4102bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* In 32 bit mode ONLY, compute an I8 into a
4112bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   reg-or-5-bit-unsigned-immediate, the latter being an immediate in
4122bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   the range 1 .. 31 inclusive.  Used for doing shift amounts. */
4131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH*        iselWordExpr_RH5u_wrk ( ISelEnv* env, IRExpr* e,
4141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                             IREndness IEndianess );
4151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH*        iselWordExpr_RH5u     ( ISelEnv* env, IRExpr* e,
4161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                             IREndness IEndianess );
4172bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
41834085e398dd703798a0d6a60e039075e03397c8fsewardj/* In 64-bit mode ONLY, compute an I8 into a
4192bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   reg-or-6-bit-unsigned-immediate, the latter being an immediate in
4202bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   the range 1 .. 63 inclusive.  Used for doing shift amounts. */
4211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH*        iselWordExpr_RH6u_wrk ( ISelEnv* env, IRExpr* e,
4221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                             IREndness IEndianess );
4231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH*        iselWordExpr_RH6u     ( ISelEnv* env, IRExpr* e,
4241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                             IREndness IEndianess );
4252bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
4262bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode: compute an I32 into an AMode.
42734085e398dd703798a0d6a60e039075e03397c8fsewardj   64-bit mode: compute an I64 into an AMode.
42834085e398dd703798a0d6a60e039075e03397c8fsewardj
42934085e398dd703798a0d6a60e039075e03397c8fsewardj   Requires to know (xferTy) the type of data to be loaded/stored
43034085e398dd703798a0d6a60e039075e03397c8fsewardj   using this amode.  That is so that, for 64-bit code generation, any
43134085e398dd703798a0d6a60e039075e03397c8fsewardj   PPCAMode_IR returned will have an index (immediate offset) field
43234085e398dd703798a0d6a60e039075e03397c8fsewardj   that is guaranteed to be 4-aligned, if there is any chance that the
43334085e398dd703798a0d6a60e039075e03397c8fsewardj   amode is to be used in ld/ldu/lda/std/stdu.
43434085e398dd703798a0d6a60e039075e03397c8fsewardj
43534085e398dd703798a0d6a60e039075e03397c8fsewardj   Since there are no such restrictions on 32-bit insns, xferTy is
43634085e398dd703798a0d6a60e039075e03397c8fsewardj   ignored for 32-bit code generation. */
4371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCAMode*     iselWordExpr_AMode_wrk ( ISelEnv* env, IRExpr* e,
4381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IRType xferTy,
4391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IREndness IEndianess );
4401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCAMode*     iselWordExpr_AMode     ( ISelEnv* env, IRExpr* e,
4411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IRType xferTy,
4421f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IREndness IEndianess );
4432bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
444c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselInt128Expr_to_32x4_wrk ( HReg* rHi, HReg* rMedHi,
445c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                         HReg* rMedLo, HReg* rLo,
4461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         ISelEnv* env, IRExpr* e,
4471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
448c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselInt128Expr_to_32x4     ( HReg* rHi, HReg* rMedHi,
449c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                         HReg* rMedLo, HReg* rLo,
4501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         ISelEnv* env, IRExpr* e,
4511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
452c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
453c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4542bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode ONLY: compute an I64 into a GPR pair. */
4551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void          iselInt64Expr_wrk ( HReg* rHi, HReg* rLo,
4561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         ISelEnv* env, IRExpr* e,
4571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
4581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void          iselInt64Expr     ( HReg* rHi, HReg* rLo,
4591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         ISelEnv* env, IRExpr* e,
4601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
461cd304497d9d869f9b24a002299d3953ee072229bcerion
4622bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 64-bit mode ONLY: compute an I128 into a GPR64 pair. */
463f0de28cf1a762b0d6f74c93d3532c89a230673bbcerionstatic void          iselInt128Expr_wrk ( HReg* rHi, HReg* rLo,
4641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          ISelEnv* env, IRExpr* e,
4651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          IREndness IEndianess );
4661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
467f0de28cf1a762b0d6f74c93d3532c89a230673bbcerionstatic void          iselInt128Expr     ( HReg* rHi, HReg* rLo,
4681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          ISelEnv* env, IRExpr* e,
4691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          IREndness IEndianess );
470f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
4711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCCondCode   iselCondCode_wrk ( ISelEnv* env, IRExpr* e,
4721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IREndness IEndianess );
4731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCCondCode   iselCondCode     ( ISelEnv* env, IRExpr* e,
4741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IREndness IEndianess );
4752c49e036c365df707cd8e6622d66382f380557b2cerion
4761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselDblExpr_wrk ( ISelEnv* env, IRExpr* e,
4771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                       IREndness IEndianess );
4781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselDblExpr     ( ISelEnv* env, IRExpr* e,
4791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                       IREndness IEndianess );
480094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselFltExpr_wrk ( ISelEnv* env, IRExpr* e,
4821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                       IREndness IEndianess );
4831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselFltExpr     ( ISelEnv* env, IRExpr* e,
4841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                       IREndness IEndianess );
485094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselVecExpr_wrk ( ISelEnv* env, IRExpr* e,
4871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                       IREndness IEndianess );
4881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselVecExpr     ( ISelEnv* env, IRExpr* e,
4891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                       IREndness IEndianess );
490cd304497d9d869f9b24a002299d3953ee072229bcerion
491c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* 64-bit mode ONLY. */
4921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselDfp32Expr_wrk ( ISelEnv* env, IRExpr* e,
4931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
4941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselDfp32Expr     ( ISelEnv* env, IRExpr* e,
4951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
4961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselDfp64Expr_wrk ( ISelEnv* env, IRExpr* e,
4971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
4981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg          iselDfp64Expr     ( ISelEnv* env, IRExpr* e,
4991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess );
500c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
501c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* 64-bit mode ONLY: compute an D128 into a GPR64 pair. */
502c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselDfp128Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env,
5031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IRExpr* e, IREndness IEndianess );
504c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselDfp128Expr     ( HReg* rHi, HReg* rLo, ISelEnv* env,
5051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IRExpr* e, IREndness IEndianess );
506cd304497d9d869f9b24a002299d3953ee072229bcerion
507cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
508cd304497d9d869f9b24a002299d3953ee072229bcerion/*--- ISEL: Misc helpers                                ---*/
509cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
510cd304497d9d869f9b24a002299d3953ee072229bcerion
511cd304497d9d869f9b24a002299d3953ee072229bcerion/* Make an int reg-reg move. */
512cd304497d9d869f9b24a002299d3953ee072229bcerion
5135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic PPCInstr* mk_iMOVds_RR ( HReg r_dst, HReg r_src )
514cd304497d9d869f9b24a002299d3953ee072229bcerion{
5154628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(r_dst) == hregClass(r_src));
5164628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(r_src) ==  HRcInt32 ||
5174628ccd1bafb946378f91849b92ffcfea0267b2ecerion           hregClass(r_src) ==  HRcInt64);
5185b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   return PPCInstr_Alu(Palu_OR, r_dst, r_src, PPCRH_Reg(r_src));
51998411db016ecb3bd1b8b72f75e4e3a49c95f4882cerion}
52098411db016ecb3bd1b8b72f75e4e3a49c95f4882cerion
521b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/* Advance/retreat %r1 by n. */
522cd304497d9d869f9b24a002299d3953ee072229bcerion
523f0de28cf1a762b0d6f74c93d3532c89a230673bbcerionstatic void add_to_sp ( ISelEnv* env, UInt n )
524094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
5254628ccd1bafb946378f91849b92ffcfea0267b2ecerion   HReg sp = StackFramePtr(env->mode64);
52674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(n <= 1024 && (n%16) == 0);
5275b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_Alu( Palu_ADD, sp, sp,
5285b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                               PPCRH_Imm(True,toUShort(n)) ));
529094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
530094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
531f0de28cf1a762b0d6f74c93d3532c89a230673bbcerionstatic void sub_from_sp ( ISelEnv* env, UInt n )
532094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
5334628ccd1bafb946378f91849b92ffcfea0267b2ecerion   HReg sp = StackFramePtr(env->mode64);
53474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(n <= 1024 && (n%16) == 0);
5355b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_Alu( Palu_SUB, sp, sp,
5365b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                               PPCRH_Imm(True,toUShort(n)) ));
537094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
538094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
539225a034683024109da729a4d2f080364b9485007cerion/*
540225a034683024109da729a4d2f080364b9485007cerion  returns a quadword aligned address on the stack
541225a034683024109da729a4d2f080364b9485007cerion   - copies SP, adds 16bytes, aligns to quadword.
542225a034683024109da729a4d2f080364b9485007cerion  use sub_from_sp(32) before calling this,
543225a034683024109da729a4d2f080364b9485007cerion  as expects to have 32 bytes to play with.
544225a034683024109da729a4d2f080364b9485007cerion*/
545225a034683024109da729a4d2f080364b9485007cerionstatic HReg get_sp_aligned16 ( ISelEnv* env )
546225a034683024109da729a4d2f080364b9485007cerion{
547225a034683024109da729a4d2f080364b9485007cerion   HReg       r = newVRegI(env);
548225a034683024109da729a4d2f080364b9485007cerion   HReg align16 = newVRegI(env);
5494628ccd1bafb946378f91849b92ffcfea0267b2ecerion   addInstr(env, mk_iMOVds_RR(r, StackFramePtr(env->mode64)));
550225a034683024109da729a4d2f080364b9485007cerion   // add 16
5515b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_Alu( Palu_ADD, r, r,
5525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                               PPCRH_Imm(True,toUShort(16)) ));
553225a034683024109da729a4d2f080364b9485007cerion   // mask to quadword
5544628ccd1bafb946378f91849b92ffcfea0267b2ecerion   addInstr(env,
5554628ccd1bafb946378f91849b92ffcfea0267b2ecerion            PPCInstr_LI(align16, 0xFFFFFFFFFFFFFFF0ULL, env->mode64));
5565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_Alu(Palu_AND, r,r, PPCRH_Reg(align16)));
557225a034683024109da729a4d2f080364b9485007cerion   return r;
558225a034683024109da729a4d2f080364b9485007cerion}
559225a034683024109da729a4d2f080364b9485007cerion
560225a034683024109da729a4d2f080364b9485007cerion
561094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
562094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* Load 2*I32 regs to fp reg */
5635b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic HReg mk_LoadRR32toFPR ( ISelEnv* env,
5645b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                               HReg r_srcHi, HReg r_srcLo )
565094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
566094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   HReg fr_dst = newVRegF(env);
5675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   PPCAMode *am_addr0, *am_addr1;
568094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
5694628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(!env->mode64);
570f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregClass(r_srcHi) == HRcInt32);
571f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregClass(r_srcLo) == HRcInt32);
572f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
573094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   sub_from_sp( env, 16 );        // Move SP down 16 bytes
5744628ccd1bafb946378f91849b92ffcfea0267b2ecerion   am_addr0 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
5754628ccd1bafb946378f91849b92ffcfea0267b2ecerion   am_addr1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
576094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
577094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   // store hi,lo as Ity_I32's
5784628ccd1bafb946378f91849b92ffcfea0267b2ecerion   addInstr(env, PPCInstr_Store( 4, am_addr0, r_srcHi, env->mode64 ));
5794628ccd1bafb946378f91849b92ffcfea0267b2ecerion   addInstr(env, PPCInstr_Store( 4, am_addr1, r_srcLo, env->mode64 ));
580f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
581f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   // load as float
5825b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fr_dst, am_addr0));
583f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
584f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   add_to_sp( env, 16 );          // Reset SP
585f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   return fr_dst;
586f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
587f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
588f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* Load I64 reg to fp reg */
589f0de28cf1a762b0d6f74c93d3532c89a230673bbcerionstatic HReg mk_LoadR64toFPR ( ISelEnv* env, HReg r_src )
590f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
591f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   HReg fr_dst = newVRegF(env);
5925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   PPCAMode *am_addr0;
593f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5944628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(env->mode64);
595f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregClass(r_src) == HRcInt64);
596f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
597f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   sub_from_sp( env, 16 );        // Move SP down 16 bytes
5984628ccd1bafb946378f91849b92ffcfea0267b2ecerion   am_addr0 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
599f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
600f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   // store as Ity_I64
6014628ccd1bafb946378f91849b92ffcfea0267b2ecerion   addInstr(env, PPCInstr_Store( 8, am_addr0, r_src, env->mode64 ));
602094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
603094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   // load as float
6045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fr_dst, am_addr0));
605094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
606094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   add_to_sp( env, 16 );          // Reset SP
607094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   return fr_dst;
608094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
609cd304497d9d869f9b24a002299d3953ee072229bcerion
610cd304497d9d869f9b24a002299d3953ee072229bcerion
61102d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion/* Given an amode, return one which references 4 bytes further
61202d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   along. */
613cd304497d9d869f9b24a002299d3953ee072229bcerion
6145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic PPCAMode* advance4 ( ISelEnv* env, PPCAMode* am )
61502d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion{
6165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   PPCAMode* am4 = dopyPPCAMode( am );
617b51f0f4f33256638ed953156a2635aa739b232f1sewardj   if (am4->tag == Pam_IR
618b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && am4->Pam.IR.index + 4 <= 32767) {
619b51f0f4f33256638ed953156a2635aa739b232f1sewardj      am4->Pam.IR.index += 4;
620b51f0f4f33256638ed953156a2635aa739b232f1sewardj   } else {
6215b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("advance4(ppc,host)");
62202d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   }
62302d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   return am4;
62402d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion}
625cd304497d9d869f9b24a002299d3953ee072229bcerion
626b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
627b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/* Given a guest-state array descriptor, an index expression and a
628b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   bias, generate a PPCAMode pointing at the relevant piece of
629aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   guest state.  */
630b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic
631dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjPPCAMode* genGuestArrayOffset ( ISelEnv* env, IRRegArray* descr,
6321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                IRExpr* off, Int bias, IREndness IEndianess )
633b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj{
634b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   HReg rtmp, roff;
635b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   Int  elemSz = sizeofIRType(descr->elemTy);
636b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   Int  nElems = descr->nElems;
637b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   Int  shift  = 0;
638b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
639b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /* Throw out any cases we don't need.  In theory there might be a
640b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      day where we need to handle others, but not today. */
641b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
642b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (nElems != 16 && nElems != 32)
643aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      vpanic("genGuestArrayOffset(ppc host)(1)");
644b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
645b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   switch (elemSz) {
646aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      case 4:  shift = 2; break;
647b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      case 8:  shift = 3; break;
648aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      default: vpanic("genGuestArrayOffset(ppc host)(2)");
649b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   }
650b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
651b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (bias < -100 || bias > 100) /* somewhat arbitrarily */
652aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      vpanic("genGuestArrayOffset(ppc host)(3)");
65366d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj   if (descr->base < 0 || descr->base > 5000) /* somewhat arbitrarily */
654478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      vpanic("genGuestArrayOffset(ppc host)(4)");
655b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
656b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /* Compute off into a reg, %off.  Then return:
657b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
658b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         addi %tmp, %off, bias (if bias != 0)
659b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         andi %tmp, nElems-1
660b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         sldi %tmp, shift
661b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         addi %tmp, %tmp, base
662b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         ... Baseblockptr + %tmp ...
663b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   */
6641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   roff = iselWordExpr_R(env, off, IEndianess);
665b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   rtmp = newVRegI(env);
666b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   addInstr(env, PPCInstr_Alu(
667b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    Palu_ADD,
668b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    rtmp, roff,
669b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    PPCRH_Imm(True/*signed*/, toUShort(bias))));
670b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   addInstr(env, PPCInstr_Alu(
671b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    Palu_AND,
672b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    rtmp, rtmp,
673e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj                    PPCRH_Imm(False/*unsigned*/, toUShort(nElems-1))));
674b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   addInstr(env, PPCInstr_Shft(
675b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    Pshft_SHL,
676aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                    env->mode64 ? False : True/*F:64-bit, T:32-bit shift*/,
677b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    rtmp, rtmp,
678b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    PPCRH_Imm(False/*unsigned*/, toUShort(shift))));
679b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   addInstr(env, PPCInstr_Alu(
680b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    Palu_ADD,
681b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    rtmp, rtmp,
682b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    PPCRH_Imm(True/*signed*/, toUShort(descr->base))));
683b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   return
684b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      PPCAMode_RR( GuestStatePtr(env->mode64), rtmp );
685b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj}
686b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
687b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
688b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*---------------------------------------------------------*/
689b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*--- ISEL: Function call helpers                       ---*/
690b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*---------------------------------------------------------*/
691b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
6922c49e036c365df707cd8e6622d66382f380557b2cerion/* Used only in doHelperCall.  See big comment in doHelperCall re
6932c49e036c365df707cd8e6622d66382f380557b2cerion   handling of register-parameter args.  This function figures out
6942c49e036c365df707cd8e6622d66382f380557b2cerion   whether evaluation of an expression might require use of a fixed
6952c49e036c365df707cd8e6622d66382f380557b2cerion   register.  If in doubt return True (safe but suboptimal).
6962c49e036c365df707cd8e6622d66382f380557b2cerion*/
6972c49e036c365df707cd8e6622d66382f380557b2cerionstatic
6982c49e036c365df707cd8e6622d66382f380557b2cerionBool mightRequireFixedRegs ( IRExpr* e )
6992c49e036c365df707cd8e6622d66382f380557b2cerion{
7002c49e036c365df707cd8e6622d66382f380557b2cerion   switch (e->tag) {
701dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   case Iex_RdTmp: case Iex_Const: case Iex_Get:
702b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion      return False;
703b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion   default:
704b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion      return True;
7052c49e036c365df707cd8e6622d66382f380557b2cerion   }
7062c49e036c365df707cd8e6622d66382f380557b2cerion}
707cd304497d9d869f9b24a002299d3953ee072229bcerion
708cd304497d9d869f9b24a002299d3953ee072229bcerion
70974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj/* Do a complete function call.  |guard| is a Ity_Bit expression
7102c49e036c365df707cd8e6622d66382f380557b2cerion   indicating whether or not the call happens.  If guard==NULL, the
71174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   call is unconditional.  |retloc| is set to indicate where the
71274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   return value is after the call.  The caller (of this fn) must
71374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   generate code to add |stackAdjustAfterCall| to the stack pointer
71474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   after the call is done. */
715cd304497d9d869f9b24a002299d3953ee072229bcerion
7162c49e036c365df707cd8e6622d66382f380557b2cerionstatic
71774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardjvoid doHelperCall ( /*OUT*/UInt*   stackAdjustAfterCall,
71874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                    /*OUT*/RetLoc* retloc,
71974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                    ISelEnv* env,
72074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                    IRExpr* guard,
7211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                    IRCallee* cee, IRType retTy, IRExpr** args,
7221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                    IREndness IEndianess)
7232c49e036c365df707cd8e6622d66382f380557b2cerion{
7245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   PPCCondCode cc;
7255b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   HReg        argregs[PPC_N_REGPARMS];
7265b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   HReg        tmpregs[PPC_N_REGPARMS];
7275b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   Bool        go_fast;
7285b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   Int         n_args, i, argreg;
7295b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   UInt        argiregs;
7304628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool        mode64 = env->mode64;
7312c49e036c365df707cd8e6622d66382f380557b2cerion
73274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   /* Set default returns.  We'll update them later if needed. */
73374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   *stackAdjustAfterCall = 0;
73474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   *retloc               = mk_RetLoc_INVALID();
73574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
73674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   /* These are used for cross-checking that IR-level constraints on
7379041956f39c57e265122ed0a71061dea1e554edcflorian      the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */
73874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   UInt nVECRETs = 0;
73974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   UInt nBBPTRs  = 0;
74074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
7412c49e036c365df707cd8e6622d66382f380557b2cerion   /* Marshal args for a call and do the call.
7422c49e036c365df707cd8e6622d66382f380557b2cerion
7432c49e036c365df707cd8e6622d66382f380557b2cerion      This function only deals with a tiny set of possibilities, which
7442c49e036c365df707cd8e6622d66382f380557b2cerion      cover all helpers in practice.  The restrictions are that only
745f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      arguments in registers are supported, hence only PPC_N_REGPARMS x
746f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      (mode32:32 | mode64:64) integer bits in total can be passed.
747f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      In fact the only supported arg type is (mode32:I32 | mode64:I64).
7482c49e036c365df707cd8e6622d66382f380557b2cerion
74974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      The return type can be I{64,32,16,8} or V{128,256}.  In the
75074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      latter two cases, it is expected that |args| will contain the
7519041956f39c57e265122ed0a71061dea1e554edcflorian      special node IRExpr_VECRET(), in which case this routine
75274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      generates code to allocate space on the stack for the vector
75374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      return value.  Since we are not passing any scalars on the
75474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      stack, it is enough to preallocate the return space before
75574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      marshalling any arguments, in this case.
75674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
7579041956f39c57e265122ed0a71061dea1e554edcflorian      |args| may also contain IRExpr_BBPTR(), in which case the value
75874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      in the guest state pointer register is passed as the
75974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      corresponding argument.
76074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
7612c49e036c365df707cd8e6622d66382f380557b2cerion      Generating code which is both efficient and correct when
7622c49e036c365df707cd8e6622d66382f380557b2cerion      parameters are to be passed in registers is difficult, for the
7632c49e036c365df707cd8e6622d66382f380557b2cerion      reasons elaborated in detail in comments attached to
7642c49e036c365df707cd8e6622d66382f380557b2cerion      doHelperCall() in priv/host-x86/isel.c.  Here, we use a variant
7652c49e036c365df707cd8e6622d66382f380557b2cerion      of the method described in those comments.
7662c49e036c365df707cd8e6622d66382f380557b2cerion
7672c49e036c365df707cd8e6622d66382f380557b2cerion      The problem is split into two cases: the fast scheme and the
7682c49e036c365df707cd8e6622d66382f380557b2cerion      slow scheme.  In the fast scheme, arguments are computed
7692c49e036c365df707cd8e6622d66382f380557b2cerion      directly into the target (real) registers.  This is only safe
7702c49e036c365df707cd8e6622d66382f380557b2cerion      when we can be sure that computation of each argument will not
7712c49e036c365df707cd8e6622d66382f380557b2cerion      trash any real registers set by computation of any other
7722c49e036c365df707cd8e6622d66382f380557b2cerion      argument.
7732c49e036c365df707cd8e6622d66382f380557b2cerion
7742c49e036c365df707cd8e6622d66382f380557b2cerion      In the slow scheme, all args are first computed into vregs, and
7752c49e036c365df707cd8e6622d66382f380557b2cerion      once they are all done, they are moved to the relevant real
7762c49e036c365df707cd8e6622d66382f380557b2cerion      regs.  This always gives correct code, but it also gives a bunch
7772c49e036c365df707cd8e6622d66382f380557b2cerion      of vreg-to-rreg moves which are usually redundant but are hard
7782c49e036c365df707cd8e6622d66382f380557b2cerion      for the register allocator to get rid of.
7792c49e036c365df707cd8e6622d66382f380557b2cerion
7802c49e036c365df707cd8e6622d66382f380557b2cerion      To decide which scheme to use, all argument expressions are
7812c49e036c365df707cd8e6622d66382f380557b2cerion      first examined.  If they are all so simple that it is clear they
7822c49e036c365df707cd8e6622d66382f380557b2cerion      will be evaluated without use of any fixed registers, use the
7832c49e036c365df707cd8e6622d66382f380557b2cerion      fast scheme, else use the slow scheme.  Note also that only
7842c49e036c365df707cd8e6622d66382f380557b2cerion      unconditional calls may use the fast scheme, since having to
7852c49e036c365df707cd8e6622d66382f380557b2cerion      compute a condition expression could itself trash real
7862c49e036c365df707cd8e6622d66382f380557b2cerion      registers.
7872c49e036c365df707cd8e6622d66382f380557b2cerion
7882c49e036c365df707cd8e6622d66382f380557b2cerion      Note this requires being able to examine an expression and
7892c49e036c365df707cd8e6622d66382f380557b2cerion      determine whether or not evaluation of it might use a fixed
7902c49e036c365df707cd8e6622d66382f380557b2cerion      register.  That requires knowledge of how the rest of this insn
7912c49e036c365df707cd8e6622d66382f380557b2cerion      selector works.  Currently just the following 3 are regarded as
7922c49e036c365df707cd8e6622d66382f380557b2cerion      safe -- hopefully they cover the majority of arguments in
7932c49e036c365df707cd8e6622d66382f380557b2cerion      practice: IRExpr_Tmp IRExpr_Const IRExpr_Get.
7942c49e036c365df707cd8e6622d66382f380557b2cerion   */
7952c49e036c365df707cd8e6622d66382f380557b2cerion
796f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* Note that the cee->regparms field is meaningless on PPC32/64 host
7972c49e036c365df707cd8e6622d66382f380557b2cerion      (since there is only one calling convention) and so we always
7982c49e036c365df707cd8e6622d66382f380557b2cerion      ignore it. */
7992c49e036c365df707cd8e6622d66382f380557b2cerion
8002c49e036c365df707cd8e6622d66382f380557b2cerion   n_args = 0;
8012c49e036c365df707cd8e6622d66382f380557b2cerion   for (i = 0; args[i]; i++)
8022c49e036c365df707cd8e6622d66382f380557b2cerion      n_args++;
8032c49e036c365df707cd8e6622d66382f380557b2cerion
80474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   if (n_args > PPC_N_REGPARMS) {
805f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vpanic("doHelperCall(PPC): cannot currently handle > 8 args");
806f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      // PPC_N_REGPARMS
8072c49e036c365df707cd8e6622d66382f380557b2cerion   }
80874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
80974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   /* This is kind of stupid .. the arrays are sized as PPC_N_REGPARMS
81074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      but we then assume that that value is 8. */
81174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(PPC_N_REGPARMS == 8);
812b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion
813f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[0] = hregPPC_GPR3(mode64);
814f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[1] = hregPPC_GPR4(mode64);
815f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[2] = hregPPC_GPR5(mode64);
816f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[3] = hregPPC_GPR6(mode64);
817f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[4] = hregPPC_GPR7(mode64);
818f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[5] = hregPPC_GPR8(mode64);
819f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[6] = hregPPC_GPR9(mode64);
820f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   argregs[7] = hregPPC_GPR10(mode64);
8216a64a9f0eddb932c55c2cd6c2c2ad2c6c4b6cafasewardj   argiregs = 0;
8222c49e036c365df707cd8e6622d66382f380557b2cerion
8232c49e036c365df707cd8e6622d66382f380557b2cerion   tmpregs[0] = tmpregs[1] = tmpregs[2] =
8242c49e036c365df707cd8e6622d66382f380557b2cerion   tmpregs[3] = tmpregs[4] = tmpregs[5] =
8252c49e036c365df707cd8e6622d66382f380557b2cerion   tmpregs[6] = tmpregs[7] = INVALID_HREG;
8262c49e036c365df707cd8e6622d66382f380557b2cerion
8272c49e036c365df707cd8e6622d66382f380557b2cerion   /* First decide which scheme (slow or fast) is to be used.  First
8282c49e036c365df707cd8e6622d66382f380557b2cerion      assume the fast scheme, and select slow if any contraindications
8292c49e036c365df707cd8e6622d66382f380557b2cerion      (wow) appear. */
8302c49e036c365df707cd8e6622d66382f380557b2cerion
8312c49e036c365df707cd8e6622d66382f380557b2cerion   go_fast = True;
8322c49e036c365df707cd8e6622d66382f380557b2cerion
83374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   /* We'll need space on the stack for the return value.  Avoid
83474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      possible complications with nested calls by using the slow
83574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      scheme. */
83674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   if (retTy == Ity_V128 || retTy == Ity_V256)
83774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      go_fast = False;
83874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
83974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   if (go_fast && guard) {
8402c49e036c365df707cd8e6622d66382f380557b2cerion      if (guard->tag == Iex_Const
8412c49e036c365df707cd8e6622d66382f380557b2cerion          && guard->Iex.Const.con->tag == Ico_U1
8422c49e036c365df707cd8e6622d66382f380557b2cerion          && guard->Iex.Const.con->Ico.U1 == True) {
8432c49e036c365df707cd8e6622d66382f380557b2cerion         /* unconditional */
8442c49e036c365df707cd8e6622d66382f380557b2cerion      } else {
8452c49e036c365df707cd8e6622d66382f380557b2cerion         /* Not manifestly unconditional -- be conservative. */
8462c49e036c365df707cd8e6622d66382f380557b2cerion         go_fast = False;
8472c49e036c365df707cd8e6622d66382f380557b2cerion      }
8482c49e036c365df707cd8e6622d66382f380557b2cerion   }
8492c49e036c365df707cd8e6622d66382f380557b2cerion
8502c49e036c365df707cd8e6622d66382f380557b2cerion   if (go_fast) {
8512c49e036c365df707cd8e6622d66382f380557b2cerion      for (i = 0; i < n_args; i++) {
85274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         IRExpr* arg = args[i];
8539041956f39c57e265122ed0a71061dea1e554edcflorian         if (UNLIKELY(arg->tag == Iex_BBPTR)) {
85474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* that's OK */
85574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
8569041956f39c57e265122ed0a71061dea1e554edcflorian         else if (UNLIKELY(arg->tag == Iex_VECRET)) {
85774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* This implies ill-formed IR, since if the IR was
85874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               well-formed, the return-type test above would have
85974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               filtered it out. */
86074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vpanic("doHelperCall(PPC): invalid IR");
86174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
86274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         else if (mightRequireFixedRegs(arg)) {
8632c49e036c365df707cd8e6622d66382f380557b2cerion            go_fast = False;
8642c49e036c365df707cd8e6622d66382f380557b2cerion            break;
8652c49e036c365df707cd8e6622d66382f380557b2cerion         }
8662c49e036c365df707cd8e6622d66382f380557b2cerion      }
8672c49e036c365df707cd8e6622d66382f380557b2cerion   }
8682c49e036c365df707cd8e6622d66382f380557b2cerion
8692c49e036c365df707cd8e6622d66382f380557b2cerion   /* At this point the scheme to use has been established.  Generate
8702c49e036c365df707cd8e6622d66382f380557b2cerion      code to get the arg values into the argument rregs. */
8712c49e036c365df707cd8e6622d66382f380557b2cerion
8722c49e036c365df707cd8e6622d66382f380557b2cerion   if (go_fast) {
8732c49e036c365df707cd8e6622d66382f380557b2cerion
8742c49e036c365df707cd8e6622d66382f380557b2cerion      /* FAST SCHEME */
8752c49e036c365df707cd8e6622d66382f380557b2cerion      argreg = 0;
8762c49e036c365df707cd8e6622d66382f380557b2cerion
8772c49e036c365df707cd8e6622d66382f380557b2cerion      for (i = 0; i < n_args; i++) {
87874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         IRExpr* arg = args[i];
879f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(argreg < PPC_N_REGPARMS);
88074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
8819041956f39c57e265122ed0a71061dea1e554edcflorian         if (arg->tag == Iex_BBPTR) {
8826a64a9f0eddb932c55c2cd6c2c2ad2c6c4b6cafasewardj            argiregs |= (1 << (argreg+3));
88384ad616686a2c29be1c2b1f65f72ae79820a84c4cerion            addInstr(env, mk_iMOVds_RR( argregs[argreg],
88474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                                        GuestStatePtr(mode64) ));
88574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            argreg++;
88674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         } else {
8879041956f39c57e265122ed0a71061dea1e554edcflorian            vassert(arg->tag != Iex_VECRET);
88874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            IRType ty = typeOfIRExpr(env->type_env, arg);
88974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(ty == Ity_I32 || ty == Ity_I64);
89074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            if (!mode64) {
89174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               if (ty == Ity_I32) {
89274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  argiregs |= (1 << (argreg+3));
89374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  addInstr(env,
89474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                           mk_iMOVds_RR( argregs[argreg],
8951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         iselWordExpr_R(env, arg,
8961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll							IEndianess) ));
89774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               } else { // Ity_I64 in 32-bit mode
89874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  HReg rHi, rLo;
899d1526f226f529c916d2868d10d52194f7e6b7235sewardj                  if ((argreg%2) == 1)
90074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                                 // ppc32 ELF abi spec for passing LONG_LONG
90174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                     argreg++;   // XXX: odd argreg => even rN
90274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  vassert(argreg < PPC_N_REGPARMS-1);
9031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  iselInt64Expr(&rHi,&rLo, env, arg, IEndianess);
90474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  argiregs |= (1 << (argreg+3));
90574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  addInstr(env, mk_iMOVds_RR( argregs[argreg++], rHi ));
90674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  argiregs |= (1 << (argreg+3));
90774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  addInstr(env, mk_iMOVds_RR( argregs[argreg], rLo));
90874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               }
90974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            } else { // mode64
91074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               argiregs |= (1 << (argreg+3));
91174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR( argregs[argreg],
9121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           iselWordExpr_R(env, arg,
9131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                                          IEndianess) ));
91474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            }
91574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            argreg++;
91674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         } /* if (arg == IRExprP__BBPR) */
9172c49e036c365df707cd8e6622d66382f380557b2cerion      }
9182c49e036c365df707cd8e6622d66382f380557b2cerion
9192c49e036c365df707cd8e6622d66382f380557b2cerion      /* Fast scheme only applies for unconditional calls.  Hence: */
9207e3080762e559bb58213654a7be8cbb529e40446sewardj      cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
9212c49e036c365df707cd8e6622d66382f380557b2cerion
9222c49e036c365df707cd8e6622d66382f380557b2cerion   } else {
9232c49e036c365df707cd8e6622d66382f380557b2cerion
9242c49e036c365df707cd8e6622d66382f380557b2cerion      /* SLOW SCHEME; move via temporaries */
9252c49e036c365df707cd8e6622d66382f380557b2cerion      argreg = 0;
9262c49e036c365df707cd8e6622d66382f380557b2cerion
92774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      /* If we have a vector return type, allocate a place for it on
92874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         the stack and record its address.  Rather than figure out the
92974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         complexities of PPC{32,64} ELF ABI stack frame layout, simply
93074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         drop the SP by 1024 and allocate the return point in the
93174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         middle.  I think this should comfortably clear any ABI
93274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         mandated register save areas.  Note that it doesn't maintain
93374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         the backchain as it should, since we're not doing st{d,w}u to
93474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         adjust the SP, but .. that doesn't seem to be a big deal.
93574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         Since we're not expecting to have to unwind out of here. */
93674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      HReg r_vecRetAddr = INVALID_HREG;
93774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      if (retTy == Ity_V128) {
93874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         r_vecRetAddr = newVRegI(env);
93974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         sub_from_sp(env, 512);
94074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         addInstr(env, mk_iMOVds_RR( r_vecRetAddr, StackFramePtr(mode64) ));
94174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         sub_from_sp(env, 512);
94274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      }
94374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      else if (retTy == Ity_V256) {
94474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         vassert(0); //ATC
94574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         r_vecRetAddr = newVRegI(env);
94674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         sub_from_sp(env, 512);
94774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         addInstr(env, mk_iMOVds_RR( r_vecRetAddr, StackFramePtr(mode64) ));
94874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         sub_from_sp(env, 512);
94974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      }
95074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
95174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(n_args >= 0 && n_args <= 8);
9522c49e036c365df707cd8e6622d66382f380557b2cerion      for (i = 0; i < n_args; i++) {
95374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         IRExpr* arg = args[i];
954f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(argreg < PPC_N_REGPARMS);
9559041956f39c57e265122ed0a71061dea1e554edcflorian         if (UNLIKELY(arg->tag == Iex_BBPTR)) {
95674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            tmpregs[argreg] = newVRegI(env);
95774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            addInstr(env, mk_iMOVds_RR( tmpregs[argreg],
95874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                                        GuestStatePtr(mode64) ));
95974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            nBBPTRs++;
96074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
9619041956f39c57e265122ed0a71061dea1e554edcflorian         else if (UNLIKELY(arg->tag == Iex_VECRET)) {
96274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* We stashed the address of the return slot earlier, so just
96374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               retrieve it now. */
96474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(!hregIsInvalid(r_vecRetAddr));
96574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            tmpregs[i] = r_vecRetAddr;
96674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            nVECRETs++;
96774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
96874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         else {
96974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            IRType ty = typeOfIRExpr(env->type_env, arg);
97074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(ty == Ity_I32 || ty == Ity_I64);
97174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            if (!mode64) {
97274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               if (ty == Ity_I32) {
9731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  tmpregs[argreg] = iselWordExpr_R(env, arg, IEndianess);
97474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               } else { // Ity_I64 in 32-bit mode
97574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  HReg rHi, rLo;
976d1526f226f529c916d2868d10d52194f7e6b7235sewardj                  if ((argreg%2) == 1)
97774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                                // ppc32 ELF abi spec for passing LONG_LONG
97874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                     argreg++;  // XXX: odd argreg => even rN
97974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  vassert(argreg < PPC_N_REGPARMS-1);
9801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  iselInt64Expr(&rHi,&rLo, env, arg, IEndianess);
98174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  tmpregs[argreg++] = rHi;
98274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  tmpregs[argreg]   = rLo;
98374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               }
98474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            } else { // mode64
9851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               tmpregs[argreg] = iselWordExpr_R(env, arg, IEndianess);
986f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            }
98784ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         }
9882c49e036c365df707cd8e6622d66382f380557b2cerion         argreg++;
9892c49e036c365df707cd8e6622d66382f380557b2cerion      }
9902c49e036c365df707cd8e6622d66382f380557b2cerion
9912c49e036c365df707cd8e6622d66382f380557b2cerion      /* Now we can compute the condition.  We can't do it earlier
9922c49e036c365df707cd8e6622d66382f380557b2cerion         because the argument computations could trash the condition
9932c49e036c365df707cd8e6622d66382f380557b2cerion         codes.  Be a bit clever to handle the common case where the
9942c49e036c365df707cd8e6622d66382f380557b2cerion         guard is 1:Bit. */
9957e3080762e559bb58213654a7be8cbb529e40446sewardj      cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
9962c49e036c365df707cd8e6622d66382f380557b2cerion      if (guard) {
9972c49e036c365df707cd8e6622d66382f380557b2cerion         if (guard->tag == Iex_Const
9982c49e036c365df707cd8e6622d66382f380557b2cerion             && guard->Iex.Const.con->tag == Ico_U1
9992c49e036c365df707cd8e6622d66382f380557b2cerion             && guard->Iex.Const.con->Ico.U1 == True) {
10002c49e036c365df707cd8e6622d66382f380557b2cerion            /* unconditional -- do nothing */
10012c49e036c365df707cd8e6622d66382f380557b2cerion         } else {
10021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            cc = iselCondCode( env, guard, IEndianess );
10032c49e036c365df707cd8e6622d66382f380557b2cerion         }
10042c49e036c365df707cd8e6622d66382f380557b2cerion      }
10052c49e036c365df707cd8e6622d66382f380557b2cerion
10062c49e036c365df707cd8e6622d66382f380557b2cerion      /* Move the args to their final destinations. */
10072c49e036c365df707cd8e6622d66382f380557b2cerion      for (i = 0; i < argreg; i++) {
100879efdc6ea93db174395af845d4e21a4a7ad600ccflorian         if (hregIsInvalid(tmpregs[i]))  // Skip invalid regs
1009336246aabe1cf75641d44ea7d3b76b9ee50d9b18cerion            continue;
10102c49e036c365df707cd8e6622d66382f380557b2cerion         /* None of these insns, including any spill code that might
10112c49e036c365df707cd8e6622d66382f380557b2cerion            be generated, may alter the condition codes. */
10126a64a9f0eddb932c55c2cd6c2c2ad2c6c4b6cafasewardj         argiregs |= (1 << (i+3));
10132c49e036c365df707cd8e6622d66382f380557b2cerion         addInstr( env, mk_iMOVds_RR( argregs[i], tmpregs[i] ) );
10142c49e036c365df707cd8e6622d66382f380557b2cerion      }
10152c49e036c365df707cd8e6622d66382f380557b2cerion
10162c49e036c365df707cd8e6622d66382f380557b2cerion   }
10172c49e036c365df707cd8e6622d66382f380557b2cerion
101874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   /* Do final checks, set the return values, and generate the call
101974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      instruction proper. */
102074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   if (retTy == Ity_V128 || retTy == Ity_V256) {
102174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(nVECRETs == 1);
102274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   } else {
102374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(nVECRETs == 0);
102474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   }
1025f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
102674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(nBBPTRs == 0 || nBBPTRs == 1);
102774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
102874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(*stackAdjustAfterCall == 0);
102974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(is_RetLoc_INVALID(*retloc));
103074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   switch (retTy) {
103174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      case Ity_INVALID:
103274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         /* Function doesn't return a value. */
103374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *retloc = mk_RetLoc_simple(RLPri_None);
103474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         break;
103574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      case Ity_I64:
103674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *retloc = mk_RetLoc_simple(mode64 ? RLPri_Int : RLPri_2Int);
103774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         break;
103874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      case Ity_I32: case Ity_I16: case Ity_I8:
103974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *retloc = mk_RetLoc_simple(RLPri_Int);
104074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         break;
104174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      case Ity_V128:
104274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         /* Result is 512 bytes up the stack, and after it has been
104374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            retrieved, adjust SP upwards by 1024. */
104474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *retloc = mk_RetLoc_spRel(RLPri_V128SpRel, 512);
104574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *stackAdjustAfterCall = 1024;
104674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         break;
104774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      case Ity_V256:
104874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         vassert(0); // ATC
104974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         /* Ditto */
105074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *retloc = mk_RetLoc_spRel(RLPri_V256SpRel, 512);
105174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         *stackAdjustAfterCall = 1024;
105274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         break;
105374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      default:
105474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         /* IR can denote other possible return types, but we don't
105574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            handle those here. */
105674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         vassert(0);
105774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   }
105874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
105974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   /* Finally, generate the call itself.  This needs the *retloc value
106074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      set in the switch above, which is why it's at the end. */
106174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
106293a09742b0de3d61718882c2d999f64be402564dflorian   Addr64 target = mode64 ? (Addr)cee->addr
106393a09742b0de3d61718882c2d999f64be402564dflorian                          : toUInt((Addr)(cee->addr));
106493a09742b0de3d61718882c2d999f64be402564dflorian   addInstr(env, PPCInstr_Call( cc, target, argiregs, *retloc ));
10652c49e036c365df707cd8e6622d66382f380557b2cerion}
1066cd304497d9d869f9b24a002299d3953ee072229bcerion
1067cd304497d9d869f9b24a002299d3953ee072229bcerion
1068b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*---------------------------------------------------------*/
1069b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*--- ISEL: FP rounding mode helpers                    ---*/
1070b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*---------------------------------------------------------*/
10716e53088a92d40be75cc362986956ac149b3fa94bsewardj
1072b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj///* Set FPU's rounding mode to the default */
1073b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//static
1074b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//void set_FPU_rounding_default ( ISelEnv* env )
1075b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//{
1076b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   HReg fr_src = newVRegF(env);
1077b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   HReg r_src  = newVRegI(env);
1078b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//
1079b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   /* Default rounding mode = 0x0
1080b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//      Only supporting the rounding-mode bits - the rest of FPSCR is 0x0
1081b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//       - so we can set the whole register at once (faster)
1082b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//      note: upper 32 bits ignored by FpLdFPSCR
1083b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   */
1084b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   addInstr(env, PPCInstr_LI(r_src, 0x0, env->mode64));
1085b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   if (env->mode64) {
1086b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//      fr_src = mk_LoadR64toFPR( env, r_src );         // 1*I64 -> F64
1087b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   } else {
1088b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//      fr_src = mk_LoadRR32toFPR( env, r_src, r_src ); // 2*I32 -> F64
1089b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   }
1090b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//   addInstr(env, PPCInstr_FpLdFPSCR( fr_src ));
1091b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj//}
1092094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
10935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion/* Convert IR rounding mode to PPC encoding */
10945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic HReg roundModeIRtoPPC ( ISelEnv* env, HReg r_rmIR )
1095094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
1096b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /*
1097c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   rounding mode                     | PPC  |  IR
1098c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   -----------------------------------------------
1099c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to nearest, ties to even          | 000  | 000
1100c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to zero                           | 001  | 011
1101c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to +infinity                      | 010  | 010
1102c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to -infinity                      | 011  | 001
1103c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   +++++ Below are the extended rounding modes for decimal floating point +++++
1104c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to nearest, ties away from 0      | 100  | 100
1105c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to nearest, ties toward 0         | 101  | 111
1106c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to away from 0                    | 110  | 110
1107c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   to prepare for shorter precision  | 111  | 101
1108b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   */
11095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   HReg r_rmPPC = newVRegI(env);
1110b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   HReg r_tmp1  = newVRegI(env);
1111c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   HReg r_tmp2  = newVRegI(env);
1112094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
11134628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(r_rmIR) == HRcGPR(env->mode64));
1114f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
1115b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   // r_rmPPC = XOR(r_rmIR, r_rmIR << 1) & 3
1116b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   //
1117b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   // slwi  tmp1,    r_rmIR, 1
1118b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   // xor   tmp1,    r_rmIR, tmp1
1119b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   // andi  r_rmPPC, tmp1, 3
11205b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion
11215b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
1122b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                               r_tmp1, r_rmIR, PPCRH_Imm(False,1)));
1123b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1124c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   addInstr( env, PPCInstr_Alu( Palu_AND,
1125c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                r_tmp2, r_tmp1, PPCRH_Imm( False, 3 ) ) );
1126b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1127c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   addInstr( env, PPCInstr_Alu( Palu_XOR,
1128c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                r_rmPPC, r_rmIR, PPCRH_Reg( r_tmp2 ) ) );
1129b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
11305b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   return r_rmPPC;
1131094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
1132094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
1133094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
1134b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/* Set the FPU's rounding mode: 'mode' is an I32-typed expression
1135c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   denoting a value in the range 0 .. 7, indicating a round mode
1136b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   encoded as per type IRRoundingMode.  Set the PPC FPSCR to have the
1137c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   same rounding.  When the dfp_rm arg is True, set the decimal
1138c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   floating point rounding mode bits (29:31); otherwise, set the
1139c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   binary floating point rounding mode bits (62:63).
1140b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1141094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   For speed & simplicity, we're setting the *entire* FPSCR here.
1142b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1143b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   Setting the rounding mode is expensive.  So this function tries to
1144b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   avoid repeatedly setting the rounding mode to the same thing by
1145b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   first comparing 'mode' to the 'mode' tree supplied in the previous
1146b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   call to this function, if any.  (The previous value is stored in
1147b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   env->previous_rm.)  If 'mode' is a single IR temporary 't' and
1148b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   env->previous_rm is also just 't', then the setting is skipped.
1149b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1150b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   This is safe because of the SSA property of IR: an IR temporary can
1151b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   only be defined once and so will have the same value regardless of
1152b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   where it appears in the block.  Cool stuff, SSA.
1153b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1154b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   A safety condition: all attempts to set the RM must be aware of
1155b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   this mechanism - by being routed through the functions here.
1156b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1157b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   Of course this only helps if blocks where the RM is set more than
1158b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   once and it is set to the same value each time, *and* that value is
1159b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   held in the same IR temporary each time.  In order to assure the
1160b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   latter as much as possible, the IR optimiser takes care to do CSE
1161b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   on any block with any sign of floating point activity.
1162094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion*/
1163094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerionstatic
11641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllvoid _set_FPU_rounding_mode ( ISelEnv* env, IRExpr* mode, Bool dfp_rm,
11651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                              IREndness IEndianess )
1166094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
116707b07a966a2fdbcf621251a0c1a8ab84807fb120cerion   HReg fr_src = newVRegF(env);
1168f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   HReg r_src;
1169f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
117007b07a966a2fdbcf621251a0c1a8ab84807fb120cerion   vassert(typeOfIRExpr(env->type_env,mode) == Ity_I32);
1171b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1172b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /* Do we need to do anything? */
1173b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (env->previous_rm
1174dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj       && env->previous_rm->tag == Iex_RdTmp
1175dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj       && mode->tag == Iex_RdTmp
1176dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj       && env->previous_rm->Iex.RdTmp.tmp == mode->Iex.RdTmp.tmp) {
1177b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* no - setting it to what it was before.  */
1178b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      vassert(typeOfIRExpr(env->type_env, env->previous_rm) == Ity_I32);
1179b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      return;
1180b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   }
1181094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
1182b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /* No luck - we better set it, and remember what we set it to. */
1183b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   env->previous_rm = mode;
1184b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1185b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /* Only supporting the rounding-mode bits - the rest of FPSCR is
1186b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      0x0 - so we can set the whole register at once (faster). */
1187094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
11885b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   // Resolve rounding mode and convert to PPC representation
11891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   r_src = roundModeIRtoPPC( env, iselWordExpr_R(env, mode, IEndianess) );
1190c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
1191f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   // gpr -> fpr
11924628ccd1bafb946378f91849b92ffcfea0267b2ecerion   if (env->mode64) {
1193c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (dfp_rm) {
1194c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_tmp1 = newVRegI( env );
1195c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env,
1196c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                   PPCInstr_Shft( Pshft_SHL, False/*64bit shift*/,
1197c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                  r_tmp1, r_src, PPCRH_Imm( False, 32 ) ) );
1198c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fr_src = mk_LoadR64toFPR( env, r_tmp1 );
1199c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      } else {
1200c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fr_src = mk_LoadR64toFPR( env, r_src ); // 1*I64 -> F64
1201c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
1202f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   } else {
1203c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (dfp_rm) {
1204c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_zero = newVRegI( env );
1205c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_LI( r_zero, 0, env->mode64 ) );
1206c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fr_src = mk_LoadRR32toFPR( env, r_src, r_zero );
1207c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      } else {
1208c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fr_src = mk_LoadRR32toFPR( env, r_src, r_src ); // 2*I32 -> F64
1209c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
1210f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
1211094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
1212094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   // Move to FPSCR
1213c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   addInstr(env, PPCInstr_FpLdFPSCR( fr_src, dfp_rm ));
1214c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
1215c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
12161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void set_FPU_rounding_mode ( ISelEnv* env, IRExpr* mode,
12171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IREndness IEndianess )
1218c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
12191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   _set_FPU_rounding_mode(env, mode, False, IEndianess);
1220c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
1221c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
12221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void set_FPU_DFP_rounding_mode ( ISelEnv* env, IRExpr* mode,
12231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IREndness IEndianess )
1224c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
12251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   _set_FPU_rounding_mode(env, mode, True, IEndianess);
1226094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
1227cd304497d9d869f9b24a002299d3953ee072229bcerion
1228cd304497d9d869f9b24a002299d3953ee072229bcerion
1229b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*---------------------------------------------------------*/
1230b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*--- ISEL: vector helpers                              ---*/
1231b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/*---------------------------------------------------------*/
1232b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
1233cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion/* Generate all-zeroes into a new vector register.
1234cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion*/
1235cd90bfe9a039fb52f46065da04ba5e892541a5d5cerionstatic HReg generate_zeroes_V128 ( ISelEnv* env )
1236cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion{
1237cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   HReg dst = newVRegV(env);
1238cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   addInstr(env, PPCInstr_AvBinary(Pav_XOR, dst, dst, dst));
1239cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   return dst;
1240cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion}
1241cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion
1242d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj/* Generate all-ones into a new vector register.
1243d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj*/
1244d2b1816d5a45eab742a6a7716a38133d2d47d66esewardjstatic HReg generate_ones_V128 ( ISelEnv* env )
1245d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj{
1246d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj   HReg dst = newVRegV(env);
1247d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj   PPCVI5s * src = PPCVI5s_Imm(-1);
1248d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj   addInstr(env, PPCInstr_AvSplat(8, dst, src));
1249d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj   return dst;
1250d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj}
1251d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj
1252cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion
125327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion/*
125427b3d7ec17c3a0814d4980db87defbb4f07339bfcerion  Generates code for AvSplat
125527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion  - takes in IRExpr* of type 8|16|32
125627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion    returns vector reg of duplicated lanes of input
125727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion  - uses AvSplat(imm) for imms up to simm6.
125827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion    otherwise must use store reg & load vector
125927b3d7ec17c3a0814d4980db87defbb4f07339bfcerion*/
12601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg mk_AvDuplicateRI( ISelEnv* env, IRExpr* e, IREndness IEndianess )
126127b3d7ec17c3a0814d4980db87defbb4f07339bfcerion{
12625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   HReg   r_src;
12635b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   HReg   dst = newVRegV(env);
12641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   PPCRI* ri  = iselWordExpr_RI(env, e, IEndianess);
12655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   IRType ty  = typeOfIRExpr(env->type_env,e);
12665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   UInt   sz  = (ty == Ity_I8) ? 8 : (ty == Ity_I16) ? 16 : 32;
126727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
126827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
126927b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   /* special case: immediate */
127027b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   if (ri->tag == Pri_Imm) {
127127b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      Int simm32 = (Int)ri->Pri.Imm;
127227b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
127327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      /* figure out if it's do-able with imm splats. */
127427b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      if (simm32 >= -32 && simm32 <= 31) {
127527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         Char simm6 = (Char)simm32;
127627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         if (simm6 > 15) {           /* 16:31 inclusive */
127727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion            HReg v1 = newVRegV(env);
127827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion            HReg v2 = newVRegV(env);
12795b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AvSplat(sz, v1, PPCVI5s_Imm(-16)));
12805b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AvSplat(sz, v2, PPCVI5s_Imm(simm6-16)));
1281d3e52410a03147c36dbf977a37e77a4de246f7c9cerion            addInstr(env,
12825b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               (sz== 8) ? PPCInstr_AvBin8x16(Pav_SUBU, dst, v2, v1) :
12835b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               (sz==16) ? PPCInstr_AvBin16x8(Pav_SUBU, dst, v2, v1)
12845b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                        : PPCInstr_AvBin32x4(Pav_SUBU, dst, v2, v1) );
128527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion            return dst;
128627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         }
128727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         if (simm6 < -16) {          /* -32:-17 inclusive */
128827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion            HReg v1 = newVRegV(env);
128927b3d7ec17c3a0814d4980db87defbb4f07339bfcerion            HReg v2 = newVRegV(env);
12905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AvSplat(sz, v1, PPCVI5s_Imm(-16)));
12915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AvSplat(sz, v2, PPCVI5s_Imm(simm6+16)));
1292d3e52410a03147c36dbf977a37e77a4de246f7c9cerion            addInstr(env,
12935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               (sz== 8) ? PPCInstr_AvBin8x16(Pav_ADDU, dst, v2, v1) :
12945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               (sz==16) ? PPCInstr_AvBin16x8(Pav_ADDU, dst, v2, v1)
12955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                        : PPCInstr_AvBin32x4(Pav_ADDU, dst, v2, v1) );
129627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion            return dst;
129727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         }
129827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         /* simplest form:              -16:15 inclusive */
12995b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvSplat(sz, dst, PPCVI5s_Imm(simm6)));
130027b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         return dst;
130127b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      }
130227b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
130327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      /* no luck; use the Slow way. */
130427b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      r_src = newVRegI(env);
13054628ccd1bafb946378f91849b92ffcfea0267b2ecerion      addInstr(env, PPCInstr_LI(r_src, (Long)simm32, env->mode64));
130627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   }
130727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   else {
130827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      r_src = ri->Pri.Reg;
130927b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   }
131027b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
131127b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   {
13121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      /* Store r_src multiple times (sz dependent); then load the dest vector. */
1313197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj      HReg r_aligned16;
13141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCAMode *am_offset, *am_offset_zero;
131527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
131627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      sub_from_sp( env, 32 );     // Move SP down
131727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      /* Get a 16-aligned address within our stack space */
1318197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj      r_aligned16 = get_sp_aligned16( env );
131927b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
13201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      Int i;
13211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      Int stride = (sz == 8) ? 1 : (sz == 16) ? 2 : 4;
13221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      UChar num_bytes_to_store = stride;
13231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_offset_zero = PPCAMode_IR( 0, r_aligned16 );
13241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_offset = am_offset_zero;
13251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      for (i = 0; i < 16; i+=stride, am_offset = PPCAMode_IR( i, r_aligned16)) {
13261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         addInstr(env, PPCInstr_Store( num_bytes_to_store, am_offset, r_src, env->mode64 ));
13271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      }
132827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
13291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      /* Effectively splat the r_src value to dst */
1330678ede2f4b3d38e9a4d27839d76724134990ca53carll      addInstr(env, PPCInstr_AvLdSt( True/*ld*/, 16, dst, am_offset_zero ) );
133127b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      add_to_sp( env, 32 );       // Reset SP
133227b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
133327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      return dst;
133427b3d7ec17c3a0814d4980db87defbb4f07339bfcerion   }
133527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion}
133627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
1337cd304497d9d869f9b24a002299d3953ee072229bcerion
13388ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion/* for each lane of vSrc: lane == nan ? laneX = all 1's : all 0's */
13391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg isNan ( ISelEnv* env, HReg vSrc, IREndness IEndianess )
13408ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion{
134141a7b70f888cf73cf3da6a53b31937ce0d26e8f4sewardj   HReg zeros, msk_exp, msk_mnt, expt, mnts, vIsNan;
134241a7b70f888cf73cf3da6a53b31937ce0d26e8f4sewardj
13438ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion   vassert(hregClass(vSrc) == HRcVec128);
13448ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
13451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   zeros   = mk_AvDuplicateRI(env, mkU32(0), IEndianess);
13461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   msk_exp = mk_AvDuplicateRI(env, mkU32(0x7F800000), IEndianess);
13471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   msk_mnt = mk_AvDuplicateRI(env, mkU32(0x7FFFFF), IEndianess);
134841a7b70f888cf73cf3da6a53b31937ce0d26e8f4sewardj   expt    = newVRegV(env);
134941a7b70f888cf73cf3da6a53b31937ce0d26e8f4sewardj   mnts    = newVRegV(env);
135041a7b70f888cf73cf3da6a53b31937ce0d26e8f4sewardj   vIsNan  = newVRegV(env);
13518ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
1352b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   /* 32bit float => sign(1) | exponent(8) | mantissa(23)
13538ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      nan => exponent all ones, mantissa > 0 */
13548ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
13555b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_AvBinary(Pav_AND, expt, vSrc, msk_exp));
13565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_AvBin32x4(Pav_CMPEQU, expt, expt, msk_exp));
13575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_AvBinary(Pav_AND, mnts, vSrc, msk_mnt));
13585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_AvBin32x4(Pav_CMPGTU, mnts, mnts, zeros));
13595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   addInstr(env, PPCInstr_AvBinary(Pav_AND, vIsNan, expt, mnts));
13608ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion   return vIsNan;
13618ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion}
13628ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
13638ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
1364cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
13655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion/*--- ISEL: Integer expressions (64/32/16/8 bit)        ---*/
1366cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
1367cd304497d9d869f9b24a002299d3953ee072229bcerion
1368cd304497d9d869f9b24a002299d3953ee072229bcerion/* Select insns for an integer-typed expression, and add them to the
1369cd304497d9d869f9b24a002299d3953ee072229bcerion   code list.  Return a reg holding the result.  This reg will be a
1370cd304497d9d869f9b24a002299d3953ee072229bcerion   virtual register.  THE RETURNED REG MUST NOT BE MODIFIED.  If you
1371cd304497d9d869f9b24a002299d3953ee072229bcerion   want to modify it, ask for a new vreg, copy it in there, and modify
1372cd304497d9d869f9b24a002299d3953ee072229bcerion   the copy.  The register allocator will do its best to map both
1373cd304497d9d869f9b24a002299d3953ee072229bcerion   vregs to the same real register, so the copies will often disappear
1374cd304497d9d869f9b24a002299d3953ee072229bcerion   later in the game.
1375cd304497d9d869f9b24a002299d3953ee072229bcerion
13765b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   This should handle expressions of 64, 32, 16 and 8-bit type.
13775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   All results are returned in a (mode64 ? 64bit : 32bit) register.
13785b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   For 16- and 8-bit expressions, the upper (32/48/56 : 16/24) bits
13795b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   are arbitrary, so you should mask or sign extend partial values
13805b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   if necessary.
1381cd304497d9d869f9b24a002299d3953ee072229bcerion*/
1382cd304497d9d869f9b24a002299d3953ee072229bcerion
13831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselWordExpr_R ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
1384cd304497d9d869f9b24a002299d3953ee072229bcerion{
13851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselWordExpr_R_wrk(env, e, IEndianess);
1386cd304497d9d869f9b24a002299d3953ee072229bcerion   /* sanity checks ... */
13879a934a9750fbfc6ae16435422036920d91cd681acerion#  if 0
1388cd304497d9d869f9b24a002299d3953ee072229bcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
1389cd304497d9d869f9b24a002299d3953ee072229bcerion#  endif
1390f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
13914628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(r) == HRcGPR(env->mode64));
1392cd304497d9d869f9b24a002299d3953ee072229bcerion   vassert(hregIsVirtual(r));
1393cd304497d9d869f9b24a002299d3953ee072229bcerion   return r;
1394cd304497d9d869f9b24a002299d3953ee072229bcerion}
1395cd304497d9d869f9b24a002299d3953ee072229bcerion
1396cd304497d9d869f9b24a002299d3953ee072229bcerion/* DO NOT CALL THIS DIRECTLY ! */
13971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e,
13981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IREndness IEndianess )
1399cd304497d9d869f9b24a002299d3953ee072229bcerion{
14004628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
14012c49e036c365df707cd8e6622d66382f380557b2cerion   MatchInfo mi;
14022c49e036c365df707cd8e6622d66382f380557b2cerion   DECLARE_PATTERN(p_32to1_then_1Uto8);
1403cd304497d9d869f9b24a002299d3953ee072229bcerion
1404cd304497d9d869f9b24a002299d3953ee072229bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
1405f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8 || ty == Ity_I16 ||
1406f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           ty == Ity_I32 || ((ty == Ity_I64) && mode64));
1407cd304497d9d869f9b24a002299d3953ee072229bcerion
1408cd304497d9d869f9b24a002299d3953ee072229bcerion   switch (e->tag) {
1409cd304497d9d869f9b24a002299d3953ee072229bcerion
1410cd304497d9d869f9b24a002299d3953ee072229bcerion   /* --------- TEMP --------- */
1411dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   case Iex_RdTmp:
1412dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
1413cd304497d9d869f9b24a002299d3953ee072229bcerion
1414b536af93912b69421440c27aa0533ad77d678f85cerion   /* --------- LOAD --------- */
1415af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj   case Iex_Load: {
1416e768e92e054cde495849a5c842a477d287677f78sewardj      HReg      r_dst;
1417e768e92e054cde495849a5c842a477d287677f78sewardj      PPCAMode* am_addr;
14181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      if (e->Iex.Load.end != IEndianess)
1419af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         goto irreducible;
1420e768e92e054cde495849a5c842a477d287677f78sewardj      r_dst   = newVRegI(env);
14211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode( env, e->Iex.Load.addr, ty/*of xfer*/,
14221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IEndianess );
1423e768e92e054cde495849a5c842a477d287677f78sewardj      addInstr(env, PPCInstr_Load( toUChar(sizeofIRType(ty)),
1424e768e92e054cde495849a5c842a477d287677f78sewardj                                   r_dst, am_addr, mode64 ));
1425f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return r_dst;
1426e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      /*NOTREACHED*/
1427b536af93912b69421440c27aa0533ad77d678f85cerion   }
1428cd304497d9d869f9b24a002299d3953ee072229bcerion
14292c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- BINARY OP --------- */
14302c49e036c365df707cd8e6622d66382f380557b2cerion   case Iex_Binop: {
14315b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAluOp  aluOp;
14325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCShftOp shftOp;
14332c49e036c365df707cd8e6622d66382f380557b2cerion
14342c49e036c365df707cd8e6622d66382f380557b2cerion      /* Is it an addition or logical style op? */
14352c49e036c365df707cd8e6622d66382f380557b2cerion      switch (e->Iex.Binop.op) {
1436f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_Add8: case Iop_Add16: case Iop_Add32: case Iop_Add64:
1437f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         aluOp = Palu_ADD; break;
1438f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_Sub8: case Iop_Sub16: case Iop_Sub32: case Iop_Sub64:
1439f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         aluOp = Palu_SUB; break;
1440f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_And8: case Iop_And16: case Iop_And32: case Iop_And64:
1441f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         aluOp = Palu_AND; break;
1442f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_Or8:  case Iop_Or16:  case Iop_Or32:  case Iop_Or64:
1443f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         aluOp = Palu_OR; break;
1444f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_Xor8: case Iop_Xor16: case Iop_Xor32: case Iop_Xor64:
1445f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         aluOp = Palu_XOR; break;
1446f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
1447f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         aluOp = Palu_INVALID; break;
14482c49e036c365df707cd8e6622d66382f380557b2cerion      }
14492c49e036c365df707cd8e6622d66382f380557b2cerion      /* For commutative ops we assume any literal
14502c49e036c365df707cd8e6622d66382f380557b2cerion         values are on the second operand. */
14512c49e036c365df707cd8e6622d66382f380557b2cerion      if (aluOp != Palu_INVALID) {
14525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         HReg   r_dst   = newVRegI(env);
14531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
14545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCRH* ri_srcR = NULL;
1455b51f0f4f33256638ed953156a2635aa739b232f1sewardj         /* get right arg into an RH, in the appropriate way */
1456b51f0f4f33256638ed953156a2635aa739b232f1sewardj         switch (aluOp) {
1457f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         case Palu_ADD: case Palu_SUB:
14582bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            ri_srcR = iselWordExpr_RH(env, True/*signed*/,
14591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      e->Iex.Binop.arg2, IEndianess);
1460f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            break;
1461f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         case Palu_AND: case Palu_OR: case Palu_XOR:
14622bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            ri_srcR = iselWordExpr_RH(env, False/*signed*/,
14631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      e->Iex.Binop.arg2, IEndianess);
1464f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            break;
1465bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         default:
14662bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            vpanic("iselWordExpr_R_wrk-aluOp-arg2");
1467bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         }
14685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(aluOp, r_dst, r_srcL, ri_srcR));
1469bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return r_dst;
1470bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
1471bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion
1472bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      /* a shift? */
1473bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      switch (e->Iex.Binop.op) {
1474bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Iop_Shl8: case Iop_Shl16: case Iop_Shl32: case Iop_Shl64:
1475bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         shftOp = Pshft_SHL; break;
1476bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Iop_Shr8: case Iop_Shr16: case Iop_Shr32: case Iop_Shr64:
1477bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         shftOp = Pshft_SHR; break;
1478bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Iop_Sar8: case Iop_Sar16: case Iop_Sar32: case Iop_Sar64:
1479bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         shftOp = Pshft_SAR; break;
1480bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      default:
1481bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         shftOp = Pshft_INVALID; break;
1482bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
1483bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      /* we assume any literal values are on the second operand. */
1484bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      if (shftOp != Pshft_INVALID) {
14855b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         HReg   r_dst   = newVRegI(env);
14861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
14875b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCRH* ri_srcR = NULL;
1488bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         /* get right arg into an RH, in the appropriate way */
1489bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         switch (shftOp) {
1490bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         case Pshft_SHL: case Pshft_SHR: case Pshft_SAR:
1491f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            if (!mode64)
14921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2, IEndianess);
1493f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            else
14941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               ri_srcR = iselWordExpr_RH6u(env, e->Iex.Binop.arg2, IEndianess);
1495f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            break;
1496f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         default:
1497bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion            vpanic("iselIntExpr_R_wrk-shftOp-arg2");
149801ca53eabcfe735a7b4a779456c3f420b9ce6f29cerion         }
1499f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         /* widen the left arg if needed */
1500bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         if (shftOp == Pshft_SHR || shftOp == Pshft_SAR) {
1501bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion            if (ty == Ity_I8 || ty == Ity_I16) {
15025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCRH* amt = PPCRH_Imm(False,
15035b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                      toUShort(ty == Ity_I8 ? 24 : 16));
15045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               HReg   tmp = newVRegI(env);
15055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               addInstr(env, PPCInstr_Shft(Pshft_SHL,
15065b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           True/*32bit shift*/,
15075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           tmp, r_srcL, amt));
15085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               addInstr(env, PPCInstr_Shft(shftOp,
15095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           True/*32bit shift*/,
15105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           tmp, tmp,    amt));
1511f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion               r_srcL = tmp;
1512f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion               vassert(0); /* AWAITING TEST CASE */
1513f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            }
1514f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
1515bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         /* Only 64 expressions need 64bit shifts,
1516bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion            32bit shifts are fine for all others */
1517bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         if (ty == Ity_I64) {
1518bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion            vassert(mode64);
15195b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Shft(shftOp, False/*64bit shift*/,
15205b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                        r_dst, r_srcL, ri_srcR));
1521bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         } else {
15225b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Shft(shftOp, True/*32bit shift*/,
15235b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                        r_dst, r_srcL, ri_srcR));
1524bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         }
1525a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
15262c49e036c365df707cd8e6622d66382f380557b2cerion      }
15275e2527ea1c98cdfcace8190dd631153195fb52f7cerion
1528c0e707e9b29f43821a5b505a468107992426aa7ecerion      /* How about a div? */
1529b51f0f4f33256638ed953156a2635aa739b232f1sewardj      if (e->Iex.Binop.op == Iop_DivS32 ||
15304aa412af1d8166cc11f39a6e721df49431d23618sewardj          e->Iex.Binop.op == Iop_DivU32 ||
1531e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj          e->Iex.Binop.op == Iop_DivS32E ||
15324aa412af1d8166cc11f39a6e721df49431d23618sewardj          e->Iex.Binop.op == Iop_DivU32E) {
1533e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj         Bool syned  = toBool((e->Iex.Binop.op == Iop_DivS32) || (e->Iex.Binop.op == Iop_DivS32E));
1534bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg r_dst  = newVRegI(env);
15351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
15361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
15374aa412af1d8166cc11f39a6e721df49431d23618sewardj         addInstr( env,
1538e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                      PPCInstr_Div( ( ( e->Iex.Binop.op == Iop_DivU32E )
1539e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                             || ( e->Iex.Binop.op == Iop_DivS32E ) ) ? True
1540e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                                                                     : False,
1541e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    syned,
1542e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    True/*32bit div*/,
1543e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    r_dst,
1544e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    r_srcL,
1545e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    r_srcR ) );
1546bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return r_dst;
1547bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
1548bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      if (e->Iex.Binop.op == Iop_DivS64 ||
1549e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj          e->Iex.Binop.op == Iop_DivU64 || e->Iex.Binop.op == Iop_DivS64E
1550e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj          || e->Iex.Binop.op == Iop_DivU64E ) {
15514aa412af1d8166cc11f39a6e721df49431d23618sewardj         Bool syned  = toBool((e->Iex.Binop.op == Iop_DivS64) ||(e->Iex.Binop.op == Iop_DivS64E));
1552a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst  = newVRegI(env);
15531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
15541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
1555bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         vassert(mode64);
15564aa412af1d8166cc11f39a6e721df49431d23618sewardj         addInstr( env,
1557e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                      PPCInstr_Div( ( ( e->Iex.Binop.op == Iop_DivS64E )
1558e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                             || ( e->Iex.Binop.op
1559e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                                      == Iop_DivU64E ) ) ? True
1560e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                                                         : False,
1561e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    syned,
1562e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    False/*64bit div*/,
1563e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    r_dst,
1564e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    r_srcL,
1565e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj                                    r_srcR ) );
1566a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
1567c0e707e9b29f43821a5b505a468107992426aa7ecerion      }
1568c0e707e9b29f43821a5b505a468107992426aa7ecerion
156998411db016ecb3bd1b8b72f75e4e3a49c95f4882cerion      /* No? Anyone for a mul? */
15702bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->Iex.Binop.op == Iop_Mul32
15712bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          || e->Iex.Binop.op == Iop_Mul64) {
1572f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         Bool syned       = False;
1573bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         Bool sz32        = (e->Iex.Binop.op != Iop_Mul64);
1574b51f0f4f33256638ed953156a2635aa739b232f1sewardj         HReg r_dst       = newVRegI(env);
15751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL      = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
15761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR      = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
15775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(syned, False/*lo32*/, sz32,
15785b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     r_dst, r_srcL, r_srcR));
1579a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
158098411db016ecb3bd1b8b72f75e4e3a49c95f4882cerion      }
158198411db016ecb3bd1b8b72f75e4e3a49c95f4882cerion
1582bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      /* 32 x 32 -> 64 multiply */
15832bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (mode64
15842bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && (e->Iex.Binop.op == Iop_MullU32
15852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj              || e->Iex.Binop.op == Iop_MullS32)) {
1586bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg tLo    = newVRegI(env);
1587bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg tHi    = newVRegI(env);
1588bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg r_dst  = newVRegI(env);
1589bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         Bool syned  = toBool(e->Iex.Binop.op == Iop_MullS32);
15901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
15911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
15925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(False/*signedness irrelevant*/,
15935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     False/*lo32*/, True/*32bit mul*/,
15945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, r_srcL, r_srcR));
15955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(syned,
15965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     True/*hi32*/, True/*32bit mul*/,
15975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tHi, r_srcL, r_srcR));
15985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,
15995b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     r_dst, tHi, PPCRH_Imm(False,32)));
16005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_OR,
16015b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_dst, r_dst, PPCRH_Reg(tLo)));
1602bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return r_dst;
1603bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
1604bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion
1605b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* El-mutanto 3-way compare? */
16062bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->Iex.Binop.op == Iop_CmpORD32S
16072bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          || e->Iex.Binop.op == Iop_CmpORD32U) {
16085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         Bool   syned = toBool(e->Iex.Binop.op == Iop_CmpORD32S);
16095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         HReg   dst   = newVRegI(env);
16101f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
16111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRH* srcR  = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2,
16121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IEndianess);
16135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Cmp(syned, True/*32bit cmp*/,
16145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    7/*cr*/, srcL, srcR));
16155b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MfCR(dst));
16165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND, dst, dst,
16175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    PPCRH_Imm(False,7<<1)));
1618bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return dst;
1619bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
1620bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion
16212bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->Iex.Binop.op == Iop_CmpORD64S
16222bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          || e->Iex.Binop.op == Iop_CmpORD64U) {
16235b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         Bool   syned = toBool(e->Iex.Binop.op == Iop_CmpORD64S);
16245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         HReg   dst   = newVRegI(env);
16251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
16261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRH* srcR  = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2,
16271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IEndianess);
1628bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         vassert(mode64);
16295b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Cmp(syned, False/*64bit cmp*/,
16305b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    7/*cr*/, srcL, srcR));
16315b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MfCR(dst));
16325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND, dst, dst,
16335b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    PPCRH_Imm(False,7<<1)));
1634b51f0f4f33256638ed953156a2635aa739b232f1sewardj         return dst;
1635b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
1636b51f0f4f33256638ed953156a2635aa739b232f1sewardj
1637478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      if (e->Iex.Binop.op == Iop_Max32U) {
16381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg        r1   = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
16391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg        r2   = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
1640478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg        rdst = newVRegI(env);
1641478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         PPCCondCode cc   = mk_PPCCondCode( Pct_TRUE, Pcf_7LT );
1642478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, mk_iMOVds_RR(rdst, r1));
1643478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
1644478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj                                    7/*cr*/, rdst, PPCRH_Reg(r2)));
1645478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_CMov(cc, rdst, PPCRI_Reg(r2)));
1646478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         return rdst;
1647478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      }
1648478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj
164988a9908b9b2a58daee177e33f90e59f4f9627259cerion      if (e->Iex.Binop.op == Iop_32HLto64) {
16501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_Hi  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
16511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_Lo  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
165291639685ee6dbad9fe01af2d8a4841f19faff5efcarll         HReg   r_Tmp = newVRegI(env);
1653dba87e2eb883914b8c1bc3ef05a1147dd4f930eacerion         HReg   r_dst = newVRegI(env);
1654dba87e2eb883914b8c1bc3ef05a1147dd4f930eacerion         HReg   msk   = newVRegI(env);
165588a9908b9b2a58daee177e33f90e59f4f9627259cerion         vassert(mode64);
165688a9908b9b2a58daee177e33f90e59f4f9627259cerion         /* r_dst = OR( r_Hi<<32, r_Lo ) */
165788a9908b9b2a58daee177e33f90e59f4f9627259cerion         addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,
165888a9908b9b2a58daee177e33f90e59f4f9627259cerion                                     r_dst, r_Hi, PPCRH_Imm(False,32)));
1659dba87e2eb883914b8c1bc3ef05a1147dd4f930eacerion         addInstr(env, PPCInstr_LI(msk, 0xFFFFFFFF, mode64));
166091639685ee6dbad9fe01af2d8a4841f19faff5efcarll         addInstr(env, PPCInstr_Alu( Palu_AND, r_Tmp, r_Lo,
1661dba87e2eb883914b8c1bc3ef05a1147dd4f930eacerion                                     PPCRH_Reg(msk) ));
166288a9908b9b2a58daee177e33f90e59f4f9627259cerion         addInstr(env, PPCInstr_Alu( Palu_OR, r_dst, r_dst,
166391639685ee6dbad9fe01af2d8a4841f19faff5efcarll                                     PPCRH_Reg(r_Tmp) ));
166488a9908b9b2a58daee177e33f90e59f4f9627259cerion         return r_dst;
166588a9908b9b2a58daee177e33f90e59f4f9627259cerion      }
166688a9908b9b2a58daee177e33f90e59f4f9627259cerion
1667a7b0d10848b63ff9d0608187c13134aded7a3c47florian      if ((e->Iex.Binop.op == Iop_CmpF64) ||
1668a7b0d10848b63ff9d0608187c13134aded7a3c47florian          (e->Iex.Binop.op == Iop_CmpD64) ||
1669cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj          (e->Iex.Binop.op == Iop_CmpD128)) {
1670cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg fr_srcL;
1671cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg fr_srcL_lo;
1672cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg fr_srcR;
1673cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg fr_srcR_lo;
1674094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
16755b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         HReg r_ccPPC   = newVRegI(env);
1676094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg r_ccIR    = newVRegI(env);
1677094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg r_ccIR_b0 = newVRegI(env);
1678094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg r_ccIR_b2 = newVRegI(env);
1679094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg r_ccIR_b6 = newVRegI(env);
1680094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
1681cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         if (e->Iex.Binop.op == Iop_CmpF64) {
16821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            fr_srcL = iselDblExpr(env, e->Iex.Binop.arg1, IEndianess);
16831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            fr_srcR = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
1684cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            addInstr(env, PPCInstr_FpCmp(r_ccPPC, fr_srcL, fr_srcR));
1685cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1686cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         } else if (e->Iex.Binop.op == Iop_CmpD64) {
16871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            fr_srcL = iselDfp64Expr(env, e->Iex.Binop.arg1, IEndianess);
16881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            fr_srcR = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
1689cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            addInstr(env, PPCInstr_Dfp64Cmp(r_ccPPC, fr_srcL, fr_srcR));
1690cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1691cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         } else {    //  e->Iex.Binop.op == Iop_CmpD128
16921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselDfp128Expr(&fr_srcL, &fr_srcL_lo, env, e->Iex.Binop.arg1,
16931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
16941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselDfp128Expr(&fr_srcR, &fr_srcR_lo, env, e->Iex.Binop.arg2,
16951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
1696cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            addInstr(env, PPCInstr_Dfp128Cmp(r_ccPPC, fr_srcL, fr_srcL_lo,
1697cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                             fr_srcR, fr_srcR_lo));
1698cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         }
1699094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
17005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         /* Map compare result from PPC to IR,
1701094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion            conforming to CmpF64 definition. */
1702094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         /*
1703094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion           FP cmp result | PPC | IR
1704094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion           --------------------------
1705094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion           UN            | 0x1 | 0x45
1706094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion           EQ            | 0x2 | 0x40
1707094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion           GT            | 0x4 | 0x00
1708094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion           LT            | 0x8 | 0x01
1709094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         */
1710094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
17115b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         // r_ccIR_b0 = r_ccPPC[0] | r_ccPPC[3]
17125b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHR, True/*32bit shift*/,
17135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     r_ccIR_b0, r_ccPPC,
17145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     PPCRH_Imm(False,0x3)));
17155b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_OR,  r_ccIR_b0,
17165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccPPC,   PPCRH_Reg(r_ccIR_b0)));
17175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND, r_ccIR_b0,
17185b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccIR_b0, PPCRH_Imm(False,0x1)));
1719094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
17205b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         // r_ccIR_b2 = r_ccPPC[0]
17215b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
17225b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     r_ccIR_b2, r_ccPPC,
17235b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     PPCRH_Imm(False,0x2)));
17245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND, r_ccIR_b2,
17255b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccIR_b2, PPCRH_Imm(False,0x4)));
17265b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion
17275b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         // r_ccIR_b6 = r_ccPPC[0] | r_ccPPC[1]
17285b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHR, True/*32bit shift*/,
17295b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     r_ccIR_b6, r_ccPPC,
17305b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     PPCRH_Imm(False,0x1)));
17315b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_OR,  r_ccIR_b6,
17325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccPPC, PPCRH_Reg(r_ccIR_b6)));
17335b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
17345b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     r_ccIR_b6, r_ccIR_b6,
17355b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     PPCRH_Imm(False,0x6)));
17365b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND, r_ccIR_b6,
17375b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccIR_b6, PPCRH_Imm(False,0x40)));
1738b51f0f4f33256638ed953156a2635aa739b232f1sewardj
1739b51f0f4f33256638ed953156a2635aa739b232f1sewardj         // r_ccIR = r_ccIR_b0 | r_ccIR_b2 | r_ccIR_b6
17405b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_OR, r_ccIR,
17415b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccIR_b0, PPCRH_Reg(r_ccIR_b2)));
17425b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_OR, r_ccIR,
17435b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_ccIR,    PPCRH_Reg(r_ccIR_b6)));
1744094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return r_ccIR;
1745094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
1746cd304497d9d869f9b24a002299d3953ee072229bcerion
17474aa412af1d8166cc11f39a6e721df49431d23618sewardj      if ( e->Iex.Binop.op == Iop_F64toI32S ||
17484aa412af1d8166cc11f39a6e721df49431d23618sewardj               e->Iex.Binop.op == Iop_F64toI32U ) {
174992923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         /* This works in both mode64 and mode32. */
175092923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         HReg      r1      = StackFramePtr(env->mode64);
175192923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
17521f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg      fsrc    = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
175392923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         HReg      ftmp    = newVRegF(env);
175492923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         HReg      idst    = newVRegI(env);
17557fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
1756094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         /* Set host rounding mode */
17571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
1758cd304497d9d869f9b24a002299d3953ee072229bcerion
1759094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         sub_from_sp( env, 16 );
17607d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpCftI(False/*F->I*/, True/*int32*/,
17614aa412af1d8166cc11f39a6e721df49431d23618sewardj                                       e->Iex.Binop.op == Iop_F64toI32S ? True/*syned*/
17624aa412af1d8166cc11f39a6e721df49431d23618sewardj                                                                     : False,
17634aa412af1d8166cc11f39a6e721df49431d23618sewardj                                       True/*flt64*/,
17647d810d793616af057ce861746aa985df3304cb86sewardj                                       ftmp, fsrc));
176592923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         addInstr(env, PPCInstr_FpSTFIW(r1, ftmp));
17667fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         addInstr(env, PPCInstr_Load(4, idst, zero_r1, mode64));
17677fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
17687fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         /* in 64-bit mode we need to sign-widen idst. */
17697fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         if (mode64)
17707fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_Unary(Pun_EXTSW, idst, idst));
17717fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
1772094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         add_to_sp( env, 16 );
1773094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
1774b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         ///* Restore default FPU rounding. */
1775b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         //set_FPU_rounding_default( env );
177692923de6a68e5c84365b1fe5799c79815fd7d8e6sewardj         return idst;
1777094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
1778cd304497d9d869f9b24a002299d3953ee072229bcerion
17794aa412af1d8166cc11f39a6e721df49431d23618sewardj      if (e->Iex.Binop.op == Iop_F64toI64S || e->Iex.Binop.op == Iop_F64toI64U ) {
17807fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         if (mode64) {
17817fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg      r1      = StackFramePtr(env->mode64);
17827fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
17831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg      fsrc    = iselDblExpr(env, e->Iex.Binop.arg2,
17841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess);
17857fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg      idst    = newVRegI(env);
17867fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg      ftmp    = newVRegF(env);
17877fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
17887fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            /* Set host rounding mode */
17891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
17907fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
17917fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            sub_from_sp( env, 16 );
17924aa412af1d8166cc11f39a6e721df49431d23618sewardj            addInstr(env, PPCInstr_FpCftI(False/*F->I*/, False/*int64*/,
17934aa412af1d8166cc11f39a6e721df49431d23618sewardj                                          ( e->Iex.Binop.op == Iop_F64toI64S ) ? True
17944aa412af1d8166cc11f39a6e721df49431d23618sewardj                                                                            : False,
179566d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj                                          True, ftmp, fsrc));
17967fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
17977fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_Load(8, idst, zero_r1, True/*mode64*/));
17987fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            add_to_sp( env, 16 );
17997fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
1800b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
1801b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
18027fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            return idst;
18037fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         }
180407b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      }
180507b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
1806cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (e->Iex.Binop.op == Iop_D64toI64S ) {
1807cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      r1      = StackFramePtr(env->mode64);
1808cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
18091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg      fr_src  = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
1810cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      idst    = newVRegI(env);
1811cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      ftmp    = newVRegF(env);
1812cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
1813cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Set host rounding mode */
18141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
1815cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DCTFIX, ftmp, fr_src));
1816cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
1817cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
1818cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(8, idst, zero_r1, mode64));
1819cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
1820cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
1821cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
1822cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         ///* Restore default FPU rounding. */
1823cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         //set_FPU_rounding_default( env );
1824cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return idst;
1825cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
1826cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
1827cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (e->Iex.Binop.op == Iop_D128toI64S ) {
1828cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCFpOp fpop = Pfp_DCTFIXQ;
1829cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcHi = newVRegF(env);
1830cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcLo = newVRegF(env);
1831cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg idst    = newVRegI(env);
1832cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg ftmp    = newVRegF(env);
1833cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
1834cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
18351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
18361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
18371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
1838cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpD128toD64(fpop, ftmp, r_srcHi, r_srcLo));
1839cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
1840cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the D64 result into an integer register
1841cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
1842cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
1843cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(8, idst, zero_r1, True/*mode64*/));
1844cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
1845cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return idst;
1846cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
18472c49e036c365df707cd8e6622d66382f380557b2cerion      break;
18482c49e036c365df707cd8e6622d66382f380557b2cerion   }
1849cd304497d9d869f9b24a002299d3953ee072229bcerion
18502c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- UNARY OP --------- */
18512c49e036c365df707cd8e6622d66382f380557b2cerion   case Iex_Unop: {
18525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IROp op_unop = e->Iex.Unop.op;
18535b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion
18542c49e036c365df707cd8e6622d66382f380557b2cerion      /* 1Uto8(32to1(expr32)) */
18552c49e036c365df707cd8e6622d66382f380557b2cerion      DEFINE_PATTERN(p_32to1_then_1Uto8,
18562c49e036c365df707cd8e6622d66382f380557b2cerion                     unop(Iop_1Uto8,unop(Iop_32to1,bind(0))));
18572c49e036c365df707cd8e6622d66382f380557b2cerion      if (matchIRExpr(&mi,p_32to1_then_1Uto8,e)) {
18582c49e036c365df707cd8e6622d66382f380557b2cerion         IRExpr* expr32 = mi.bindee[0];
1859a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = newVRegI(env);
18601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, expr32, IEndianess);
18615b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND, r_dst,
18625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    r_src, PPCRH_Imm(False,1)));
1863a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
18642c49e036c365df707cd8e6622d66382f380557b2cerion      }
1865cd304497d9d869f9b24a002299d3953ee072229bcerion
1866af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj      /* 16Uto32(LDbe:I16(expr32)) */
18672c49e036c365df707cd8e6622d66382f380557b2cerion      {
1868af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         DECLARE_PATTERN(p_LDbe16_then_16Uto32);
1869af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         DEFINE_PATTERN(p_LDbe16_then_16Uto32,
1870af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj                        unop(Iop_16Uto32,
18711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             IRExpr_Load(IEndianess,Ity_I16,bind(0))) );
1872af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         if (matchIRExpr(&mi,p_LDbe16_then_16Uto32,e)) {
1873a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion            HReg r_dst = newVRegI(env);
1874e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj            PPCAMode* amode
18751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               = iselWordExpr_AMode( env, mi.bindee[0], Ity_I16/*xfer*/,
18761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess );
18777fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_Load(2,r_dst,amode, mode64));
1878a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion            return r_dst;
18792c49e036c365df707cd8e6622d66382f380557b2cerion         }
18802c49e036c365df707cd8e6622d66382f380557b2cerion      }
18812c49e036c365df707cd8e6622d66382f380557b2cerion
18825b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (op_unop) {
1883ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_8Uto16:
1884ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_8Uto32:
1885f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_8Uto64:
1886f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_16Uto32:
1887f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_16Uto64: {
1888c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj         HReg   r_dst = newVRegI(env);
18891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
18905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         UShort mask  = toUShort(op_unop==Iop_16Uto64 ? 0xFFFF :
18915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 op_unop==Iop_16Uto32 ? 0xFFFF : 0xFF);
18925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Alu(Palu_AND,r_dst,r_src,
18935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                    PPCRH_Imm(False,mask)));
1894a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
1895ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
1896f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_32Uto64: {
1897f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_dst = newVRegI(env);
18981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
1899f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(mode64);
19005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19015b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,
19025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_src, PPCRH_Imm(False,32)));
19035b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SHR, False/*64bit shift*/,
19055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_dst, PPCRH_Imm(False,32)));
1906f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return r_dst;
1907f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
1908ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_8Sto16:
1909ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_8Sto32:
1910bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Iop_16Sto32: {
1911bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg   r_dst = newVRegI(env);
19121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
19135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         UShort amt   = toUShort(op_unop==Iop_16Sto32 ? 16 : 24);
19145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19155b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
19165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_src, PPCRH_Imm(False,amt)));
19175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19185b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
19195b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_dst, PPCRH_Imm(False,amt)));
1920bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return r_dst;
1921bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
1922bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Iop_8Sto64:
1923eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_16Sto64: {
1924c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj         HReg   r_dst = newVRegI(env);
19251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
19267a08c10a6fc8b26b5442ad438a6819d3ad6ae4adflorian         UShort amt   = toUShort(op_unop==Iop_8Sto64  ? 56 : 48);
1927bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         vassert(mode64);
19285b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19295b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,
19305b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_src, PPCRH_Imm(False,amt)));
19315b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SAR, False/*64bit shift*/,
19335b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_dst, PPCRH_Imm(False,amt)));
1934a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
1935ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
1936eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_32Sto64: {
1937eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg   r_dst = newVRegI(env);
19381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
1939eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj	 vassert(mode64);
1940eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         /* According to the IBM docs, in 64 bit mode, srawi r,r,0
1941eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj            sign extends the lower 32 bits into the upper 32 bits. */
1942eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env,
1943eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                  PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
1944eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                r_dst, r_src, PPCRH_Imm(False,0)));
1945eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         return r_dst;
1946eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      }
1947ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_Not8:
1948ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_Not16:
1949f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_Not32:
1950f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_Not64: {
1951d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         if (op_unop == Iop_Not64) vassert(mode64);
1952a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = newVRegI(env);
19531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
19545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Unary(Pun_NOT,r_dst,r_src));
1955a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
1956ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
1957ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_64HIto32: {
1958f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         if (!mode64) {
1959f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            HReg rHi, rLo;
19601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg, IEndianess);
1961f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            return rHi; /* and abandon rLo .. poor wee thing :-) */
1962f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         } else {
1963f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            HReg   r_dst = newVRegI(env);
19641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
19655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env,
19665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                     PPCInstr_Shft(Pshft_SHR, False/*64bit shift*/,
19675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                   r_dst, r_src, PPCRH_Imm(False,32)));
1968f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            return r_dst;
1969f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
1970ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
1971ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_64to32: {
1972f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         if (!mode64) {
1973f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            HReg rHi, rLo;
19741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg, IEndianess);
1975f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            return rLo; /* similar stupid comment to the above ... */
1976f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         } else {
1977f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* This is a no-op. */
19781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            return iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
1979f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
1980f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
1981f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_64to16: {
1982f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         if (mode64) { /* This is a no-op. */
19831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            return iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
1984f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
19852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         break; /* evidently not used in 32-bit mode */
1986ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
1987ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_16HIto8:
1988ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_32HIto16: {
1989c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj         HReg   r_dst = newVRegI(env);
19901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
19915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         UShort shift = toUShort(op_unop == Iop_16HIto8 ? 8 : 16);
19925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
19935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SHR, True/*32bit shift*/,
19945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_src, PPCRH_Imm(False,shift)));
1995a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
1996ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
19972bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      case Iop_128HIto64:
19982bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         if (mode64) {
19992bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            HReg rHi, rLo;
20001f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt128Expr(&rHi,&rLo, env, e->Iex.Unop.arg, IEndianess);
20012bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            return rHi; /* and abandon rLo .. poor wee thing :-) */
20022bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         }
20032bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         break;
20042bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      case Iop_128to64:
20052bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         if (mode64) {
20062bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            HReg rHi, rLo;
20071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt128Expr(&rHi,&rLo, env, e->Iex.Unop.arg, IEndianess);
20082bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            return rLo; /* similar stupid comment to the above ... */
20092bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         }
20102bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         break;
20119627fe8ab46ad30954941812f330aa358b9cacf3florian      case Iop_1Uto64:
2012ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_1Uto32:
20139627fe8ab46ad30954941812f330aa358b9cacf3florian      case Iop_1Uto8:
20149627fe8ab46ad30954941812f330aa358b9cacf3florian         if ((op_unop != Iop_1Uto64) || mode64) {
20159627fe8ab46ad30954941812f330aa358b9cacf3florian            HReg        r_dst = newVRegI(env);
20161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            PPCCondCode cond  = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
20179627fe8ab46ad30954941812f330aa358b9cacf3florian            addInstr(env, PPCInstr_Set(cond,r_dst));
20189627fe8ab46ad30954941812f330aa358b9cacf3florian            return r_dst;
20199627fe8ab46ad30954941812f330aa358b9cacf3florian         }
20209627fe8ab46ad30954941812f330aa358b9cacf3florian         break;
2021ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_1Sto8:
2022ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_1Sto16:
2023ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_1Sto32: {
2024ab9132df645da753ae6b0421d551ea5c024aa6e6cerion         /* could do better than this, but for now ... */
20255b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         HReg        r_dst = newVRegI(env);
20261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cond  = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
20275b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Set(cond,r_dst));
20285b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
20295b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
20305b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_dst, PPCRH_Imm(False,31)));
20315b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
20325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
20335b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                r_dst, r_dst, PPCRH_Imm(False,31)));
2034a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
2035ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
20362bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      case Iop_1Sto64:
20372bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         if (mode64) {
20382bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            /* could do better than this, but for now ... */
20392bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            HReg        r_dst = newVRegI(env);
20401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            PPCCondCode cond  = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
20412bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            addInstr(env, PPCInstr_Set(cond,r_dst));
20422bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,
20432bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                        r_dst, r_dst, PPCRH_Imm(False,63)));
20442bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            addInstr(env, PPCInstr_Shft(Pshft_SAR, False/*64bit shift*/,
20452bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                        r_dst, r_dst, PPCRH_Imm(False,63)));
20462bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            return r_dst;
20472bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         }
20482bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         break;
204907b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      case Iop_Clz32:
205007b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      case Iop_Clz64: {
2051633274098fafebdc79cf1c8a1ef7f9a9914669f1sewardj         HReg r_src, r_dst;
20525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCUnaryOp op_clz = (op_unop == Iop_Clz32) ? Pun_CLZ32 :
20535b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                                      Pun_CLZ64;
20542bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         if (op_unop == Iop_Clz64 && !mode64)
20552bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            goto irreducible;
2056ab9132df645da753ae6b0421d551ea5c024aa6e6cerion         /* Count leading zeroes. */
2057633274098fafebdc79cf1c8a1ef7f9a9914669f1sewardj         r_dst = newVRegI(env);
20581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
20595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Unary(op_clz,r_dst,r_src));
2060a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
2061ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      }
2062eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj
2063eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_Left8:
2064a25732d38e6cc810c032eb99503e77438a6e8153florian      case Iop_Left16:
2065eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_Left32:
2066eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_Left64: {
2067eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg r_src, r_dst;
2068eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         if (op_unop == Iop_Left64 && !mode64)
2069eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj            goto irreducible;
2070eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         r_dst = newVRegI(env);
20711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
2072eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Unary(Pun_NEG,r_dst,r_src));
2073eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, r_dst, r_dst, PPCRH_Reg(r_src)));
2074eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         return r_dst;
2075eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      }
2076eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj
2077eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_CmpwNEZ32: {
2078ed623dbefb52ca3211490d656abc999a129df060cerion         HReg r_dst = newVRegI(env);
20791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
20805b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Unary(Pun_NEG,r_dst,r_src));
2081eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, r_dst, r_dst, PPCRH_Reg(r_src)));
2082eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
2083eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                     r_dst, r_dst, PPCRH_Imm(False, 31)));
2084eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         return r_dst;
2085eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      }
2086eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj
2087eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_CmpwNEZ64: {
2088eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg r_dst = newVRegI(env);
20891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
2090eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         if (!mode64) goto irreducible;
2091eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Unary(Pun_NEG,r_dst,r_src));
2092eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, r_dst, r_dst, PPCRH_Reg(r_src)));
2093eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Shft(Pshft_SAR, False/*64bit shift*/,
2094eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                     r_dst, r_dst, PPCRH_Imm(False, 63)));
2095ed623dbefb52ca3211490d656abc999a129df060cerion         return r_dst;
2096ed623dbefb52ca3211490d656abc999a129df060cerion      }
2097cd304497d9d869f9b24a002299d3953ee072229bcerion
2098225a034683024109da729a4d2f080364b9485007cerion      case Iop_V128to32: {
2099197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         HReg        r_aligned16;
2100225a034683024109da729a4d2f080364b9485007cerion         HReg        dst  = newVRegI(env);
21011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg        vec  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
21021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCAMode *am_off0, *am_off_word0;
2103225a034683024109da729a4d2f080364b9485007cerion         sub_from_sp( env, 32 );     // Move SP down 32 bytes
2104225a034683024109da729a4d2f080364b9485007cerion
2105225a034683024109da729a4d2f080364b9485007cerion         // get a quadword aligned address within our stack space
2106197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         r_aligned16 = get_sp_aligned16( env );
21075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off0  = PPCAMode_IR( 0, r_aligned16 );
21081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
21091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         /* Note that the store below (done via PPCInstr_AvLdSt) uses
21101f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll          * stvx, which stores the vector in proper LE format,
21111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll          * with byte zero (far right byte of the register in LE format)
21121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll          * stored at the lowest memory address.  Therefore, to obtain
21131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll          * integer word zero, we need to use that lowest memory address
21141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll          * as the base for the load.
21151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll          */
21161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
21171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            am_off_word0 = am_off0;
21181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
21191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            am_off_word0 = PPCAMode_IR( 12,r_aligned16 );
2120225a034683024109da729a4d2f080364b9485007cerion
2121225a034683024109da729a4d2f080364b9485007cerion         // store vec, load low word to dst
21225b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
21235b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 ));
21245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
21251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  PPCInstr_Load( 4, dst, am_off_word0, mode64 ));
2126225a034683024109da729a4d2f080364b9485007cerion
2127225a034683024109da729a4d2f080364b9485007cerion         add_to_sp( env, 32 );       // Reset SP
2128225a034683024109da729a4d2f080364b9485007cerion         return dst;
2129225a034683024109da729a4d2f080364b9485007cerion      }
2130cd304497d9d869f9b24a002299d3953ee072229bcerion
2131aa87c71b838ba24e6355654453ac9593e7aa0905sewardj      case Iop_V128to64:
21322bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      case Iop_V128HIto64:
21332bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         if (mode64) {
21342bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            HReg     r_aligned16;
21352bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            HReg     dst = newVRegI(env);
21361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     vec = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
21371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            PPCAMode *am_off0, *am_off8, *am_off_arg;
21382bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            sub_from_sp( env, 32 );     // Move SP down 32 bytes
2139aa87c71b838ba24e6355654453ac9593e7aa0905sewardj
21402bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            // get a quadword aligned address within our stack space
21412bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            r_aligned16 = get_sp_aligned16( env );
21422bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            am_off0 = PPCAMode_IR( 0, r_aligned16 );
21432bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            am_off8 = PPCAMode_IR( 8 ,r_aligned16 );
2144aa87c71b838ba24e6355654453ac9593e7aa0905sewardj
21451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            // store vec, load low word or high to dst
21462bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            addInstr(env,
21472bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                     PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 ));
21481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            if (IEndianess == Iend_LE) {
21491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               if (op_unop == Iop_V128HIto64)
21501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  am_off_arg = am_off8;
21511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               else
21521f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  am_off_arg = am_off0;
21531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            } else {
21541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               if (op_unop == Iop_V128HIto64)
21551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  am_off_arg = am_off0;
21561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               else
21571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                  am_off_arg = am_off8;
21581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            }
21592bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            addInstr(env,
21602bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                     PPCInstr_Load(
21617fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                        8, dst,
21621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        am_off_arg,
21632bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                        mode64 ));
2164aa87c71b838ba24e6355654453ac9593e7aa0905sewardj
21652bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            add_to_sp( env, 32 );       // Reset SP
21662bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            return dst;
21672bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         }
21682bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         break;
2169ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_16to8:
2170ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_32to8:
2171ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Iop_32to16:
2172f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_64to8:
2173ab9132df645da753ae6b0421d551ea5c024aa6e6cerion         /* These are no-ops. */
21741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         return iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
2175ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
217607b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      /* ReinterpF64asI64(e) */
217707b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      /* Given an IEEE754 double, produce an I64 with the same bit
217807b07a966a2fdbcf621251a0c1a8ab84807fb120cerion         pattern. */
21792bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      case Iop_ReinterpF64asI64:
21802bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         if (mode64) {
21812bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            PPCAMode *am_addr;
21821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg fr_src = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
21832bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            HReg r_dst  = newVRegI(env);
21842bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
21852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            sub_from_sp( env, 16 );     // Move SP down 16 bytes
21862bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            am_addr = PPCAMode_IR( 0, StackFramePtr(mode64) );
21872bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
21882bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            // store as F64
21892bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
21902bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                           fr_src, am_addr ));
21912bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            // load as Ity_I64
21927fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_Load( 8, r_dst, am_addr, mode64 ));
21932bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
21942bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            add_to_sp( env, 16 );       // Reset SP
21952bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj            return r_dst;
21962bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         }
21972bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         break;
219807b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
2199c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj      /* ReinterpF32asI32(e) */
2200c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj      /* Given an IEEE754 float, produce an I32 with the same bit
2201c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         pattern. */
2202c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj      case Iop_ReinterpF32asI32: {
2203c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         /* I believe this generates correct code for both 32- and
2204c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj            64-bit hosts. */
2205c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         PPCAMode *am_addr;
22061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselFltExpr(env, e->Iex.Unop.arg, IEndianess);
2207c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         HReg r_dst  = newVRegI(env);
2208c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj
2209c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         sub_from_sp( env, 16 );     // Move SP down 16 bytes
2210c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         am_addr = PPCAMode_IR( 0, StackFramePtr(mode64) );
2211c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj
2212c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         // store as F32
2213c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 4,
2214c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj                                        fr_src, am_addr ));
2215c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         // load as Ity_I32
2216c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         addInstr(env, PPCInstr_Load( 4, r_dst, am_addr, mode64 ));
2217c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj
2218c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         add_to_sp( env, 16 );       // Reset SP
2219c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj         return r_dst;
2220c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj      }
22215eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      break;
22225eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
22235eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      case Iop_ReinterpD64asI64:
22245eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         if (mode64) {
22255eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            PPCAMode *am_addr;
22261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg fr_src = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
22275eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            HReg r_dst  = newVRegI(env);
22285eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
22295eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            sub_from_sp( env, 16 );     // Move SP down 16 bytes
22305eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            am_addr = PPCAMode_IR( 0, StackFramePtr(mode64) );
22315eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
22325eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            // store as D64
22335eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
22345eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                           fr_src, am_addr ));
22355eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            // load as Ity_I64
22365eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            addInstr(env, PPCInstr_Load( 8, r_dst, am_addr, mode64 ));
22375eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            add_to_sp( env, 16 );       // Reset SP
22385eff1c502e995d1f9668cc9def72d5db59f21b13sewardj            return r_dst;
22395eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         }
22405eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         break;
2241c07349e10b1ac3e3016a48a4cbfb3f9506e91692sewardj
22424c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      case Iop_BCDtoDPB: {
2243cfe046e178666280b87da998b1b52ecda03ecd89sewardj         /* the following is only valid in 64 bit mode */
2244cfe046e178666280b87da998b1b52ecda03ecd89sewardj         if (!mode64) break;
2245cfe046e178666280b87da998b1b52ecda03ecd89sewardj
22464c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCCondCode cc;
22474c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         UInt        argiregs;
22484c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        argregs[1];
22494c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        r_dst  = newVRegI(env);
22504c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Int         argreg;
22514c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22524c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs = 0;
22534c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argreg = 0;
22544c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[0] = hregPPC_GPR3(mode64);
22554c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22564c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= (1 << (argreg+3));
22574c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR( argregs[argreg++],
22581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     iselWordExpr_R(env, e->Iex.Unop.arg,
22591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                                    IEndianess) ) );
22604c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22614c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
22621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE) {
226393a09742b0de3d61718882c2d999f64be402564dflorian             addInstr(env, PPCInstr_Call( cc, (Addr)h_calc_BCDtoDPB,
22641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          argiregs,
22651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          mk_RetLoc_simple(RLPri_Int)) );
22661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         } else {
22671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll             HWord*      fdescr;
22681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll             fdescr = (HWord*)h_calc_BCDtoDPB;
22691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll             addInstr(env, PPCInstr_Call( cc, (Addr64)(fdescr[0]),
22701f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          argiregs,
22711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          mk_RetLoc_simple(RLPri_Int)) );
22721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         }
22734c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22744c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR(r_dst, argregs[0]));
22754c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         return r_dst;
22764c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      }
22774c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22784c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      case Iop_DPBtoBCD: {
2279cfe046e178666280b87da998b1b52ecda03ecd89sewardj         /* the following is only valid in 64 bit mode */
2280cfe046e178666280b87da998b1b52ecda03ecd89sewardj         if (!mode64) break;
2281cfe046e178666280b87da998b1b52ecda03ecd89sewardj
22824c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCCondCode cc;
22834c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         UInt        argiregs;
22844c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        argregs[1];
22854c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        r_dst  = newVRegI(env);
22864c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Int         argreg;
22874c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22884c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs = 0;
22894c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argreg = 0;
22904c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[0] = hregPPC_GPR3(mode64);
22914c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22924c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= (1 << (argreg+3));
22934c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR( argregs[argreg++],
22941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     iselWordExpr_R(env, e->Iex.Unop.arg,
22951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                                    IEndianess) ) );
22964c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22974c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
22984c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
22991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll        if (IEndianess == Iend_LE) {
230093a09742b0de3d61718882c2d999f64be402564dflorian            addInstr(env, PPCInstr_Call( cc, (Addr)h_calc_DPBtoBCD,
23011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         argiregs,
23021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         mk_RetLoc_simple(RLPri_Int) ) );
23031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll	} else {
23041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HWord*      fdescr;
23051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            fdescr = (HWord*)h_calc_DPBtoBCD;
23061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Call( cc, (Addr64)(fdescr[0]),
23071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         argiregs,
23081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         mk_RetLoc_simple(RLPri_Int) ) );
23091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         }
23104c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
23114c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR(r_dst, argregs[0]));
23124c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         return r_dst;
23134c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      }
23144c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
2315ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      default:
2316ab9132df645da753ae6b0421d551ea5c024aa6e6cerion         break;
23172c49e036c365df707cd8e6622d66382f380557b2cerion      }
2318cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
2319cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll     switch (e->Iex.Unop.op) {
2320cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        case Iop_ExtractExpD64: {
2321cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
2322cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg fr_dst = newVRegI(env);
23231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg fr_src = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
2324cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmp    = newVRegF(env);
2325cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
2326cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Dfp64Unary(Pfp_DXEX, tmp, fr_src));
2327cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
2328cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the D64 result into a integer register
2329cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            sub_from_sp( env, 16 );
2330cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
2331cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(8, fr_dst, zero_r1, env->mode64));
2332cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            add_to_sp( env, 16 );
2333cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            return fr_dst;
2334cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
2335cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         case Iop_ExtractExpD128: {
2336cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg fr_dst = newVRegI(env);
2337cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg r_srcHi;
2338cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg r_srcLo;
2339cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmp    = newVRegF(env);
2340cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
2341cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
23421f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Unop.arg,
23431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
2344cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_ExtractExpD128(Pfp_DXEXQ, tmp,
2345cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                                  r_srcHi, r_srcLo));
2346cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
2347cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            sub_from_sp( env, 16 );
2348cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
2349cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(8, fr_dst, zero_r1, env->mode64));
2350cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            add_to_sp( env, 16 );
2351cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            return fr_dst;
2352cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
2353cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         default:
2354cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            break;
2355cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
2356cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
23572c49e036c365df707cd8e6622d66382f380557b2cerion      break;
23582c49e036c365df707cd8e6622d66382f380557b2cerion   }
2359cd304497d9d869f9b24a002299d3953ee072229bcerion
2360cd304497d9d869f9b24a002299d3953ee072229bcerion   /* --------- GET --------- */
2361cd304497d9d869f9b24a002299d3953ee072229bcerion   case Iex_Get: {
2362f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (ty == Ity_I8  || ty == Ity_I16 ||
2363f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          ty == Ity_I32 || ((ty == Ity_I64) && mode64)) {
2364a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = newVRegI(env);
23655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
23665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                          GuestStatePtr(mode64) );
23675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Load( toUChar(sizeofIRType(ty)),
23687fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                                      r_dst, am_addr, mode64 ));
2369a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
2370cd304497d9d869f9b24a002299d3953ee072229bcerion      }
2371cd304497d9d869f9b24a002299d3953ee072229bcerion      break;
2372cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2373cd304497d9d869f9b24a002299d3953ee072229bcerion
2374aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   case Iex_GetI: {
2375aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      PPCAMode* src_am
2376aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         = genGuestArrayOffset( env, e->Iex.GetI.descr,
23771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                e->Iex.GetI.ix, e->Iex.GetI.bias,
23781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                IEndianess );
2379aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      HReg r_dst = newVRegI(env);
23806e53088a92d40be75cc362986956ac149b3fa94bsewardj      if (mode64 && ty == Ity_I64) {
23816e53088a92d40be75cc362986956ac149b3fa94bsewardj         addInstr(env, PPCInstr_Load( toUChar(8),
23827fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                                      r_dst, src_am, mode64 ));
23836e53088a92d40be75cc362986956ac149b3fa94bsewardj         return r_dst;
23846e53088a92d40be75cc362986956ac149b3fa94bsewardj      }
2385aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      if ((!mode64) && ty == Ity_I32) {
2386aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         addInstr(env, PPCInstr_Load( toUChar(4),
2387aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                      r_dst, src_am, mode64 ));
2388aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         return r_dst;
2389aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      }
23906e53088a92d40be75cc362986956ac149b3fa94bsewardj      break;
2391aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   }
2392cd304497d9d869f9b24a002299d3953ee072229bcerion
23932c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- CCALL --------- */
23942c49e036c365df707cd8e6622d66382f380557b2cerion   case Iex_CCall: {
2395f5530ec9316238e1536ac0abc26781e62e2bb13asewardj      vassert(ty == e->Iex.CCall.retty); /* well-formedness of IR */
2396cd304497d9d869f9b24a002299d3953ee072229bcerion
2397cfe046e178666280b87da998b1b52ecda03ecd89sewardj      /* be very restrictive for now.  Only 32/64-bit ints allowed for
2398f5530ec9316238e1536ac0abc26781e62e2bb13asewardj         args, and 32 bits or host machine word for return type. */
2399f5530ec9316238e1536ac0abc26781e62e2bb13asewardj      if (!(ty == Ity_I32 || (mode64 && ty == Ity_I64)))
24002c49e036c365df707cd8e6622d66382f380557b2cerion         goto irreducible;
240174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj
24022c49e036c365df707cd8e6622d66382f380557b2cerion      /* Marshal args, do the call, clear stack. */
240374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      UInt   addToSp = 0;
240474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      RetLoc rloc    = mk_RetLoc_INVALID();
240574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      doHelperCall( &addToSp, &rloc, env, NULL/*guard*/,
24061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                    e->Iex.CCall.cee, e->Iex.CCall.retty, e->Iex.CCall.args,
24071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                    IEndianess );
240874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(is_sane_RetLoc(rloc));
240974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(rloc.pri == RLPri_Int);
241074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(addToSp == 0);
2411a56e9cc23be921deeebd9df13b427b63aa661aaccerion
2412a56e9cc23be921deeebd9df13b427b63aa661aaccerion      /* GPR3 now holds the destination address from Pin_Goto */
2413f5530ec9316238e1536ac0abc26781e62e2bb13asewardj      HReg r_dst = newVRegI(env);
2414f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
2415a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion      return r_dst;
24162c49e036c365df707cd8e6622d66382f380557b2cerion   }
2417ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
24182c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- LITERAL --------- */
24192c49e036c365df707cd8e6622d66382f380557b2cerion   /* 32/16/8-bit literals */
24202c49e036c365df707cd8e6622d66382f380557b2cerion   case Iex_Const: {
2421f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      Long l;
2422b51f0f4f33256638ed953156a2635aa739b232f1sewardj      HReg r_dst = newVRegI(env);
24235b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IRConst* con = e->Iex.Const.con;
24245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (con->tag) {
24252bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         case Ico_U64: if (!mode64) goto irreducible;
24262bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                       l = (Long)            con->Ico.U64; break;
24272bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         case Ico_U32: l = (Long)(Int)       con->Ico.U32; break;
24282bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         case Ico_U16: l = (Long)(Int)(Short)con->Ico.U16; break;
24292bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         case Ico_U8:  l = (Long)(Int)(Char )con->Ico.U8;  break;
24302bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         default:      vpanic("iselIntExpr_R.const(ppc)");
2431b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
24325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_LI(r_dst, (ULong)l, mode64));
2433a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion      return r_dst;
24342c49e036c365df707cd8e6622d66382f380557b2cerion   }
2435cd304497d9d869f9b24a002299d3953ee072229bcerion
2436b536af93912b69421440c27aa0533ad77d678f85cerion   /* --------- MULTIPLEX --------- */
243799dd03e04a6914d90d5fee727d61d76905334becflorian   case Iex_ITE: { // VFD
2438f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if ((ty == Ity_I8  || ty == Ity_I16 ||
2439f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           ty == Ity_I32 || ((ty == Ity_I64) && mode64)) &&
244099dd03e04a6914d90d5fee727d61d76905334becflorian          typeOfIRExpr(env->type_env,e->Iex.ITE.cond) == Ity_I1) {
24411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* r1    = iselWordExpr_RI(env, e->Iex.ITE.iftrue, IEndianess);
24421f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r0    = iselWordExpr_R(env, e->Iex.ITE.iffalse, IEndianess);
2443009230b9758291b594e60d7c0243a73d53e81854sewardj         HReg   r_dst = newVRegI(env);
2444009230b9758291b594e60d7c0243a73d53e81854sewardj         addInstr(env, mk_iMOVds_RR(r_dst,r0));
24451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cc = iselCondCode(env, e->Iex.ITE.cond, IEndianess);
244699dd03e04a6914d90d5fee727d61d76905334becflorian         addInstr(env, PPCInstr_CMov(cc, r_dst, r1));
2447a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         return r_dst;
2448b536af93912b69421440c27aa0533ad77d678f85cerion      }
2449b536af93912b69421440c27aa0533ad77d678f85cerion      break;
2450b536af93912b69421440c27aa0533ad77d678f85cerion   }
2451ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
2452cd304497d9d869f9b24a002299d3953ee072229bcerion   default:
2453ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      break;
2454cd304497d9d869f9b24a002299d3953ee072229bcerion   } /* switch (e->tag) */
2455cd304497d9d869f9b24a002299d3953ee072229bcerion
2456ed623dbefb52ca3211490d656abc999a129df060cerion
2457cd304497d9d869f9b24a002299d3953ee072229bcerion   /* We get here if no pattern matched. */
2458cd304497d9d869f9b24a002299d3953ee072229bcerion irreducible:
2459cd304497d9d869f9b24a002299d3953ee072229bcerion   ppIRExpr(e);
24605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselIntExpr_R(ppc): cannot reduce tree");
2461cd304497d9d869f9b24a002299d3953ee072229bcerion}
2462cd304497d9d869f9b24a002299d3953ee072229bcerion
2463cd304497d9d869f9b24a002299d3953ee072229bcerion
2464cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
2465cd304497d9d869f9b24a002299d3953ee072229bcerion/*--- ISEL: Integer expression auxiliaries              ---*/
2466cd304497d9d869f9b24a002299d3953ee072229bcerion/*---------------------------------------------------------*/
2467cd304497d9d869f9b24a002299d3953ee072229bcerion
2468cd304497d9d869f9b24a002299d3953ee072229bcerion/* --------------------- AMODEs --------------------- */
2469cd304497d9d869f9b24a002299d3953ee072229bcerion
2470cd304497d9d869f9b24a002299d3953ee072229bcerion/* Return an AMode which computes the value of the specified
2471cd304497d9d869f9b24a002299d3953ee072229bcerion   expression, possibly also adding insns to the code list as a
24722bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   result.  The expression may only be a word-size one.
2473cd304497d9d869f9b24a002299d3953ee072229bcerion*/
2474cd304497d9d869f9b24a002299d3953ee072229bcerion
24752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardjstatic Bool uInt_fits_in_16_bits ( UInt u )
2476a5f957df568527d44219383f4a04a8f4028b80a2sewardj{
2477a5f957df568527d44219383f4a04a8f4028b80a2sewardj   /* Is u the same as the sign-extend of its lower 16 bits? */
2478a5f957df568527d44219383f4a04a8f4028b80a2sewardj   Int i = u & 0xFFFF;
2479a5f957df568527d44219383f4a04a8f4028b80a2sewardj   i <<= 16;
2480a5f957df568527d44219383f4a04a8f4028b80a2sewardj   i >>= 16;
2481db36c0ffa42c0fafe50d223cd0d59048af17c362sewardj   return toBool(u == (UInt)i);
2482a5f957df568527d44219383f4a04a8f4028b80a2sewardj}
2483a5f957df568527d44219383f4a04a8f4028b80a2sewardj
24842bb062db199d9799e1259ab608e8a1aea3bb29a3sewardjstatic Bool uLong_fits_in_16_bits ( ULong u )
24852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj{
24862bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* Is u the same as the sign-extend of its lower 16 bits? */
24872bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   Long i = u & 0xFFFFULL;
24882bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   i <<= 48;
24892bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   i >>= 48;
24902bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   return toBool(u == (ULong)i);
24912bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj}
24922bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
249334085e398dd703798a0d6a60e039075e03397c8fsewardjstatic Bool uLong_is_4_aligned ( ULong u )
249434085e398dd703798a0d6a60e039075e03397c8fsewardj{
249534085e398dd703798a0d6a60e039075e03397c8fsewardj   return toBool((u & 3ULL) == 0);
249634085e398dd703798a0d6a60e039075e03397c8fsewardj}
249734085e398dd703798a0d6a60e039075e03397c8fsewardj
24984628ccd1bafb946378f91849b92ffcfea0267b2ecerionstatic Bool sane_AMode ( ISelEnv* env, PPCAMode* am )
2499cd304497d9d869f9b24a002299d3953ee072229bcerion{
25004628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
2501cd304497d9d869f9b24a002299d3953ee072229bcerion   switch (am->tag) {
2502f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pam_IR:
25032bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Using uInt_fits_in_16_bits in 64-bit mode seems a bit bogus,
25042bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         somehow, but I think it's OK. */
25054628ccd1bafb946378f91849b92ffcfea0267b2ecerion      return toBool( hregClass(am->Pam.IR.base) == HRcGPR(mode64) &&
2506f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion                     hregIsVirtual(am->Pam.IR.base) &&
25072bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                     uInt_fits_in_16_bits(am->Pam.IR.index) );
2508f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pam_RR:
25094628ccd1bafb946378f91849b92ffcfea0267b2ecerion      return toBool( hregClass(am->Pam.RR.base) == HRcGPR(mode64) &&
25104628ccd1bafb946378f91849b92ffcfea0267b2ecerion                     hregIsVirtual(am->Pam.RR.base) &&
25114628ccd1bafb946378f91849b92ffcfea0267b2ecerion                     hregClass(am->Pam.RR.index) == HRcGPR(mode64) &&
2512e6be61f7fef74148e92c8c027702bec9cd99dffaflorian                     hregIsVirtual(am->Pam.RR.index) );
2513f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
25145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("sane_AMode: unknown ppc amode tag");
2515cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2516cd304497d9d869f9b24a002299d3953ee072229bcerion}
2517cd304497d9d869f9b24a002299d3953ee072229bcerion
251834085e398dd703798a0d6a60e039075e03397c8fsewardjstatic
25191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllPPCAMode* iselWordExpr_AMode ( ISelEnv* env, IRExpr* e, IRType xferTy,
25201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                               IREndness IEndianess )
2521cd304497d9d869f9b24a002299d3953ee072229bcerion{
25221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   PPCAMode* am = iselWordExpr_AMode_wrk(env, e, xferTy, IEndianess);
25234628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(sane_AMode(env, am));
2524cd304497d9d869f9b24a002299d3953ee072229bcerion   return am;
2525cd304497d9d869f9b24a002299d3953ee072229bcerion}
2526cd304497d9d869f9b24a002299d3953ee072229bcerion
2527cd304497d9d869f9b24a002299d3953ee072229bcerion/* DO NOT CALL THIS DIRECTLY ! */
25281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCAMode* iselWordExpr_AMode_wrk ( ISelEnv* env, IRExpr* e,
25291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          IRType xferTy, IREndness IEndianess )
2530cd304497d9d869f9b24a002299d3953ee072229bcerion{
2531cd304497d9d869f9b24a002299d3953ee072229bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
25322bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25332bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   if (env->mode64) {
25342bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
253534085e398dd703798a0d6a60e039075e03397c8fsewardj      /* If the data load/store type is I32 or I64, this amode might
253634085e398dd703798a0d6a60e039075e03397c8fsewardj         be destined for use in ld/ldu/lwa/st/stu.  In which case
253734085e398dd703798a0d6a60e039075e03397c8fsewardj         insist that if it comes out as an _IR, the immediate must
253834085e398dd703798a0d6a60e039075e03397c8fsewardj         have its bottom two bits be zero.  This does assume that for
253934085e398dd703798a0d6a60e039075e03397c8fsewardj         any other type (I8/I16/I128/F32/F64/V128) the amode will not
254034085e398dd703798a0d6a60e039075e03397c8fsewardj         be parked in any such instruction.  But that seems a
254134085e398dd703798a0d6a60e039075e03397c8fsewardj         reasonable assumption.  */
254234085e398dd703798a0d6a60e039075e03397c8fsewardj      Bool aligned4imm = toBool(xferTy == Ity_I32 || xferTy == Ity_I64);
254334085e398dd703798a0d6a60e039075e03397c8fsewardj
25442bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      vassert(ty == Ity_I64);
2545ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
25462bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add64(expr,i), where i == sign-extend of (i & 0xFFFF) */
25472bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25482bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add64
25492bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->tag == Iex_Const
25502bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U64
255134085e398dd703798a0d6a60e039075e03397c8fsewardj          && (aligned4imm  ? uLong_is_4_aligned(e->Iex.Binop.arg2
255234085e398dd703798a0d6a60e039075e03397c8fsewardj                                                 ->Iex.Const.con->Ico.U64)
255334085e398dd703798a0d6a60e039075e03397c8fsewardj                           : True)
25542bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && uLong_fits_in_16_bits(e->Iex.Binop.arg2
25552bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                    ->Iex.Const.con->Ico.U64)) {
25562bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_IR( (Int)e->Iex.Binop.arg2->Iex.Const.con->Ico.U64,
25571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             iselWordExpr_R(env, e->Iex.Binop.arg1,
25581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess) );
25592bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
256033aa6da1102a12139debec996c33e4effa16f77ccerion
25612bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add64(expr,expr) */
25622bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25632bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add64) {
25641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
25651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_idx  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
25662bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_RR( r_idx, r_base );
25672bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
25682bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25692bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   } else {
25702bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25712bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      vassert(ty == Ity_I32);
25722bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25732bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */
25742bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add32
25762bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->tag == Iex_Const
25772bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32
25782bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && uInt_fits_in_16_bits(e->Iex.Binop.arg2
25792bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                   ->Iex.Const.con->Ico.U32)) {
25802bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_IR( (Int)e->Iex.Binop.arg2->Iex.Const.con->Ico.U32,
25811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             iselWordExpr_R(env, e->Iex.Binop.arg1,
25821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess) );
25832bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
25842bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add32(expr,expr) */
25862bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25872bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add32) {
25881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
25891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_idx  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
25902bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_RR( r_idx, r_base );
25912bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
25922bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
2593cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2594cd304497d9d869f9b24a002299d3953ee072229bcerion
2595cd304497d9d869f9b24a002299d3953ee072229bcerion   /* Doesn't match anything in particular.  Generate it into
2596cd304497d9d869f9b24a002299d3953ee072229bcerion      a register and use that. */
25971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCAMode_IR( 0, iselWordExpr_R(env,e,IEndianess) );
2598cd304497d9d869f9b24a002299d3953ee072229bcerion}
2599cd304497d9d869f9b24a002299d3953ee072229bcerion
2600cd304497d9d869f9b24a002299d3953ee072229bcerion
2601b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* --------------------- RH --------------------- */
2602b51f0f4f33256638ed953156a2635aa739b232f1sewardj
26032bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* Compute an I8/I16/I32 (and I64, in 64-bit mode) into a RH
26042bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   (reg-or-halfword-immediate).  It's important to specify whether the
26052bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   immediate is to be regarded as signed or not.  If yes, this will
26062bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   never return -32768 as an immediate; this guaranteed that all
26072bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   signed immediates that are return can have their sign inverted if
26082bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   need be. */
2609b51f0f4f33256638ed953156a2635aa739b232f1sewardj
26101f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH ( ISelEnv* env, Bool syned, IRExpr* e,
26111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                IREndness IEndianess )
2612b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
26131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll  PPCRH* ri = iselWordExpr_RH_wrk(env, syned, e, IEndianess);
2614b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* sanity checks ... */
2615b51f0f4f33256638ed953156a2635aa739b232f1sewardj   switch (ri->tag) {
2616f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Imm:
2617f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(ri->Prh.Imm.syned == syned);
2618f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (syned)
2619f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(ri->Prh.Imm.imm16 != 0x8000);
2620f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2621f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Reg:
26224628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Prh.Reg.reg) == HRcGPR(env->mode64));
2623f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Prh.Reg.reg));
2624f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2625f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
26265b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("iselIntExpr_RH: unknown ppc RH tag");
2627b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2628b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2629b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2630b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* DO NOT CALL THIS DIRECTLY ! */
26311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH_wrk ( ISelEnv* env, Bool syned, IRExpr* e,
26321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IREndness IEndianess )
2633b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
2634f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   ULong u;
2635f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   Long  l;
2636b51f0f4f33256638ed953156a2635aa739b232f1sewardj   IRType ty = typeOfIRExpr(env->type_env,e);
2637f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8  || ty == Ity_I16 ||
26384628ccd1bafb946378f91849b92ffcfea0267b2ecerion           ty == Ity_I32 || ((ty == Ity_I64) && env->mode64));
2639b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2640b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* special case: immediate */
2641b51f0f4f33256638ed953156a2635aa739b232f1sewardj   if (e->tag == Iex_Const) {
26425b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IRConst* con = e->Iex.Const.con;
2643b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* What value are we aiming to generate? */
26445b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (con->tag) {
2645f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* Note: Not sign-extending - we carry 'syned' around */
26464628ccd1bafb946378f91849b92ffcfea0267b2ecerion      case Ico_U64: vassert(env->mode64);
26475b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                    u =              con->Ico.U64; break;
26485b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U32: u = 0xFFFFFFFF & con->Ico.U32; break;
26495b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U16: u = 0x0000FFFF & con->Ico.U16; break;
26505b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U8:  u = 0x000000FF & con->Ico.U8; break;
26515b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default:      vpanic("iselIntExpr_RH.Iex_Const(ppch)");
2652b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
2653f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      l = (Long)u;
2654b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* Now figure out if it's representable. */
2655b51f0f4f33256638ed953156a2635aa739b232f1sewardj      if (!syned && u <= 65535) {
26565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         return PPCRH_Imm(False/*unsigned*/, toUShort(u & 0xFFFF));
2657b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
2658f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (syned && l >= -32767 && l <= 32767) {
26595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         return PPCRH_Imm(True/*signed*/, toUShort(u & 0xFFFF));
2660b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
2661b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* no luck; use the Slow Way. */
2662b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2663b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2664b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* default case: calculate into a register and return that */
26651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRH_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2666b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2667b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2668b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2669cd304497d9d869f9b24a002299d3953ee072229bcerion/* --------------------- RIs --------------------- */
2670cd304497d9d869f9b24a002299d3953ee072229bcerion
26715b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion/* Calculate an expression into an PPCRI operand.  As with
26722bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   iselIntExpr_R, the expression can have type 32, 16 or 8 bits, or,
26732bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   in 64-bit mode, 64 bits. */
2674cd304497d9d869f9b24a002299d3953ee072229bcerion
26751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRI* iselWordExpr_RI ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
2676cd304497d9d869f9b24a002299d3953ee072229bcerion{
26771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   PPCRI* ri = iselWordExpr_RI_wrk(env, e, IEndianess);
2678cd304497d9d869f9b24a002299d3953ee072229bcerion   /* sanity checks ... */
2679cd304497d9d869f9b24a002299d3953ee072229bcerion   switch (ri->tag) {
2680f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pri_Imm:
2681f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2682f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pri_Reg:
26834628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Pri.Reg) == HRcGPR(env->mode64));
2684f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Pri.Reg));
2685f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2686f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
26875b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("iselIntExpr_RI: unknown ppc RI tag");
2688cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2689cd304497d9d869f9b24a002299d3953ee072229bcerion}
2690cd304497d9d869f9b24a002299d3953ee072229bcerion
2691cd304497d9d869f9b24a002299d3953ee072229bcerion/* DO NOT CALL THIS DIRECTLY ! */
26921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRI* iselWordExpr_RI_wrk ( ISelEnv* env, IRExpr* e,
26931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IREndness IEndianess )
2694cd304497d9d869f9b24a002299d3953ee072229bcerion{
2695f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   Long  l;
2696cd304497d9d869f9b24a002299d3953ee072229bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
2697f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8  || ty == Ity_I16 ||
26984628ccd1bafb946378f91849b92ffcfea0267b2ecerion           ty == Ity_I32 || ((ty == Ity_I64) && env->mode64));
2699cd304497d9d869f9b24a002299d3953ee072229bcerion
2700cd304497d9d869f9b24a002299d3953ee072229bcerion   /* special case: immediate */
2701cd304497d9d869f9b24a002299d3953ee072229bcerion   if (e->tag == Iex_Const) {
27025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IRConst* con = e->Iex.Const.con;
27035b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (con->tag) {
27044628ccd1bafb946378f91849b92ffcfea0267b2ecerion      case Ico_U64: vassert(env->mode64);
27055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                    l = (Long)            con->Ico.U64; break;
27065b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U32: l = (Long)(Int)       con->Ico.U32; break;
27075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U16: l = (Long)(Int)(Short)con->Ico.U16; break;
27085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U8:  l = (Long)(Int)(Char )con->Ico.U8;  break;
27095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default:      vpanic("iselIntExpr_RI.Iex_Const(ppch)");
2710cd304497d9d869f9b24a002299d3953ee072229bcerion      }
27115b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      return PPCRI_Imm((ULong)l);
2712cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2713cd304497d9d869f9b24a002299d3953ee072229bcerion
2714cd304497d9d869f9b24a002299d3953ee072229bcerion   /* default case: calculate into a register and return that */
27151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRI_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2716cd304497d9d869f9b24a002299d3953ee072229bcerion}
2717cd304497d9d869f9b24a002299d3953ee072229bcerion
2718cd304497d9d869f9b24a002299d3953ee072229bcerion
2719b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* --------------------- RH5u --------------------- */
2720b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2721b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter
2722b51f0f4f33256638ed953156a2635aa739b232f1sewardj   being an immediate in the range 1 .. 31 inclusive.  Used for doing
27232bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   shift amounts.  Only used in 32-bit mode. */
2724b51f0f4f33256638ed953156a2635aa739b232f1sewardj
27251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH5u ( ISelEnv* env, IRExpr* e,
27261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                  IREndness IEndianess )
2727b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
27282bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   PPCRH* ri;
27292bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   vassert(!env->mode64);
27301f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   ri = iselWordExpr_RH5u_wrk(env, e, IEndianess);
2731b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* sanity checks ... */
2732b51f0f4f33256638ed953156a2635aa739b232f1sewardj   switch (ri->tag) {
2733f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Imm:
2734f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(ri->Prh.Imm.imm16 >= 1 && ri->Prh.Imm.imm16 <= 31);
2735f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(!ri->Prh.Imm.syned);
2736f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2737f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Reg:
27384628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Prh.Reg.reg) == HRcGPR(env->mode64));
2739f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Prh.Reg.reg));
2740f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2741f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
27425b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("iselIntExpr_RH5u: unknown ppc RI tag");
2743b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2744b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2745b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2746b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* DO NOT CALL THIS DIRECTLY ! */
27471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH5u_wrk ( ISelEnv* env, IRExpr* e,
27481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      IREndness IEndianess )
2749b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
2750b51f0f4f33256638ed953156a2635aa739b232f1sewardj   IRType ty = typeOfIRExpr(env->type_env,e);
2751b51f0f4f33256638ed953156a2635aa739b232f1sewardj   vassert(ty == Ity_I8);
2752b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2753b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* special case: immediate */
2754b51f0f4f33256638ed953156a2635aa739b232f1sewardj   if (e->tag == Iex_Const
2755b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && e->Iex.Const.con->tag == Ico_U8
2756b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && e->Iex.Const.con->Ico.U8 >= 1
2757b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && e->Iex.Const.con->Ico.U8 <= 31) {
27585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      return PPCRH_Imm(False/*unsigned*/, e->Iex.Const.con->Ico.U8);
2759b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2760b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2761b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* default case: calculate into a register and return that */
27621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRH_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2763b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2764b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2765b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2766f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* --------------------- RH6u --------------------- */
2767f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2768f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* Compute an I8 into a reg-or-6-bit-unsigned-immediate, the latter
2769f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   being an immediate in the range 1 .. 63 inclusive.  Used for doing
27702bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   shift amounts.  Only used in 64-bit mode. */
2771f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
27721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH6u ( ISelEnv* env, IRExpr* e,
27731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                  IREndness IEndianess )
2774f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
27752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   PPCRH* ri;
27762bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   vassert(env->mode64);
27771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   ri = iselWordExpr_RH6u_wrk(env, e, IEndianess);
2778f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* sanity checks ... */
2779f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   switch (ri->tag) {
2780f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Imm:
2781f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(ri->Prh.Imm.imm16 >= 1 && ri->Prh.Imm.imm16 <= 63);
2782f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(!ri->Prh.Imm.syned);
2783f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2784f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Reg:
27854628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Prh.Reg.reg) == HRcGPR(env->mode64));
2786f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Prh.Reg.reg));
2787f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2788f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
2789f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vpanic("iselIntExpr_RH6u: unknown ppc64 RI tag");
2790f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
2791f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
2792f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2793f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* DO NOT CALL THIS DIRECTLY ! */
27941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH6u_wrk ( ISelEnv* env, IRExpr* e,
27951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      IREndness IEndianess )
2796f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
2797f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   IRType ty = typeOfIRExpr(env->type_env,e);
2798f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8);
2799f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2800f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* special case: immediate */
2801f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Const
2802f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && e->Iex.Const.con->tag == Ico_U8
2803f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && e->Iex.Const.con->Ico.U8 >= 1
2804f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && e->Iex.Const.con->Ico.U8 <= 63) {
28055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      return PPCRH_Imm(False/*unsigned*/, e->Iex.Const.con->Ico.U8);
2806f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
2807f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2808f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* default case: calculate into a register and return that */
28091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRH_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2810f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
2811f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2812f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
28132c49e036c365df707cd8e6622d66382f380557b2cerion/* --------------------- CONDCODE --------------------- */
28142c49e036c365df707cd8e6622d66382f380557b2cerion
28152c49e036c365df707cd8e6622d66382f380557b2cerion/* Generate code to evaluated a bit-typed expression, returning the
28162c49e036c365df707cd8e6622d66382f380557b2cerion   condition code which would correspond when the expression would
28172c49e036c365df707cd8e6622d66382f380557b2cerion   notionally have returned 1. */
28182c49e036c365df707cd8e6622d66382f380557b2cerion
28191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCCondCode iselCondCode ( ISelEnv* env, IRExpr* e,
28201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                  IREndness IEndianess )
28212c49e036c365df707cd8e6622d66382f380557b2cerion{
28222c49e036c365df707cd8e6622d66382f380557b2cerion   /* Uh, there's nothing we can sanity check here, unfortunately. */
28231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return iselCondCode_wrk(env,e, IEndianess);
28242c49e036c365df707cd8e6622d66382f380557b2cerion}
28252c49e036c365df707cd8e6622d66382f380557b2cerion
28262c49e036c365df707cd8e6622d66382f380557b2cerion/* DO NOT CALL THIS DIRECTLY ! */
28271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCCondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e,
28281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      IREndness IEndianess )
28292c49e036c365df707cd8e6622d66382f380557b2cerion{
28302c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(e);
28312c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(typeOfIRExpr(env->type_env,e) == Ity_I1);
28322c49e036c365df707cd8e6622d66382f380557b2cerion
28338c51ed42ea3f276e406e5c2fc80458de2e079255cerion   /* Constant 1:Bit */
28348c51ed42ea3f276e406e5c2fc80458de2e079255cerion   if (e->tag == Iex_Const && e->Iex.Const.con->Ico.U1 == True) {
28358c51ed42ea3f276e406e5c2fc80458de2e079255cerion      // Make a compare that will always be true:
2836b51f0f4f33256638ed953156a2635aa739b232f1sewardj      HReg r_zero = newVRegI(env);
28374628ccd1bafb946378f91849b92ffcfea0267b2ecerion      addInstr(env, PPCInstr_LI(r_zero, 0, env->mode64));
28385b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28395b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r_zero, PPCRH_Reg(r_zero)));
2840b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ );
28418c51ed42ea3f276e406e5c2fc80458de2e079255cerion   }
28422c49e036c365df707cd8e6622d66382f380557b2cerion
28432c49e036c365df707cd8e6622d66382f380557b2cerion   /* Not1(...) */
28442c49e036c365df707cd8e6622d66382f380557b2cerion   if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_Not1) {
28452c49e036c365df707cd8e6622d66382f380557b2cerion      /* Generate code for the arg, and negate the test condition */
28461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCCondCode cond = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
284733aa6da1102a12139debec996c33e4effa16f77ccerion      cond.test = invertCondTest(cond.test);
2848ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      return cond;
28492c49e036c365df707cd8e6622d66382f380557b2cerion   }
28502c49e036c365df707cd8e6622d66382f380557b2cerion
28512bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: 32to1 or 64to1 --- */
2852ed623dbefb52ca3211490d656abc999a129df060cerion
28532bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* 32to1, 64to1 */
2854bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion   if (e->tag == Iex_Unop &&
2855bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion       (e->Iex.Unop.op == Iop_32to1 || e->Iex.Unop.op == Iop_64to1)) {
28561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
285720ef5472eac767474c93b7835364a23f24c0ec5dsewardj      HReg tmp = newVRegI(env);
285820ef5472eac767474c93b7835364a23f24c0ec5dsewardj      /* could do better, probably -- andi. */
28595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Alu(Palu_AND, tmp,
28605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 src, PPCRH_Imm(False,1)));
28615b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, tmp, PPCRH_Imm(False,1)));
286320ef5472eac767474c93b7835364a23f24c0ec5dsewardj      return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ );
286420ef5472eac767474c93b7835364a23f24c0ec5dsewardj   }
286520ef5472eac767474c93b7835364a23f24c0ec5dsewardj
286602d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   /* --- patterns rooted at: CmpNEZ8 --- */
286702d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion
286802d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   /* CmpNEZ8(x) */
2869009230b9758291b594e60d7c0243a73d53e81854sewardj   /* Note this cloned as CmpNE8(x,0) below. */
2870b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* could do better -- andi. */
287102d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   if (e->tag == Iex_Unop
287202d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion       && e->Iex.Unop.op == Iop_CmpNEZ8) {
28731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg arg = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
28742bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      HReg tmp = newVRegI(env);
28752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      addInstr(env, PPCInstr_Alu(Palu_AND, tmp, arg,
28765b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 PPCRH_Imm(False,0xFF)));
28775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28782bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                 7/*cr*/, tmp, PPCRH_Imm(False,0)));
2879b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
288002d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   }
288102d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion
2882ed623dbefb52ca3211490d656abc999a129df060cerion   /* --- patterns rooted at: CmpNEZ32 --- */
2883ed623dbefb52ca3211490d656abc999a129df060cerion
2884ed623dbefb52ca3211490d656abc999a129df060cerion   /* CmpNEZ32(x) */
2885ed623dbefb52ca3211490d656abc999a129df060cerion   if (e->tag == Iex_Unop
2886ed623dbefb52ca3211490d656abc999a129df060cerion       && e->Iex.Unop.op == Iop_CmpNEZ32) {
28871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg r1 = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
28885b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r1, PPCRH_Imm(False,0)));
2890b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
2891ed623dbefb52ca3211490d656abc999a129df060cerion   }
2892ed623dbefb52ca3211490d656abc999a129df060cerion
28932bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: Cmp*32* --- */
2894ed623dbefb52ca3211490d656abc999a129df060cerion
2895b536af93912b69421440c27aa0533ad77d678f85cerion   /* Cmp*32*(x,y) */
2896b536af93912b69421440c27aa0533ad77d678f85cerion   if (e->tag == Iex_Binop
2897b536af93912b69421440c27aa0533ad77d678f85cerion       && (e->Iex.Binop.op == Iop_CmpEQ32
2898b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpNE32
2899b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLT32S
2900b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLT32U
2901b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLE32S
2902b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLE32U)) {
2903bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      Bool syned = (e->Iex.Binop.op == Iop_CmpLT32S ||
2904bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion                    e->Iex.Binop.op == Iop_CmpLE32S);
29051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg   r1  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
29061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCRH* ri2 = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2, IEndianess);
29075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(syned, True/*32bit cmp*/,
29085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r1, ri2));
2909ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
2910b536af93912b69421440c27aa0533ad77d678f85cerion      switch (e->Iex.Binop.op) {
2911f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpEQ32:  return mk_PPCCondCode( Pct_TRUE,  Pcf_7EQ );
2912f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpNE32:  return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
291366d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj      case Iop_CmpLT32U: case Iop_CmpLT32S:
291466d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj         return mk_PPCCondCode( Pct_TRUE,  Pcf_7LT );
291566d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj      case Iop_CmpLE32U: case Iop_CmpLE32S:
291666d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj         return mk_PPCCondCode( Pct_FALSE, Pcf_7GT );
29175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default: vpanic("iselCondCode(ppc): CmpXX32");
2918b536af93912b69421440c27aa0533ad77d678f85cerion      }
2919b536af93912b69421440c27aa0533ad77d678f85cerion   }
2920b536af93912b69421440c27aa0533ad77d678f85cerion
29212bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: CmpNEZ64 --- */
29222bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
29232bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* CmpNEZ64 */
29242bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   if (e->tag == Iex_Unop
29252bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj       && e->Iex.Unop.op == Iop_CmpNEZ64) {
29262bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (!env->mode64) {
29272bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         HReg hi, lo;
29282bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         HReg tmp = newVRegI(env);
29291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr( &hi, &lo, env, e->Iex.Unop.arg, IEndianess );
2930b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, tmp, lo, PPCRH_Reg(hi)));
29312bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         addInstr(env, PPCInstr_Cmp(False/*sign*/, True/*32bit cmp*/,
29322bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                    7/*cr*/, tmp,PPCRH_Imm(False,0)));
29332bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
29342bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      } else {  // mode64
29351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
29362bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         addInstr(env, PPCInstr_Cmp(False/*sign*/, False/*64bit cmp*/,
29372bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                    7/*cr*/, r_src,PPCRH_Imm(False,0)));
29382bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
29392bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
29402bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   }
29412bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
29422bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: Cmp*64* --- */
29432bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
2944f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* Cmp*64*(x,y) */
2945f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Binop
2946f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && (e->Iex.Binop.op == Iop_CmpEQ64
2947f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpNE64
2948f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLT64S
2949f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLT64U
2950f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLE64S
2951f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLE64U)) {
2952bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      Bool   syned = (e->Iex.Binop.op == Iop_CmpLT64S ||
2953bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion                      e->Iex.Binop.op == Iop_CmpLE64S);
29541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg    r1 = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
29551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCRH* ri2 = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2, IEndianess);
29564628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(env->mode64);
29575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(syned, False/*64bit cmp*/,
29585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r1, ri2));
2959f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2960f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      switch (e->Iex.Binop.op) {
2961f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpEQ64:  return mk_PPCCondCode( Pct_TRUE,  Pcf_7EQ );
2962f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpNE64:  return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
2963f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpLT64U: return mk_PPCCondCode( Pct_TRUE,  Pcf_7LT );
2964f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpLE64U: return mk_PPCCondCode( Pct_FALSE, Pcf_7GT );
29655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default: vpanic("iselCondCode(ppc): CmpXX64");
2966f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
2967f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
2968f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2969009230b9758291b594e60d7c0243a73d53e81854sewardj   /* --- patterns rooted at: CmpNE8 --- */
2970009230b9758291b594e60d7c0243a73d53e81854sewardj
2971009230b9758291b594e60d7c0243a73d53e81854sewardj   /* CmpNE8(x,0) */
2972009230b9758291b594e60d7c0243a73d53e81854sewardj   /* Note this is a direct copy of CmpNEZ8 above. */
2973009230b9758291b594e60d7c0243a73d53e81854sewardj   /* could do better -- andi. */
2974009230b9758291b594e60d7c0243a73d53e81854sewardj   if (e->tag == Iex_Binop
2975009230b9758291b594e60d7c0243a73d53e81854sewardj       && e->Iex.Binop.op == Iop_CmpNE8
2976009230b9758291b594e60d7c0243a73d53e81854sewardj       && isZeroU8(e->Iex.Binop.arg2)) {
29771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg arg = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
2978009230b9758291b594e60d7c0243a73d53e81854sewardj      HReg tmp = newVRegI(env);
2979009230b9758291b594e60d7c0243a73d53e81854sewardj      addInstr(env, PPCInstr_Alu(Palu_AND, tmp, arg,
2980009230b9758291b594e60d7c0243a73d53e81854sewardj                                 PPCRH_Imm(False,0xFF)));
2981009230b9758291b594e60d7c0243a73d53e81854sewardj      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
2982009230b9758291b594e60d7c0243a73d53e81854sewardj                                 7/*cr*/, tmp, PPCRH_Imm(False,0)));
2983009230b9758291b594e60d7c0243a73d53e81854sewardj      return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
2984009230b9758291b594e60d7c0243a73d53e81854sewardj   }
2985009230b9758291b594e60d7c0243a73d53e81854sewardj
29869abfcbca0696407c4b781b9395298c5edffa33a0cerion   /* var */
2987dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
2988dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      HReg r_src      = lookupIRTemp(env, e->Iex.RdTmp.tmp);
2989be112dd3758ab345310b57f95bc43086e0191de9cerion      HReg src_masked = newVRegI(env);
29905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env,
29915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCInstr_Alu(Palu_AND, src_masked,
29925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                            r_src, PPCRH_Imm(False,1)));
29935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env,
29945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
29955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                            7/*cr*/, src_masked, PPCRH_Imm(False,1)));
2996b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ );
29979abfcbca0696407c4b781b9395298c5edffa33a0cerion   }
2998cd304497d9d869f9b24a002299d3953ee072229bcerion
2999f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vex_printf("iselCondCode(ppc): No such tag(%u)\n", e->tag);
30002c49e036c365df707cd8e6622d66382f380557b2cerion   ppIRExpr(e);
3001f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vpanic("iselCondCode(ppc)");
3002f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
3003f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3004f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3005f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/*---------------------------------------------------------*/
30062bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/*--- ISEL: Integer expressions (128 bit)               ---*/
3007f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/*---------------------------------------------------------*/
3008f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
30092bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 64-bit mode ONLY: compute a 128-bit value into a register pair,
30102bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   which is returned as the first two parameters.  As with
30112bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   iselWordExpr_R, these may be either real or virtual regs; in any
30122bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   case they must not be changed by subsequent code emitted by the
30132bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   caller.  */
3014f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
30155b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt128Expr ( HReg* rHi, HReg* rLo,
30161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             ISelEnv* env, IRExpr* e, IREndness IEndianess )
3017f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
30184628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(env->mode64);
30191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselInt128Expr_wrk(rHi, rLo, env, e, IEndianess);
3020f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion#  if 0
3021f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3022f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion#  endif
30234628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(*rHi) == HRcGPR(env->mode64));
3024f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregIsVirtual(*rHi));
30254628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(*rLo) == HRcGPR(env->mode64));
3026f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregIsVirtual(*rLo));
3027f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
3028f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3029f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* DO NOT CALL THIS DIRECTLY ! */
30305b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt128Expr_wrk ( HReg* rHi, HReg* rLo,
30311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 ISelEnv* env, IRExpr* e, IREndness IEndianess )
3032f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
3033f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(e);
3034f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(typeOfIRExpr(env->type_env,e) == Ity_I128);
3035f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3036f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* read 128-bit IRTemp */
3037dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3038dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      lookupIRTempPair( rHi, rLo, env, e->Iex.RdTmp.tmp);
3039f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return;
3040f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
3041f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3042f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* --------- BINARY ops --------- */
3043f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Binop) {
3044f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      switch (e->Iex.Binop.op) {
3045f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* 64 x 64 -> 128 multiply */
3046f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_MullU64:
3047f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_MullS64: {
3048f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg     tLo     = newVRegI(env);
3049f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg     tHi     = newVRegI(env);
3050f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         Bool     syned   = toBool(e->Iex.Binop.op == Iop_MullS64);
30511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg     r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
30521f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg     r_srcR  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
30535b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(False/*signedness irrelevant*/,
30545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     False/*lo64*/, False/*64bit mul*/,
30555b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, r_srcL, r_srcR));
30565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(syned,
30575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     True/*hi64*/, False/*64bit mul*/,
30585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tHi, r_srcL, r_srcR));
3059f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3060f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3061f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3062f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3063f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3064347da2cdf69bf23e882d957fbe923bb959a199e9sewardj      /* 64HLto128(e1,e2) */
3065347da2cdf69bf23e882d957fbe923bb959a199e9sewardj      case Iop_64HLto128:
30661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
30671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
3068347da2cdf69bf23e882d957fbe923bb959a199e9sewardj         return;
3069f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
3070f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
3071f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3072f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   } /* if (e->tag == Iex_Binop) */
3073f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3074f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3075f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* --------- UNARY ops --------- */
3076f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Unop) {
3077f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      switch (e->Iex.Unop.op) {
3078f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
3079f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
3080f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3081f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   } /* if (e->tag == Iex_Unop) */
3082f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3083f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vex_printf("iselInt128Expr(ppc64): No such tag(%u)\n", e->tag);
3084f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   ppIRExpr(e);
3085f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vpanic("iselInt128Expr(ppc64)");
30862c49e036c365df707cd8e6622d66382f380557b2cerion}
30872c49e036c365df707cd8e6622d66382f380557b2cerion
30882c49e036c365df707cd8e6622d66382f380557b2cerion
30892c49e036c365df707cd8e6622d66382f380557b2cerion/*---------------------------------------------------------*/
30902c49e036c365df707cd8e6622d66382f380557b2cerion/*--- ISEL: Integer expressions (64 bit)                ---*/
30912c49e036c365df707cd8e6622d66382f380557b2cerion/*---------------------------------------------------------*/
30922c49e036c365df707cd8e6622d66382f380557b2cerion
3093c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* 32-bit mode ONLY: compute a 128-bit value into a register quad */
3094c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselInt128Expr_to_32x4 ( HReg* rHi, HReg* rMedHi, HReg* rMedLo,
30951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     HReg* rLo, ISelEnv* env, IRExpr* e,
30961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IREndness IEndianess )
3097c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
3098c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(!env->mode64);
30991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselInt128Expr_to_32x4_wrk(rHi, rMedHi, rMedLo, rLo, env, e, IEndianess);
3100c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj#  if 0
3101c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3102c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj#  endif
3103c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rHi) == HRcInt32);
3104c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rHi));
3105c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rMedHi) == HRcInt32);
3106c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rMedHi));
3107c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rMedLo) == HRcInt32);
3108c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rMedLo));
3109c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rLo) == HRcInt32);
3110c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rLo));
3111c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
3112c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3113c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselInt128Expr_to_32x4_wrk ( HReg* rHi, HReg* rMedHi,
3114c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                         HReg* rMedLo, HReg* rLo,
31151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         ISelEnv* env, IRExpr* e,
31161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess )
3117c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
3118c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(e);
3119c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(typeOfIRExpr(env->type_env,e) == Ity_I128);
3120c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3121c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* read 128-bit IRTemp */
3122c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_RdTmp) {
3123c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      lookupIRTempQuad( rHi, rMedHi, rMedLo, rLo, env, e->Iex.RdTmp.tmp);
3124c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return;
3125c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
3126c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3127c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Binop) {
3128c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3129c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      IROp op_binop = e->Iex.Binop.op;
3130c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      switch (op_binop) {
3131c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_64HLto128:
31321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(rHi, rMedHi, env, e->Iex.Binop.arg1, IEndianess);
31331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(rMedLo, rLo, env, e->Iex.Binop.arg2, IEndianess);
3134c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
3135c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
3136c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         vex_printf("iselInt128Expr_to_32x4_wrk: Binop case 0x%x not found\n",
3137c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                    op_binop);
3138c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
3139c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
3140c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
3141c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3142c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vex_printf("iselInt128Expr_to_32x4_wrk: e->tag 0x%x not found\n", e->tag);
3143c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   return;
3144c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
3145c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
31462bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode ONLY: compute a 64-bit value into a register pair,
31472bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   which is returned as the first two parameters.  As with
31482bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   iselIntExpr_R, these may be either real or virtual regs; in any
31492bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   case they must not be changed by subsequent code emitted by the
31502bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   caller.  */
31512c49e036c365df707cd8e6622d66382f380557b2cerion
31525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt64Expr ( HReg* rHi, HReg* rLo,
31531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                            ISelEnv* env, IRExpr* e,
31541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                            IREndness IEndianess )
31552c49e036c365df707cd8e6622d66382f380557b2cerion{
31564628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(!env->mode64);
31571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselInt64Expr_wrk(rHi, rLo, env, e, IEndianess);
31582c49e036c365df707cd8e6622d66382f380557b2cerion#  if 0
31592c49e036c365df707cd8e6622d66382f380557b2cerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
31602c49e036c365df707cd8e6622d66382f380557b2cerion#  endif
31612c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregClass(*rHi) == HRcInt32);
31622c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregIsVirtual(*rHi));
31632c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregClass(*rLo) == HRcInt32);
31642c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregIsVirtual(*rLo));
31652c49e036c365df707cd8e6622d66382f380557b2cerion}
31662c49e036c365df707cd8e6622d66382f380557b2cerion
31672c49e036c365df707cd8e6622d66382f380557b2cerion/* DO NOT CALL THIS DIRECTLY ! */
31685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo,
31691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                ISelEnv* env, IRExpr* e,
31701f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                IREndness IEndianess )
31712c49e036c365df707cd8e6622d66382f380557b2cerion{
31722c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(e);
31732c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
31742c49e036c365df707cd8e6622d66382f380557b2cerion
3175e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj   /* 64-bit load */
31761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
3177e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      HReg tLo    = newVRegI(env);
3178e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      HReg tHi    = newVRegI(env);
31791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg r_addr = iselWordExpr_R(env, e->Iex.Load.addr, IEndianess);
3180e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      vassert(!env->mode64);
3181e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      addInstr(env, PPCInstr_Load( 4/*byte-load*/,
3182e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   tHi, PPCAMode_IR( 0, r_addr ),
3183e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   False/*32-bit insn please*/) );
3184e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      addInstr(env, PPCInstr_Load( 4/*byte-load*/,
3185e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   tLo, PPCAMode_IR( 4, r_addr ),
3186e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   False/*32-bit insn please*/) );
3187e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      *rHi = tHi;
3188e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      *rLo = tLo;
3189e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      return;
3190e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj   }
3191e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj
31924a49b0393204185f87664ea58f2b7a2ae1d37338cerion   /* 64-bit literal */
31934a49b0393204185f87664ea58f2b7a2ae1d37338cerion   if (e->tag == Iex_Const) {
31944a49b0393204185f87664ea58f2b7a2ae1d37338cerion      ULong w64 = e->Iex.Const.con->Ico.U64;
31954a49b0393204185f87664ea58f2b7a2ae1d37338cerion      UInt  wHi = ((UInt)(w64 >> 32)) & 0xFFFFFFFF;
31964a49b0393204185f87664ea58f2b7a2ae1d37338cerion      UInt  wLo = ((UInt)w64) & 0xFFFFFFFF;
31974a49b0393204185f87664ea58f2b7a2ae1d37338cerion      HReg  tLo = newVRegI(env);
31984a49b0393204185f87664ea58f2b7a2ae1d37338cerion      HReg  tHi = newVRegI(env);
31994a49b0393204185f87664ea58f2b7a2ae1d37338cerion      vassert(e->Iex.Const.con->tag == Ico_U64);
3200aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      addInstr(env, PPCInstr_LI(tHi, (Long)(Int)wHi, False/*mode32*/));
3201aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      addInstr(env, PPCInstr_LI(tLo, (Long)(Int)wLo, False/*mode32*/));
32024a49b0393204185f87664ea58f2b7a2ae1d37338cerion      *rHi = tHi;
32034a49b0393204185f87664ea58f2b7a2ae1d37338cerion      *rLo = tLo;
32044a49b0393204185f87664ea58f2b7a2ae1d37338cerion      return;
32054a49b0393204185f87664ea58f2b7a2ae1d37338cerion   }
32062c49e036c365df707cd8e6622d66382f380557b2cerion
32072c49e036c365df707cd8e6622d66382f380557b2cerion   /* read 64-bit IRTemp */
3208dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3209dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      lookupIRTempPair( rHi, rLo, env, e->Iex.RdTmp.tmp);
32102c49e036c365df707cd8e6622d66382f380557b2cerion      return;
32112c49e036c365df707cd8e6622d66382f380557b2cerion   }
32122c49e036c365df707cd8e6622d66382f380557b2cerion
321384ad616686a2c29be1c2b1f65f72ae79820a84c4cerion   /* 64-bit GET */
321484ad616686a2c29be1c2b1f65f72ae79820a84c4cerion   if (e->tag == Iex_Get) {
32155b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
32162bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                       GuestStatePtr(False/*mode32*/) );
32175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr4 = advance4(env, am_addr);
321884ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      HReg tLo = newVRegI(env);
321984ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      HReg tHi = newVRegI(env);
32207fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj      addInstr(env, PPCInstr_Load( 4, tHi, am_addr,  False/*mode32*/ ));
32217fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj      addInstr(env, PPCInstr_Load( 4, tLo, am_addr4, False/*mode32*/ ));
322284ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      *rHi = tHi;
322384ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      *rLo = tLo;
322484ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      return;
322584ad616686a2c29be1c2b1f65f72ae79820a84c4cerion   }
32262c49e036c365df707cd8e6622d66382f380557b2cerion
322799dd03e04a6914d90d5fee727d61d76905334becflorian   /* 64-bit ITE */
322899dd03e04a6914d90d5fee727d61d76905334becflorian   if (e->tag == Iex_ITE) { // VFD
3229a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      HReg e0Lo, e0Hi, eXLo, eXHi;
32301f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      iselInt64Expr(&eXHi, &eXLo, env, e->Iex.ITE.iftrue, IEndianess);
32311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      iselInt64Expr(&e0Hi, &e0Lo, env, e->Iex.ITE.iffalse, IEndianess);
3232a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      HReg tLo = newVRegI(env);
3233a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      HReg tHi = newVRegI(env);
323460733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, mk_iMOVds_RR(tHi,e0Hi));
323560733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, mk_iMOVds_RR(tLo,e0Lo));
32361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCCondCode cc = iselCondCode(env, e->Iex.ITE.cond, IEndianess);
323760733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, PPCInstr_CMov(cc,tHi,PPCRI_Reg(eXHi)));
323860733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, PPCInstr_CMov(cc,tLo,PPCRI_Reg(eXLo)));
3239a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      *rHi = tHi;
3240a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      *rLo = tLo;
3241a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      return;
3242a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj   }
32432c49e036c365df707cd8e6622d66382f380557b2cerion
32442c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- BINARY ops --------- */
32452c49e036c365df707cd8e6622d66382f380557b2cerion   if (e->tag == Iex_Binop) {
32465b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IROp op_binop = e->Iex.Binop.op;
32475b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (op_binop) {
32487c6dbff15934256b028a69e906cd3f80275c84absewardj         /* 32 x 32 -> 64 multiply */
32497c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_MullU32:
32507c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_MullS32: {
32517c6dbff15934256b028a69e906cd3f80275c84absewardj            HReg     tLo     = newVRegI(env);
32527c6dbff15934256b028a69e906cd3f80275c84absewardj            HReg     tHi     = newVRegI(env);
32537c6dbff15934256b028a69e906cd3f80275c84absewardj            Bool     syned   = toBool(op_binop == Iop_MullS32);
32541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1,
32551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IEndianess);
32561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     r_srcR  = iselWordExpr_R(env, e->Iex.Binop.arg2,
32571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IEndianess);
32587c6dbff15934256b028a69e906cd3f80275c84absewardj            addInstr(env, PPCInstr_MulL(False/*signedness irrelevant*/,
32597c6dbff15934256b028a69e906cd3f80275c84absewardj                                        False/*lo32*/, True/*32bit mul*/,
32607c6dbff15934256b028a69e906cd3f80275c84absewardj                                        tLo, r_srcL, r_srcR));
32617c6dbff15934256b028a69e906cd3f80275c84absewardj            addInstr(env, PPCInstr_MulL(syned,
32627c6dbff15934256b028a69e906cd3f80275c84absewardj                                        True/*hi32*/, True/*32bit mul*/,
32637c6dbff15934256b028a69e906cd3f80275c84absewardj                                        tHi, r_srcL, r_srcR));
32647c6dbff15934256b028a69e906cd3f80275c84absewardj            *rHi = tHi;
32657c6dbff15934256b028a69e906cd3f80275c84absewardj            *rLo = tLo;
32667c6dbff15934256b028a69e906cd3f80275c84absewardj            return;
32677c6dbff15934256b028a69e906cd3f80275c84absewardj         }
3268a21951955194861590440a464efb23f20ff30fc9sewardj
3269a21951955194861590440a464efb23f20ff30fc9sewardj         /* Or64/And64/Xor64 */
3270a21951955194861590440a464efb23f20ff30fc9sewardj         case Iop_Or64:
3271a21951955194861590440a464efb23f20ff30fc9sewardj         case Iop_And64:
3272a21951955194861590440a464efb23f20ff30fc9sewardj         case Iop_Xor64: {
3273a21951955194861590440a464efb23f20ff30fc9sewardj            HReg xLo, xHi, yLo, yHi;
3274a21951955194861590440a464efb23f20ff30fc9sewardj            HReg tLo = newVRegI(env);
3275a21951955194861590440a464efb23f20ff30fc9sewardj            HReg tHi = newVRegI(env);
32765b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            PPCAluOp op = (op_binop == Iop_Or64) ? Palu_OR :
32775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                          (op_binop == Iop_And64) ? Palu_AND : Palu_XOR;
32781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1, IEndianess);
32791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2, IEndianess);
32805b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Alu(op, tHi, xHi, PPCRH_Reg(yHi)));
32815b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Alu(op, tLo, xLo, PPCRH_Reg(yLo)));
3282a21951955194861590440a464efb23f20ff30fc9sewardj            *rHi = tHi;
3283a21951955194861590440a464efb23f20ff30fc9sewardj            *rLo = tLo;
3284a21951955194861590440a464efb23f20ff30fc9sewardj            return;
3285a21951955194861590440a464efb23f20ff30fc9sewardj         }
3286a21951955194861590440a464efb23f20ff30fc9sewardj
3287478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         /* Add64 */
32884a49b0393204185f87664ea58f2b7a2ae1d37338cerion         case Iop_Add64: {
32894a49b0393204185f87664ea58f2b7a2ae1d37338cerion            HReg xLo, xHi, yLo, yHi;
32904a49b0393204185f87664ea58f2b7a2ae1d37338cerion            HReg tLo = newVRegI(env);
32914a49b0393204185f87664ea58f2b7a2ae1d37338cerion            HReg tHi = newVRegI(env);
32921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1, IEndianess);
32931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2, IEndianess);
32945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AddSubC( True/*add*/, True /*set carry*/,
32955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                            tLo, xLo, yLo));
32965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AddSubC( True/*add*/, False/*read carry*/,
32975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                            tHi, xHi, yHi));
32984a49b0393204185f87664ea58f2b7a2ae1d37338cerion            *rHi = tHi;
32994a49b0393204185f87664ea58f2b7a2ae1d37338cerion            *rLo = tLo;
33004a49b0393204185f87664ea58f2b7a2ae1d37338cerion            return;
33014a49b0393204185f87664ea58f2b7a2ae1d37338cerion         }
3302ed623dbefb52ca3211490d656abc999a129df060cerion
3303ed623dbefb52ca3211490d656abc999a129df060cerion         /* 32HLto64(e1,e2) */
3304ed623dbefb52ca3211490d656abc999a129df060cerion         case Iop_32HLto64:
33051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
33061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
3307ed623dbefb52ca3211490d656abc999a129df060cerion            return;
3308ed623dbefb52ca3211490d656abc999a129df060cerion
33094aa412af1d8166cc11f39a6e721df49431d23618sewardj         /* F64toI64[S|U] */
33104aa412af1d8166cc11f39a6e721df49431d23618sewardj         case Iop_F64toI64S: case Iop_F64toI64U: {
3311c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      tLo     = newVRegI(env);
3312c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      tHi     = newVRegI(env);
3313c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      r1      = StackFramePtr(env->mode64);
3314c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
3315c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
33161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg      fsrc    = iselDblExpr(env, e->Iex.Binop.arg2,
33171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess);
3318c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      ftmp    = newVRegF(env);
3319c74373da820d4004fbfab13e136b78bbf3618104sewardj
3320c74373da820d4004fbfab13e136b78bbf3618104sewardj            vassert(!env->mode64);
3321c74373da820d4004fbfab13e136b78bbf3618104sewardj            /* Set host rounding mode */
33221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
3323c74373da820d4004fbfab13e136b78bbf3618104sewardj
3324c74373da820d4004fbfab13e136b78bbf3618104sewardj            sub_from_sp( env, 16 );
33254aa412af1d8166cc11f39a6e721df49431d23618sewardj            addInstr(env, PPCInstr_FpCftI(False/*F->I*/, False/*int64*/,
33264aa412af1d8166cc11f39a6e721df49431d23618sewardj                                          (op_binop == Iop_F64toI64S) ? True : False,
332766d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj                                          True, ftmp, fsrc));
3328c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
3329c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3330c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3331c74373da820d4004fbfab13e136b78bbf3618104sewardj            add_to_sp( env, 16 );
3332c74373da820d4004fbfab13e136b78bbf3618104sewardj
3333b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
3334b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
3335c74373da820d4004fbfab13e136b78bbf3618104sewardj            *rHi = tHi;
3336c74373da820d4004fbfab13e136b78bbf3618104sewardj            *rLo = tLo;
3337c74373da820d4004fbfab13e136b78bbf3618104sewardj            return;
3338c74373da820d4004fbfab13e136b78bbf3618104sewardj         }
3339cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         case Iop_D64toI64S: {
3340cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg      tLo     = newVRegI(env);
3341cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg      tHi     = newVRegI(env);
3342cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg      r1      = StackFramePtr(env->mode64);
3343cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
3344cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
33451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
3346cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmp    = newVRegF(env);
3347c74373da820d4004fbfab13e136b78bbf3618104sewardj
3348cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            vassert(!env->mode64);
33491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
3350cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Dfp64Unary(Pfp_DCTFIX, tmp, fr_src));
3351cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3352cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            sub_from_sp( env, 16 );
3353cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
3354cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3355cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3356cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            add_to_sp( env, 16 );
3357cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rHi = tHi;
3358cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rLo = tLo;
3359cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            return;
3360cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
3361cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         case Iop_D128toI64S: {
3362cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCFpOp fpop = Pfp_DCTFIXQ;
3363cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg r_srcHi = newVRegF(env);
3364cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg r_srcLo = newVRegF(env);
3365cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tLo     = newVRegI(env);
3366cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tHi     = newVRegI(env);
3367cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg ftmp    = newVRegF(env);
3368cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3369cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
3370cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
33711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
33721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
33731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
3374cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_DfpD128toD64(fpop, ftmp, r_srcHi, r_srcLo));
3375cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3376cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the D64 result into an integer register pair
3377cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            sub_from_sp( env, 16 );
3378cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
3379cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3380cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3381cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            add_to_sp( env, 16 );
3382cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rHi = tHi;
3383cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rLo = tLo;
3384cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            return;
3385cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
33867c6dbff15934256b028a69e906cd3f80275c84absewardj         default:
33877c6dbff15934256b028a69e906cd3f80275c84absewardj            break;
33882c49e036c365df707cd8e6622d66382f380557b2cerion      }
33892c49e036c365df707cd8e6622d66382f380557b2cerion   } /* if (e->tag == Iex_Binop) */
33902c49e036c365df707cd8e6622d66382f380557b2cerion
33912c49e036c365df707cd8e6622d66382f380557b2cerion
3392ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- UNARY ops --------- */
3393ed623dbefb52ca3211490d656abc999a129df060cerion   if (e->tag == Iex_Unop) {
3394ed623dbefb52ca3211490d656abc999a129df060cerion      switch (e->Iex.Unop.op) {
3395ed623dbefb52ca3211490d656abc999a129df060cerion
3396eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      /* CmpwNEZ64(e) */
3397eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_CmpwNEZ64: {
3398eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg argHi, argLo;
3399eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg tmp1  = newVRegI(env);
3400eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg tmp2  = newVRegI(env);
34011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&argHi, &argLo, env, e->Iex.Unop.arg, IEndianess);
3402eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         /* tmp1 = argHi | argLo */
3403eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, tmp1, argHi, PPCRH_Reg(argLo)));
3404eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         /* tmp2 = (tmp1 | -tmp1) >>s 31 */
3405eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Unary(Pun_NEG,tmp2,tmp1));
3406eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, tmp2, tmp2, PPCRH_Reg(tmp1)));
3407eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
3408eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                     tmp2, tmp2, PPCRH_Imm(False, 31)));
3409eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         *rHi = tmp2;
3410eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         *rLo = tmp2; /* yes, really tmp2 */
3411eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         return;
3412eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      }
3413eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj
3414478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      /* Left64 */
3415478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      case Iop_Left64: {
3416478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg argHi, argLo;
3417478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg zero32 = newVRegI(env);
3418478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg resHi  = newVRegI(env);
3419478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg resLo  = newVRegI(env);
34201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&argHi, &argLo, env, e->Iex.Unop.arg, IEndianess);
3421478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         vassert(env->mode64 == False);
3422478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_LI(zero32, 0, env->mode64));
3423478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         /* resHi:resLo = - argHi:argLo */
3424478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_AddSubC( False/*sub*/, True/*set carry*/,
3425478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj                                         resLo, zero32, argLo ));
3426478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_AddSubC( False/*sub*/, False/*read carry*/,
3427478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj                                         resHi, zero32, argHi ));
3428478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         /* resHi:resLo |= srcHi:srcLo */
3429478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, resLo, resLo, PPCRH_Reg(argLo)));
3430478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, resHi, resHi, PPCRH_Reg(argHi)));
3431478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         *rHi = resHi;
3432478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         *rLo = resLo;
3433478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         return;
3434478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      }
3435478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj
3436f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* 32Sto64(e) */
3437f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_32Sto64: {
3438f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
34391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
34405b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
34415b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tHi, src, PPCRH_Imm(False,31)));
3442f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3443f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = src;
3444f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3445f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3446cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_ExtractExpD64: {
3447cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg tmp    = newVRegF(env);
34481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
3449cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tLo     = newVRegI(env);
3450cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tHi     = newVRegI(env);
3451cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3452cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
3453cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3454cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DXEX, tmp, fr_src));
3455cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3456cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the D64 result into a integer register pair
3457cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
3458cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
3459cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3460cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3461cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
3462cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rHi = tHi;
3463cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rLo = tLo;
3464cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return;
3465cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
3466cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_ExtractExpD128: {
3467cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      r_srcHi;
3468cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      r_srcLo;
3469cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tmp     = newVRegF(env);
3470cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tLo     = newVRegI(env);
3471cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tHi     = newVRegI(env);
3472cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3473cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
3474cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
34751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Unop.arg, IEndianess);
3476cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_ExtractExpD128(Pfp_DXEXQ, tmp,
3477cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                                  r_srcHi, r_srcLo));
3478cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3479cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the D64 result into a integer register pair
3480cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
3481cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
3482cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3483cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3484cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
3485cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rHi = tHi;
3486cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rLo = tLo;
3487cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return;
3488cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
34896587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion
3490f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* 32Uto64(e) */
3491f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_32Uto64: {
3492f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
34931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg tLo = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
34942bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         addInstr(env, PPCInstr_LI(tHi, 0, False/*mode32*/));
3495f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3496f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3497f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3498f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
34996587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion
3500c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_128to64: {
3501c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         /* Narrow, return the low 64-bit half as a 32-bit
3502c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj          * register pair */
3503c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Hi    = INVALID_HREG;
3504c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedHi = INVALID_HREG;
3505c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedLo = INVALID_HREG;
3506c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Lo    = INVALID_HREG;
3507c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3508c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         iselInt128Expr_to_32x4(&r_Hi, &r_MedHi, &r_MedLo, &r_Lo,
35091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                env, e->Iex.Unop.arg, IEndianess);
3510c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_MedLo;
3511c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_Lo;
3512c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
3513c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
3514c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3515c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_128HIto64: {
3516c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         /* Narrow, return the high 64-bit half as a 32-bit
3517c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj          *  register pair */
3518c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Hi    = INVALID_HREG;
3519c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedHi = INVALID_HREG;
3520c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedLo = INVALID_HREG;
3521c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Lo    = INVALID_HREG;
3522c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3523c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         iselInt128Expr_to_32x4(&r_Hi, &r_MedHi, &r_MedLo, &r_Lo,
35241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                env, e->Iex.Unop.arg, IEndianess);
3525c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_Hi;
3526c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_MedHi;
3527c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
3528c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
3529c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3530f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* V128{HI}to64 */
3531f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_V128HIto64:
3532f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_V128to64: {
3533f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_aligned16;
3534f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         Int  off = e->Iex.Unop.op==Iop_V128HIto64 ? 0 : 8;
3535f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tLo = newVRegI(env);
3536f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
35371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg vec = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
35385b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode *am_off0, *am_offLO, *am_offHI;
3539f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         sub_from_sp( env, 32 );     // Move SP down 32 bytes
3540f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3541f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // get a quadword aligned address within our stack space
3542f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         r_aligned16 = get_sp_aligned16( env );
35435b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off0  = PPCAMode_IR( 0,     r_aligned16 );
35445b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_offHI = PPCAMode_IR( off,   r_aligned16 );
35455b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_offLO = PPCAMode_IR( off+4, r_aligned16 );
3546f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3547f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // store as Vec128
35485b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
35495b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 ));
3550f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3551f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // load hi,lo words (of hi/lo half of vec) as Ity_I32's
35525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
35537fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                  PPCInstr_Load( 4, tHi, am_offHI, False/*mode32*/ ));
35545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
35557fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                  PPCInstr_Load( 4, tLo, am_offLO, False/*mode32*/ ));
3556f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3557f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         add_to_sp( env, 32 );       // Reset SP
3558f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3559f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3560f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3561f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3562a21951955194861590440a464efb23f20ff30fc9sewardj
3563f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* could do better than this, but for now ... */
3564f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_1Sto64: {
3565f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tLo = newVRegI(env);
3566f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
35671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cond = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
35685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Set(cond,tLo));
35695b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
35705b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, tLo, PPCRH_Imm(False,31)));
35715b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
35725b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, tLo, PPCRH_Imm(False,31)));
3573f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         addInstr(env, mk_iMOVds_RR(tHi, tLo));
3574f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3575f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3576f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3577f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
35781bee561912427ca8f8998c89b62d86ba2ee49732sewardj
3579d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj      case Iop_Not64: {
3580d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         HReg xLo, xHi;
3581d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         HReg tmpLo = newVRegI(env);
3582d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         HReg tmpHi = newVRegI(env);
35831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&xHi, &xLo, env, e->Iex.Unop.arg, IEndianess);
3584d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         addInstr(env, PPCInstr_Unary(Pun_NOT,tmpLo,xLo));
3585d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         addInstr(env, PPCInstr_Unary(Pun_NOT,tmpHi,xHi));
3586d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         *rHi = tmpHi;
3587d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         *rLo = tmpLo;
3588d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         return;
3589d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj      }
3590d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj
3591f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* ReinterpF64asI64(e) */
3592f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* Given an IEEE754 double, produce an I64 with the same bit
3593f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         pattern. */
3594f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_ReinterpF64asI64: {
35955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode *am_addr0, *am_addr1;
35961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src  = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
3597f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_dstLo = newVRegI(env);
3598f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_dstHi = newVRegI(env);
3599f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3600f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         sub_from_sp( env, 16 );     // Move SP down 16 bytes
36012bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         am_addr0 = PPCAMode_IR( 0, StackFramePtr(False/*mode32*/) );
36022bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         am_addr1 = PPCAMode_IR( 4, StackFramePtr(False/*mode32*/) );
3603f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3604f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // store as F64
36055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
36065b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                        fr_src, am_addr0 ));
3607f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3608f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // load hi,lo as Ity_I32's
36097fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         addInstr(env, PPCInstr_Load( 4, r_dstHi,
36102bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                      am_addr0, False/*mode32*/ ));
36117fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         addInstr(env, PPCInstr_Load( 4, r_dstLo,
36122bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                      am_addr1, False/*mode32*/ ));
3613f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = r_dstHi;
3614f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = r_dstLo;
3615f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3616f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         add_to_sp( env, 16 );       // Reset SP
3617f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3618f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3619094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
36205eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      case Iop_ReinterpD64asI64: {
36211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src  = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
36224c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCAMode *am_addr0, *am_addr1;
36234c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg r_dstLo = newVRegI(env);
36244c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg r_dstHi = newVRegI(env);
36255eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36265eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36275eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         sub_from_sp( env, 16 );     // Move SP down 16 bytes
36285eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         am_addr0 = PPCAMode_IR( 0, StackFramePtr(False/*mode32*/) );
36295eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         am_addr1 = PPCAMode_IR( 4, StackFramePtr(False/*mode32*/) );
36305eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36315eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         // store as D64
36325eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
36335eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                        fr_src, am_addr0 ));
36344c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36355eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         // load hi,lo as Ity_I32's
36365eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         addInstr(env, PPCInstr_Load( 4, r_dstHi,
36375eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                      am_addr0, False/*mode32*/ ));
36385eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         addInstr(env, PPCInstr_Load( 4, r_dstLo,
36395eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                      am_addr1, False/*mode32*/ ));
36405eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         *rHi = r_dstHi;
36415eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         *rLo = r_dstLo;
36424c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36435eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         add_to_sp( env, 16 );       // Reset SP
36445eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36455eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         return;
36465eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      }
36475eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36484c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      case Iop_BCDtoDPB: {
36494c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCCondCode cc;
36504c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         UInt        argiregs;
36514c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        argregs[2];
36524c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Int         argreg;
36534c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tLo = newVRegI(env);
36544c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tHi = newVRegI(env);
36554c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpHi;
36564c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpLo;
36574c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Bool        mode64 = env->mode64;
36584c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36594c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[0] = hregPPC_GPR3(mode64);
36604c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[1] = hregPPC_GPR4(mode64);
36614c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36624c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs = 0;
36634c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argreg = 0;
36644c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr( &tmpHi, &tmpLo, env, e->Iex.Unop.arg, IEndianess );
36664c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36674c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= ( 1 << (argreg+3 ) );
36684c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( argregs[argreg++], tmpHi ) );
36694c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36704c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= ( 1 << (argreg+3 ) );
36714c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( argregs[argreg], tmpLo ) );
36724c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36734c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
36744c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE) {
367693a09742b0de3d61718882c2d999f64be402564dflorian             addInstr( env, PPCInstr_Call( cc, (Addr)h_calc_BCDtoDPB,
36771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           argiregs,
36781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           mk_RetLoc_simple(RLPri_2Int) ) );
36791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         } else {
368093a09742b0de3d61718882c2d999f64be402564dflorian             Addr64 target;
368193a09742b0de3d61718882c2d999f64be402564dflorian             target = mode64 ? (Addr)h_calc_BCDtoDPB :
368293a09742b0de3d61718882c2d999f64be402564dflorian               toUInt( (Addr)h_calc_BCDtoDPB );
368393a09742b0de3d61718882c2d999f64be402564dflorian             addInstr( env, PPCInstr_Call( cc, target,
36841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           argiregs,
36851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           mk_RetLoc_simple(RLPri_2Int) ) );
36861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         }
36871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
36884c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( tHi, argregs[argreg-1] ) );
36894c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( tLo, argregs[argreg] ) );
36904c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36914c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rHi = tHi;
36924c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rLo = tLo;
36934c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         return;
36944c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      }
36954c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36964c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      case Iop_DPBtoBCD: {
36974c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCCondCode cc;
36984c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         UInt        argiregs;
36994c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        argregs[2];
37004c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Int         argreg;
37014c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tLo = newVRegI(env);
37024c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tHi = newVRegI(env);
37034c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpHi;
37044c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpLo;
37054c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Bool        mode64 = env->mode64;
37064c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37074c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[0] = hregPPC_GPR3(mode64);
37084c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[1] = hregPPC_GPR4(mode64);
37094c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37104c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs = 0;
37114c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argreg = 0;
37124c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Unop.arg, IEndianess);
37144c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37154c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= (1 << (argreg+3));
37164c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR( argregs[argreg++], tmpHi ));
37174c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37184c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= (1 << (argreg+3));
37194c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR( argregs[argreg], tmpLo));
37204c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37214c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
37224c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE) {
372493a09742b0de3d61718882c2d999f64be402564dflorian             addInstr(env, PPCInstr_Call( cc, (Addr)h_calc_DPBtoBCD,
37251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          argiregs,
37261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          mk_RetLoc_simple(RLPri_2Int) ) );
37271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         } else {
372893a09742b0de3d61718882c2d999f64be402564dflorian             Addr64 target;
372993a09742b0de3d61718882c2d999f64be402564dflorian             target = mode64 ? (Addr)h_calc_DPBtoBCD :
373093a09742b0de3d61718882c2d999f64be402564dflorian               toUInt( (Addr)h_calc_DPBtoBCD );
373193a09742b0de3d61718882c2d999f64be402564dflorian             addInstr(env, PPCInstr_Call( cc, target, argiregs,
37321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          mk_RetLoc_simple(RLPri_2Int) ) );
37331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         }
37344c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37354c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR(tHi, argregs[argreg-1]));
37364c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR(tLo, argregs[argreg]));
37374c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37384c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rHi = tHi;
37394c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rLo = tLo;
37404c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         return;
37414c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      }
37424c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
3743f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
3744f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
3745ed623dbefb52ca3211490d656abc999a129df060cerion      }
3746ed623dbefb52ca3211490d656abc999a129df060cerion   } /* if (e->tag == Iex_Unop) */
3747ed623dbefb52ca3211490d656abc999a129df060cerion
37485b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselInt64Expr(ppc): No such tag(%u)\n", e->tag);
37492c49e036c365df707cd8e6622d66382f380557b2cerion   ppIRExpr(e);
37505b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselInt64Expr(ppc)");
37512c49e036c365df707cd8e6622d66382f380557b2cerion}
3752cd304497d9d869f9b24a002299d3953ee072229bcerion
3753b536af93912b69421440c27aa0533ad77d678f85cerion
3754094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3755094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*--- ISEL: Floating point expressions (32 bit)         ---*/
3756094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3757094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3758094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* Nothing interesting here; really just wrappers for
3759094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   64-bit stuff. */
3760094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
37611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselFltExpr ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3762094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
37631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll  HReg r = iselFltExpr_wrk( env, e, IEndianess );
3764094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  if 0
3765094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3766094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  endif
3767094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregClass(r) == HRcFlt64); /* yes, really Flt64 */
3768094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregIsVirtual(r));
3769094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   return r;
3770094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
3771094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3772094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* DO NOT CALL THIS DIRECTLY */
37731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselFltExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3774094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
37757d810d793616af057ce861746aa985df3304cb86sewardj   Bool        mode64 = env->mode64;
37767d810d793616af057ce861746aa985df3304cb86sewardj
3777094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
3778094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(ty == Ity_F32);
3779094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3780dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3781dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
3782094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3783094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
37841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
37855b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr;
3786094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
3787af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj      vassert(e->Iex.Load.ty == Ity_F32);
37881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_F32/*xfer*/,
37891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
37905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, r_dst, am_addr));
3791094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
3792094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3793094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3794094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Get) {
3795094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
37965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
37974628ccd1bafb946378f91849b92ffcfea0267b2ecerion                                       GuestStatePtr(env->mode64) );
37985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt( True/*load*/, 4, r_dst, am_addr ));
3799094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
3800094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3801094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3802b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_TruncF64asF32) {
3803b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* This is quite subtle.  The only way to do the relevant
3804b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         truncation is to do a single-precision store and then a
3805b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         double precision load to get it back into a register.  The
3806b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         problem is, if the data is then written to memory a second
3807b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         time, as in
3808b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3809b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            STbe(...) = TruncF64asF32(...)
3810b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3811b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         then will the second truncation further alter the value?  The
3812b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         answer is no: flds (as generated here) followed by fsts
3813b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         (generated for the STbe) is the identity function on 32-bit
3814b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         floats, so we are safe.
3815b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3816b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         Another upshot of this is that if iselStmt can see the
3817b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         entirety of
3818b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3819b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            STbe(...) = TruncF64asF32(arg)
3820b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3821b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         then it can short circuit having to deal with TruncF64asF32
3822b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         individually; instead just compute arg into a 64-bit FP
3823b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         register and do 'fsts' (since that itself does the
3824b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         truncation).
3825b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3826b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         We generate pretty poor code here (should be ok both for
3827b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         32-bit and 64-bit mode); but it is expected that for the most
3828b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         part the latter optimisation will apply and hence this code
3829b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         will not often be used.
3830b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      */
38311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg      fsrc    = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
3832b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      HReg      fdst    = newVRegF(env);
3833b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3834b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3835b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      sub_from_sp( env, 16 );
3836b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      // store as F32, hence truncating
3837b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      addInstr(env, PPCInstr_FpLdSt( False/*store*/, 4,
3838b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                                     fsrc, zero_r1 ));
3839b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      // and reload.  Good huh?! (sigh)
3840b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      addInstr(env, PPCInstr_FpLdSt( True/*load*/, 4,
3841b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                                     fdst, zero_r1 ));
3842b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      add_to_sp( env, 16 );
3843b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      return fdst;
3844b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   }
3845b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
38467d810d793616af057ce861746aa985df3304cb86sewardj   if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_I64UtoF32) {
38477d810d793616af057ce861746aa985df3304cb86sewardj      if (mode64) {
38487d810d793616af057ce861746aa985df3304cb86sewardj         HReg fdst = newVRegF(env);
38491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg isrc = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
38507d810d793616af057ce861746aa985df3304cb86sewardj         HReg r1   = StackFramePtr(env->mode64);
38517d810d793616af057ce861746aa985df3304cb86sewardj         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
38527d810d793616af057ce861746aa985df3304cb86sewardj
38537d810d793616af057ce861746aa985df3304cb86sewardj         /* Set host rounding mode */
38541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
38557d810d793616af057ce861746aa985df3304cb86sewardj
38567d810d793616af057ce861746aa985df3304cb86sewardj         sub_from_sp( env, 16 );
38577d810d793616af057ce861746aa985df3304cb86sewardj
38587d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_Store(8, zero_r1, isrc, True/*mode64*/));
38597d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
38607d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
38617d810d793616af057ce861746aa985df3304cb86sewardj                                       False, False,
38627d810d793616af057ce861746aa985df3304cb86sewardj                                       fdst, fdst));
38637d810d793616af057ce861746aa985df3304cb86sewardj
38647d810d793616af057ce861746aa985df3304cb86sewardj         add_to_sp( env, 16 );
38657d810d793616af057ce861746aa985df3304cb86sewardj
38667d810d793616af057ce861746aa985df3304cb86sewardj         ///* Restore default FPU rounding. */
38677d810d793616af057ce861746aa985df3304cb86sewardj         //set_FPU_rounding_default( env );
38687d810d793616af057ce861746aa985df3304cb86sewardj         return fdst;
38697d810d793616af057ce861746aa985df3304cb86sewardj      } else {
38707d810d793616af057ce861746aa985df3304cb86sewardj         /* 32-bit mode */
38717d810d793616af057ce861746aa985df3304cb86sewardj         HReg fdst = newVRegF(env);
38727d810d793616af057ce861746aa985df3304cb86sewardj         HReg isrcHi, isrcLo;
38737d810d793616af057ce861746aa985df3304cb86sewardj         HReg r1   = StackFramePtr(env->mode64);
38747d810d793616af057ce861746aa985df3304cb86sewardj         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
38757d810d793616af057ce861746aa985df3304cb86sewardj         PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
38767d810d793616af057ce861746aa985df3304cb86sewardj
38771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&isrcHi, &isrcLo, env, e->Iex.Binop.arg2, IEndianess);
38787d810d793616af057ce861746aa985df3304cb86sewardj
38797d810d793616af057ce861746aa985df3304cb86sewardj         /* Set host rounding mode */
38801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
38817d810d793616af057ce861746aa985df3304cb86sewardj
38827d810d793616af057ce861746aa985df3304cb86sewardj         sub_from_sp( env, 16 );
38837d810d793616af057ce861746aa985df3304cb86sewardj
38847d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_Store(4, zero_r1, isrcHi, False/*mode32*/));
38857d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_Store(4, four_r1, isrcLo, False/*mode32*/));
38867d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
38877d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
38887d810d793616af057ce861746aa985df3304cb86sewardj                                       False, False,
38897d810d793616af057ce861746aa985df3304cb86sewardj                                       fdst, fdst));
38907d810d793616af057ce861746aa985df3304cb86sewardj
38917d810d793616af057ce861746aa985df3304cb86sewardj         add_to_sp( env, 16 );
38927d810d793616af057ce861746aa985df3304cb86sewardj
38937d810d793616af057ce861746aa985df3304cb86sewardj         ///* Restore default FPU rounding. */
38947d810d793616af057ce861746aa985df3304cb86sewardj         //set_FPU_rounding_default( env );
38957d810d793616af057ce861746aa985df3304cb86sewardj         return fdst;
38967d810d793616af057ce861746aa985df3304cb86sewardj      }
38977d810d793616af057ce861746aa985df3304cb86sewardj
38987d810d793616af057ce861746aa985df3304cb86sewardj   }
38997d810d793616af057ce861746aa985df3304cb86sewardj
39005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselFltExpr(ppc): No such tag(%u)\n", e->tag);
3901094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   ppIRExpr(e);
39025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselFltExpr_wrk(ppc)");
3903094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
3904094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3905094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3906094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3907094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*--- ISEL: Floating point expressions (64 bit)         ---*/
3908094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3909094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3910094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* Compute a 64-bit floating point value into a register, the identity
3911094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   of which is returned.  As with iselIntExpr_R, the reg may be either
3912094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   real or virtual; in any case it must not be changed by subsequent
3913094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   code emitted by the caller.  */
3914094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3915094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* IEEE 754 formats.  From http://www.freesoft.org/CIE/RFC/1832/32.htm:
3916094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3917094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    Type                  S (1 bit)   E (11 bits)   F (52 bits)
3918094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    ----                  ---------   -----------   -----------
3919094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    signalling NaN        u           2047 (max)    .0uuuuu---u
3920094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion                                                    (with at least
3921094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion                                                     one 1 bit)
3922094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    quiet NaN             u           2047 (max)    .1uuuuu---u
3923094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3924094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    negative infinity     1           2047 (max)    .000000---0
3925094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3926094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    positive infinity     0           2047 (max)    .000000---0
3927094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3928094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    negative zero         1           0             .000000---0
3929094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3930094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    positive zero         0           0             .000000---0
3931094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion*/
3932094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
39331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDblExpr ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3934094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
39351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselDblExpr_wrk( env, e, IEndianess );
3936094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  if 0
3937094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3938094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  endif
3939094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregClass(r) == HRcFlt64);
3940094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregIsVirtual(r));
3941094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   return r;
3942094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
3943094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3944094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* DO NOT CALL THIS DIRECTLY */
39451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3946094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
39474628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
3948094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
3949094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(e);
3950094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(ty == Ity_F64);
3951094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3952dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3953dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
3954094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3955094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3956094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   /* --------- LITERAL --------- */
3957094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Const) {
3958094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      union { UInt u32x2[2]; ULong u64; Double f64; } u;
3959094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u) == 8);
3960094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u.u64) == 8);
3961094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u.f64) == 8);
3962094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u.u32x2) == 8);
3963094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3964094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (e->Iex.Const.con->tag == Ico_F64) {
3965094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         u.f64 = e->Iex.Const.con->Ico.F64;
3966094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
3967094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      else if (e->Iex.Const.con->tag == Ico_F64i) {
3968094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         u.u64 = e->Iex.Const.con->Ico.F64i;
3969094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
3970094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      else
39715b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         vpanic("iselDblExpr(ppc): const");
3972094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
397307b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      if (!mode64) {
3974f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_srcHi = newVRegI(env);
3975f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_srcLo = newVRegI(env);
39767bbac2199faa35fa0f40be6bafe701407940c240sewardj         addInstr(env, PPCInstr_LI(r_srcHi, u.u32x2[0], mode64));
39777bbac2199faa35fa0f40be6bafe701407940c240sewardj         addInstr(env, PPCInstr_LI(r_srcLo, u.u32x2[1], mode64));
3978f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return mk_LoadRR32toFPR( env, r_srcHi, r_srcLo );
397907b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      } else { // mode64
398007b07a966a2fdbcf621251a0c1a8ab84807fb120cerion         HReg r_src = newVRegI(env);
39815b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_LI(r_src, u.u64, mode64));
398207b07a966a2fdbcf621251a0c1a8ab84807fb120cerion         return mk_LoadR64toFPR( env, r_src );         // 1*I64 -> F64
3983f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3984094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3985094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
398640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   /* --------- LOAD --------- */
39871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
3988094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
39895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr;
3990af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj      vassert(e->Iex.Load.ty == Ity_F64);
39911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_F64/*xfer*/,
39921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
39935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dst, am_addr));
3994094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
3995094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3996094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
399740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   /* --------- GET --------- */
3998094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Get) {
3999094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
40005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
40015b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                       GuestStatePtr(mode64) );
40025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt( True/*load*/, 8, r_dst, am_addr ));
4003094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
4004094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4005cd304497d9d869f9b24a002299d3953ee072229bcerion
400640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   /* --------- OPS --------- */
400740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   if (e->tag == Iex_Qop) {
400840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      PPCFpOp fpop = Pfp_INVALID;
400996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian      switch (e->Iex.Qop.details->op) {
401040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MAddF64:    fpop = Pfp_MADDD; break;
401140c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MAddF64r32: fpop = Pfp_MADDS; break;
401240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MSubF64:    fpop = Pfp_MSUBD; break;
401340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MSubF64r32: fpop = Pfp_MSUBS; break;
401440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         default: break;
401540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      }
401640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      if (fpop != Pfp_INVALID) {
401740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         HReg r_dst  = newVRegF(env);
40181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcML  = iselDblExpr(env, e->Iex.Qop.details->arg2,
40191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess);
40201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcMR  = iselDblExpr(env, e->Iex.Qop.details->arg3,
40211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess);
40221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcAcc = iselDblExpr(env, e->Iex.Qop.details->arg4,
40231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess);
40241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Qop.details->arg1, IEndianess );
402540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         addInstr(env, PPCInstr_FpMulAcc(fpop, r_dst,
402640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj                                               r_srcML, r_srcMR, r_srcAcc));
402740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         return r_dst;
402840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      }
402940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   }
403040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj
4031b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (e->tag == Iex_Triop) {
4032420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      IRTriop *triop = e->Iex.Triop.details;
40335b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCFpOp fpop = Pfp_INVALID;
4034420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4035b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_AddF64:    fpop = Pfp_ADDD; break;
4036b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_SubF64:    fpop = Pfp_SUBD; break;
4037b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_MulF64:    fpop = Pfp_MULD; break;
4038b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_DivF64:    fpop = Pfp_DIVD; break;
4039b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_AddF64r32: fpop = Pfp_ADDS; break;
4040b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_SubF64r32: fpop = Pfp_SUBS; break;
4041b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_MulF64r32: fpop = Pfp_MULS; break;
4042b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_DivF64r32: fpop = Pfp_DIVS; break;
4043b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         default: break;
4044094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4045094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (fpop != Pfp_INVALID) {
4046094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg r_dst  = newVRegF(env);
40471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselDblExpr(env, triop->arg2, IEndianess);
40481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDblExpr(env, triop->arg3, IEndianess);
40491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, triop->arg1, IEndianess );
40505b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpBinary(fpop, r_dst, r_srcL, r_srcR));
4051094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return r_dst;
4052094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4053b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   }
4054b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
4055b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (e->tag == Iex_Binop) {
40561a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      PPCFpOp fpop = Pfp_INVALID;
40571a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      switch (e->Iex.Binop.op) {
4058cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_SqrtF64:   fpop = Pfp_SQRT;   break;
4059cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
40601a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      }
4061cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_SQRT) {
40621a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj         HReg fr_dst = newVRegF(env);
40631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
40641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
40651a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj         addInstr(env, PPCInstr_FpUnary(fpop, fr_dst, fr_src));
40661a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj         return fr_dst;
40671a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      }
40681a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj   }
40691a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj
40701a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj   if (e->tag == Iex_Binop) {
4071b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
4072b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      if (e->Iex.Binop.op == Iop_RoundF64toF32) {
4073b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         HReg r_dst = newVRegF(env);
40741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
40751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4076b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         addInstr(env, PPCInstr_FpRSP(r_dst, r_src));
4077b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         //set_FPU_rounding_default( env );
4078b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         return r_dst;
4079b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      }
408007b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
408195d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj      if (e->Iex.Binop.op == Iop_I64StoF64 || e->Iex.Binop.op == Iop_I64UtoF64) {
40827fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         if (mode64) {
40837fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg fdst = newVRegF(env);
40841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg isrc = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
40857fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg r1   = StackFramePtr(env->mode64);
40867fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
408707b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
40887fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            /* Set host rounding mode */
40891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
409007b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
40917fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            sub_from_sp( env, 16 );
409207b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
40937fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_Store(8, zero_r1, isrc, True/*mode64*/));
40947fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
40957fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
409695d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          e->Iex.Binop.op == Iop_I64StoF64,
409795d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          True/*fdst is 64 bit*/,
40987fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                                          fdst, fdst));
40997fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
41007fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            add_to_sp( env, 16 );
41017fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
4102b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
4103b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
41047fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            return fdst;
4105c74373da820d4004fbfab13e136b78bbf3618104sewardj         } else {
4106c74373da820d4004fbfab13e136b78bbf3618104sewardj            /* 32-bit mode */
4107c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg fdst = newVRegF(env);
4108c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg isrcHi, isrcLo;
4109c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg r1   = StackFramePtr(env->mode64);
4110c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
4111c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
4112c74373da820d4004fbfab13e136b78bbf3618104sewardj
41131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&isrcHi, &isrcLo, env, e->Iex.Binop.arg2,
41141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4115c74373da820d4004fbfab13e136b78bbf3618104sewardj
4116c74373da820d4004fbfab13e136b78bbf3618104sewardj            /* Set host rounding mode */
41171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4118c74373da820d4004fbfab13e136b78bbf3618104sewardj
4119c74373da820d4004fbfab13e136b78bbf3618104sewardj            sub_from_sp( env, 16 );
4120c74373da820d4004fbfab13e136b78bbf3618104sewardj
4121c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Store(4, zero_r1, isrcHi, False/*mode32*/));
4122c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Store(4, four_r1, isrcLo, False/*mode32*/));
4123c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
4124c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
412595d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          e->Iex.Binop.op == Iop_I64StoF64,
412695d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          True/*fdst is 64 bit*/,
4127c74373da820d4004fbfab13e136b78bbf3618104sewardj                                          fdst, fdst));
4128c74373da820d4004fbfab13e136b78bbf3618104sewardj
4129c74373da820d4004fbfab13e136b78bbf3618104sewardj            add_to_sp( env, 16 );
4130c74373da820d4004fbfab13e136b78bbf3618104sewardj
4131b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
4132b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
4133c74373da820d4004fbfab13e136b78bbf3618104sewardj            return fdst;
41347fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         }
413507b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      }
4136b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
4137094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4138094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4139094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Unop) {
41405b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCFpOp fpop = Pfp_INVALID;
4141094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      switch (e->Iex.Unop.op) {
4142baf971ad7f6e005109f3301ec9d19c98066b3840sewardj         case Iop_NegF64:     fpop = Pfp_NEG; break;
4143baf971ad7f6e005109f3301ec9d19c98066b3840sewardj         case Iop_AbsF64:     fpop = Pfp_ABS; break;
41441ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj         case Iop_RSqrtEst5GoodF64:      fpop = Pfp_RSQRTE; break;
41450f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_NegINF:  fpop = Pfp_FRIM; break;
41460f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_PosINF:  fpop = Pfp_FRIP; break;
41470f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_NEAREST: fpop = Pfp_FRIN; break;
41480f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_ZERO:    fpop = Pfp_FRIZ; break;
4149094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         default: break;
4150094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4151094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (fpop != Pfp_INVALID) {
4152094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg fr_dst = newVRegF(env);
41531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
41545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpUnary(fpop, fr_dst, fr_src));
4155094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return fr_dst;
4156094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4157094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4158094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4159094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Unop) {
4160094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      switch (e->Iex.Unop.op) {
41617c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_ReinterpI64asF64: {
41627c6dbff15934256b028a69e906cd3f80275c84absewardj            /* Given an I64, produce an IEEE754 double with the same
41637c6dbff15934256b028a69e906cd3f80275c84absewardj               bit pattern. */
41647c6dbff15934256b028a69e906cd3f80275c84absewardj            if (!mode64) {
41657c6dbff15934256b028a69e906cd3f80275c84absewardj               HReg r_srcHi, r_srcLo;
41661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               iselInt64Expr( &r_srcHi, &r_srcLo, env, e->Iex.Unop.arg,
41671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                               IEndianess);
41687c6dbff15934256b028a69e906cd3f80275c84absewardj               return mk_LoadRR32toFPR( env, r_srcHi, r_srcLo );
41697c6dbff15934256b028a69e906cd3f80275c84absewardj            } else {
41701f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
41717c6dbff15934256b028a69e906cd3f80275c84absewardj               return mk_LoadR64toFPR( env, r_src );
41727c6dbff15934256b028a69e906cd3f80275c84absewardj            }
4173094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         }
41744aa412af1d8166cc11f39a6e721df49431d23618sewardj
41757c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_F32toF64: {
41764aa412af1d8166cc11f39a6e721df49431d23618sewardj            if (e->Iex.Unop.arg->tag == Iex_Unop &&
41774aa412af1d8166cc11f39a6e721df49431d23618sewardj                     e->Iex.Unop.arg->Iex.Unop.op == Iop_ReinterpI32asF32 ) {
41784aa412af1d8166cc11f39a6e721df49431d23618sewardj               e = e->Iex.Unop.arg;
41794aa412af1d8166cc11f39a6e721df49431d23618sewardj
41801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               HReg src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
41814aa412af1d8166cc11f39a6e721df49431d23618sewardj               HReg fr_dst = newVRegF(env);
41824aa412af1d8166cc11f39a6e721df49431d23618sewardj               PPCAMode *am_addr;
41834aa412af1d8166cc11f39a6e721df49431d23618sewardj
41844aa412af1d8166cc11f39a6e721df49431d23618sewardj               sub_from_sp( env, 16 );        // Move SP down 16 bytes
41854aa412af1d8166cc11f39a6e721df49431d23618sewardj               am_addr = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
41864aa412af1d8166cc11f39a6e721df49431d23618sewardj
41874aa412af1d8166cc11f39a6e721df49431d23618sewardj               // store src as Ity_I32's
41884aa412af1d8166cc11f39a6e721df49431d23618sewardj               addInstr(env, PPCInstr_Store( 4, am_addr, src, env->mode64 ));
41894aa412af1d8166cc11f39a6e721df49431d23618sewardj
41904aa412af1d8166cc11f39a6e721df49431d23618sewardj               // load single precision float, but the end results loads into a
41914aa412af1d8166cc11f39a6e721df49431d23618sewardj               // 64-bit FP register -- i.e., F64.
41924aa412af1d8166cc11f39a6e721df49431d23618sewardj               addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, fr_dst, am_addr));
41934aa412af1d8166cc11f39a6e721df49431d23618sewardj
41944aa412af1d8166cc11f39a6e721df49431d23618sewardj               add_to_sp( env, 16 );          // Reset SP
41954aa412af1d8166cc11f39a6e721df49431d23618sewardj               return fr_dst;
41964aa412af1d8166cc11f39a6e721df49431d23618sewardj            }
41974aa412af1d8166cc11f39a6e721df49431d23618sewardj
41984aa412af1d8166cc11f39a6e721df49431d23618sewardj
41997c6dbff15934256b028a69e906cd3f80275c84absewardj            /* this is a no-op */
42001f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg res = iselFltExpr(env, e->Iex.Unop.arg, IEndianess);
42017c6dbff15934256b028a69e906cd3f80275c84absewardj            return res;
42027c6dbff15934256b028a69e906cd3f80275c84absewardj         }
42037c6dbff15934256b028a69e906cd3f80275c84absewardj         default:
42047c6dbff15934256b028a69e906cd3f80275c84absewardj            break;
4205094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4206094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4207094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4208094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   /* --------- MULTIPLEX --------- */
420999dd03e04a6914d90d5fee727d61d76905334becflorian   if (e->tag == Iex_ITE) { // VFD
4210094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (ty == Ity_F64
421199dd03e04a6914d90d5fee727d61d76905334becflorian          && typeOfIRExpr(env->type_env,e->Iex.ITE.cond) == Ity_I1) {
42121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr1    = iselDblExpr(env, e->Iex.ITE.iftrue, IEndianess);
42131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr0    = iselDblExpr(env, e->Iex.ITE.iffalse, IEndianess);
4214094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg fr_dst = newVRegF(env);
4215009230b9758291b594e60d7c0243a73d53e81854sewardj         addInstr(env, PPCInstr_FpUnary( Pfp_MOV, fr_dst, fr0 ));
42161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cc = iselCondCode(env, e->Iex.ITE.cond, IEndianess);
421799dd03e04a6914d90d5fee727d61d76905334becflorian         addInstr(env, PPCInstr_FpCMov( cc, fr_dst, fr1 ));
4218094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return fr_dst;
4219094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4220094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4221094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
42225b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselDblExpr(ppc): No such tag(%u)\n", e->tag);
4223094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   ppIRExpr(e);
42245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselDblExpr_wrk(ppc)");
4225094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
4226cd304497d9d869f9b24a002299d3953ee072229bcerion
42271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp32Expr(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4228f704eb2bab3d06d983c850b0bcf243e178060f75carll{
42291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselDfp32Expr_wrk( env, e, IEndianess );
4230f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert(hregClass(r) == HRcFlt64);
4231f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert( hregIsVirtual(r) );
4232f704eb2bab3d06d983c850b0bcf243e178060f75carll   return r;
4233f704eb2bab3d06d983c850b0bcf243e178060f75carll}
4234f704eb2bab3d06d983c850b0bcf243e178060f75carll
4235f704eb2bab3d06d983c850b0bcf243e178060f75carll/* DO NOT CALL THIS DIRECTLY */
42361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp32Expr_wrk(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4237f704eb2bab3d06d983c850b0bcf243e178060f75carll{
4238f704eb2bab3d06d983c850b0bcf243e178060f75carll   Bool mode64 = env->mode64;
4239f704eb2bab3d06d983c850b0bcf243e178060f75carll   IRType ty = typeOfIRExpr( env->type_env, e );
4240f704eb2bab3d06d983c850b0bcf243e178060f75carll
4241f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert( e );
4242f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert( ty == Ity_D32 );
4243f704eb2bab3d06d983c850b0bcf243e178060f75carll
4244f704eb2bab3d06d983c850b0bcf243e178060f75carll   /* --------- GET --------- */
4245f704eb2bab3d06d983c850b0bcf243e178060f75carll   if (e->tag == Iex_Get) {
4246f704eb2bab3d06d983c850b0bcf243e178060f75carll      HReg r_dst = newVRegF( env );
4247f704eb2bab3d06d983c850b0bcf243e178060f75carll      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
4248f704eb2bab3d06d983c850b0bcf243e178060f75carll                                       GuestStatePtr(mode64) );
4249f704eb2bab3d06d983c850b0bcf243e178060f75carll      addInstr( env, PPCInstr_FpLdSt( True/*load*/, 8, r_dst, am_addr ) );
4250f704eb2bab3d06d983c850b0bcf243e178060f75carll      return r_dst;
4251f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4252f704eb2bab3d06d983c850b0bcf243e178060f75carll
4253f704eb2bab3d06d983c850b0bcf243e178060f75carll   /* --------- LOAD --------- */
42541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
4255f704eb2bab3d06d983c850b0bcf243e178060f75carll      PPCAMode* am_addr;
4256f704eb2bab3d06d983c850b0bcf243e178060f75carll      HReg r_dst = newVRegF(env);
4257f704eb2bab3d06d983c850b0bcf243e178060f75carll      vassert(e->Iex.Load.ty == Ity_D32);
42581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_D32/*xfer*/,
42591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
4260f704eb2bab3d06d983c850b0bcf243e178060f75carll      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, r_dst, am_addr));
4261f704eb2bab3d06d983c850b0bcf243e178060f75carll      return r_dst;
4262f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4263f704eb2bab3d06d983c850b0bcf243e178060f75carll
4264f704eb2bab3d06d983c850b0bcf243e178060f75carll   /* --------- OPS --------- */
4265f704eb2bab3d06d983c850b0bcf243e178060f75carll   if (e->tag == Iex_Binop) {
4266f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (e->Iex.Binop.op == Iop_D64toD32) {
4267f704eb2bab3d06d983c850b0bcf243e178060f75carll         HReg fr_dst = newVRegF(env);
42681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
42691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4270f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DRSP, fr_dst, fr_src));
4271f704eb2bab3d06d983c850b0bcf243e178060f75carll         return fr_dst;
4272f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
4273f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4274f704eb2bab3d06d983c850b0bcf243e178060f75carll
4275f704eb2bab3d06d983c850b0bcf243e178060f75carll   ppIRExpr( e );
4276f704eb2bab3d06d983c850b0bcf243e178060f75carll   vpanic( "iselDfp32Expr_wrk(ppc)" );
4277f704eb2bab3d06d983c850b0bcf243e178060f75carll}
4278f704eb2bab3d06d983c850b0bcf243e178060f75carll
42791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp64Expr(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4280c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
42811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselDfp64Expr_wrk( env, e, IEndianess );
4282c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(r) == HRcFlt64);
4283c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( hregIsVirtual(r) );
4284c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   return r;
4285c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4286c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4287c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* DO NOT CALL THIS DIRECTLY */
42881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp64Expr_wrk(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4289c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
4290c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   Bool mode64 = env->mode64;
4291c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   IRType ty = typeOfIRExpr( env->type_env, e );
4292c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   HReg r_dstHi, r_dstLo;
4293c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4294c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( e );
4295c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( ty == Ity_D64 );
4296c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4297c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_RdTmp) {
4298c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return lookupIRTemp( env, e->Iex.RdTmp.tmp );
4299c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4300c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4301c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* --------- GET --------- */
4302c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Get) {
4303c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_dst = newVRegF( env );
4304c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
4305c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                       GuestStatePtr(mode64) );
4306c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      addInstr( env, PPCInstr_FpLdSt( True/*load*/, 8, r_dst, am_addr ) );
4307c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return r_dst;
4308c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4309c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
43101f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
4311f704eb2bab3d06d983c850b0bcf243e178060f75carll      PPCAMode* am_addr;
4312f704eb2bab3d06d983c850b0bcf243e178060f75carll      HReg r_dst = newVRegF(env);
4313f704eb2bab3d06d983c850b0bcf243e178060f75carll      vassert(e->Iex.Load.ty == Ity_D64);
43141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_D64/*xfer*/,
43151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
4316f704eb2bab3d06d983c850b0bcf243e178060f75carll      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dst, am_addr));
4317f704eb2bab3d06d983c850b0bcf243e178060f75carll      return r_dst;
4318f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4319f704eb2bab3d06d983c850b0bcf243e178060f75carll
4320c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* --------- OPS --------- */
4321c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Qop) {
4322c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_dst = newVRegF( env );
4323c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return r_dst;
4324c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4325c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4326c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Unop) {
4327cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      HReg fr_dst = newVRegF(env);
4328cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      switch (e->Iex.Unop.op) {
4329cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_ReinterpI64asD64: {
4330cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         /* Given an I64, produce an IEEE754 DFP with the same
4331cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj               bit pattern. */
4332cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         if (!mode64) {
4333cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            HReg r_srcHi, r_srcLo;
43341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr( &r_srcHi, &r_srcLo, env, e->Iex.Unop.arg,
43351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
4336cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            return mk_LoadRR32toFPR( env, r_srcHi, r_srcLo );
4337cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         } else {
43381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
4339cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            return mk_LoadR64toFPR( env, r_src );
4340cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         }
4341cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4342cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_D32toD64: {
43431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr(env, e->Iex.Unop.arg, IEndianess);
4344cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DCTDP, fr_dst, fr_src));
4345cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4346cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4347c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_D128HItoD64:
43481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_dstHi, &r_dstLo, env, e->Iex.Unop.arg,
43491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                         IEndianess );
4350c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return r_dstHi;
4351c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_D128LOtoD64:
43521f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_dstHi, &r_dstLo, env, e->Iex.Unop.arg,
43531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                         IEndianess );
4354c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return r_dstLo;
4355cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_InsertExpD64: {
43561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_srcL = iselDblExpr(env, e->Iex.Binop.arg1, IEndianess);
43571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_srcR = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
4358cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4359cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_Dfp64Binary(Pfp_DIEX, fr_dst, fr_srcL,
4360cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj					    fr_srcR));
4361cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4362cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       }
4363c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4364c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         vex_printf( "ERROR: iselDfp64Expr_wrk, UNKNOWN unop case %d\n",
4365c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                     e->Iex.Unop.op );
4366c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4367c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4368c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
436926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   if (e->tag == Iex_Binop) {
4370cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      PPCFpOp fpop = Pfp_INVALID;
4371cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      HReg fr_dst = newVRegF(env);
437226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
437326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      switch (e->Iex.Binop.op) {
4374cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_D128toD64:     fpop = Pfp_DRDPQ;  break;
4375cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_D64toD32:      fpop = Pfp_DRSP;   break;
4376cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_I64StoD64:     fpop = Pfp_DCFFIX; break;
4377cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_RoundD64toInt: fpop = Pfp_DRINTN; break;
4378cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      default: break;
437926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4380cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_DRDPQ) {
438126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg r_srcHi = newVRegF(env);
438226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg r_srcLo = newVRegF(env);
438326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
43841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
43851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
43861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
438726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_DfpD128toD64(fpop, fr_dst, r_srcHi, r_srcLo));
438826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         return fr_dst;
4389cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4390cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DRINTN) {
4391cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg fr_src = newVRegF(env);
43921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* r_rmc = iselWordExpr_RI(env, e->Iex.Binop.arg1, IEndianess);
4393cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4394cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* NOTE, this IOP takes a DFP value and rounds to the
4395cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * neares floating point integer value, i.e. fractional part
4396cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * is zero.  The result is a decimal floating point number.
4397cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * the INT in the name is a bit misleading.
4398cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          */
43991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
4400cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpRound(fr_dst, fr_src, r_rmc));
4401cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
440226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4403cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DRSP) {
44041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
44051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
440626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_Dfp64Unary(fpop, fr_dst, fr_src));
440726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         return fr_dst;
4408cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4409cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DCFFIX) {
4410cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg fr_src = newVRegF(env);
4411cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4412cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
44131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4414cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4415cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4416cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the I64 value into a floating point register
4417cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (mode64) {
44181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll           HReg tmp = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
4419cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4420cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll           addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4421cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4422cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi, tmpLo;
4423cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4424cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
44251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Binop.arg2,
44261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4427cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*mode32*/));
4428cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*mode32*/));
4429cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
4430cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4431cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8,  fr_src, zero_r1));
4432cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Unary(fpop, fr_dst, fr_src));
4433cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4434cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return fr_dst;
443526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4436cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4437cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      switch (e->Iex.Binop.op) {
4438e83db484fd409aa84e3d7307a6a770c28b8c0c16carll      /* shift instructions D64, I32 -> D64 */
4439cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_ShlD64: fpop = Pfp_DSCLI; break;
4440cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_ShrD64: fpop = Pfp_DSCRI; break;
4441cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
4442cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4443cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      if (fpop != Pfp_INVALID) {
44441f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg1, IEndianess);
44451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* shift = iselWordExpr_RI(env, e->Iex.Binop.arg2, IEndianess);
4446cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4447e83db484fd409aa84e3d7307a6a770c28b8c0c16carll         /* shift value must be an immediate value */
4448e83db484fd409aa84e3d7307a6a770c28b8c0c16carll         vassert(shift->tag == Pri_Imm);
4449e83db484fd409aa84e3d7307a6a770c28b8c0c16carll
4450cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpShift(fpop, fr_dst, fr_src, shift));
4451cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4452cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4453cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4454cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      switch (e->Iex.Binop.op) {
4455cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_InsertExpD64:
4456cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         fpop = Pfp_DIEX;
4457cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         break;
4458cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: 	break;
4459cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4460cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      if (fpop != Pfp_INVALID) {
4461cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg fr_srcL = newVRegF(env);
44621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_srcR = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
4463cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4464cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4465cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4466cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64) {
4467cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the I64 value into a floating point reg
44681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg tmp = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
4469cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4470cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4471cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4472cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the I64 register pair into a floating point reg
4473cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi;
4474cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpLo;
4475cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4476cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
44771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Binop.arg1,
44781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4479cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*!mode64*/));
4480cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*!mode64*/));
4481cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
4482cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fr_srcL, zero_r1));
4483cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Binary(fpop, fr_dst, fr_srcL,
4484cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                            fr_srcR));
4485cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4486cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4487cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
448826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   }
448926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4490c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Triop) {
4491420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      IRTriop *triop = e->Iex.Triop.details;
4492c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      PPCFpOp fpop = Pfp_INVALID;
4493c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4494420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4495c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_AddD64:
4496c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPADD;
4497c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4498c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_SubD64:
4499c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPSUB;
4500c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4501c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_MulD64:
4502c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPMUL;
4503c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4504c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_DivD64:
4505c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPDIV;
4506c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4507c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4508c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4509c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4510c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (fpop != Pfp_INVALID) {
4511c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_dst = newVRegF( env );
45121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselDfp64Expr( env, triop->arg2, IEndianess );
45131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDfp64Expr( env, triop->arg3, IEndianess );
4514c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
45151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, triop->arg1, IEndianess );
4516c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Binary( fpop, r_dst, r_srcL, r_srcR ) );
4517c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return r_dst;
4518c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4519cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4520420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4521cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_QuantizeD64:          fpop = Pfp_DQUA;  break;
4522cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_SignificanceRoundD64: fpop = Pfp_RRDTR; break;
4523cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
4524cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4525cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_DQUA) {
4526cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dst = newVRegF(env);
45271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselDfp64Expr(env, triop->arg2, IEndianess);
45281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDfp64Expr(env, triop->arg3, IEndianess);
45291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc  = iselWordExpr_RI(env, triop->arg1, IEndianess);
4530cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpQuantize(fpop, r_dst, r_srcL, r_srcR,
4531cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                            rmc));
4532cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return r_dst;
4533cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4534cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_RRDTR) {
4535cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_dst = newVRegF(env);
4536cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcL = newVRegF(env);
45371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDfp64Expr(env, triop->arg3, IEndianess);
45381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc  = iselWordExpr_RI(env, triop->arg1, IEndianess);
4539cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
45401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg i8_val = iselWordExpr_R(env, triop->arg2, IEndianess);
4541cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4542cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Move I8 to float register to issue instruction */
4543cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4544cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (mode64)
4545cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, i8_val, True/*mode64*/));
4546cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         else
4547cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, i8_val, False/*mode32*/));
4548cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4549cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_srcL, zero_r1));
4550cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4551cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4552cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // will set TE and RMC when issuing instruction
4553cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpQuantize(fpop, r_dst, r_srcL, r_srcR, rmc));
4554cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return r_dst;
4555cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4556c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4557c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4558c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   ppIRExpr( e );
4559c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vpanic( "iselDfp64Expr_wrk(ppc)" );
4560c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4561c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
45621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void iselDfp128Expr(HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e,
45631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IREndness IEndianess)
4564c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
45651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselDfp128Expr_wrk( rHi, rLo, env, e, IEndianess );
4566c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( hregIsVirtual(*rHi) );
4567c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( hregIsVirtual(*rLo) );
4568c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4569c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4570c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* DO NOT CALL THIS DIRECTLY */
45711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void iselDfp128Expr_wrk(HReg* rHi, HReg *rLo, ISelEnv* env, IRExpr* e,
45721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                               IREndness IEndianess)
4573c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
4574c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( e );
4575c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( typeOfIRExpr(env->type_env,e) == Ity_D128 );
4576c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4577c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* read 128-bit IRTemp */
4578c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_RdTmp) {
4579c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      lookupIRTempPair( rHi, rLo, env, e->Iex.RdTmp.tmp );
4580c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return;
4581c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4582c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
458326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   if (e->tag == Iex_Unop) {
458426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      HReg r_dstHi = newVRegF(env);
458526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      HReg r_dstLo = newVRegF(env);
458626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
458726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      if (e->Iex.Unop.op == Iop_I64StoD128) {
4588cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg fr_src = newVRegF(env);
4589cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4590cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4591cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the I64 value into a floating point reg
4592cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64) {
45931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg tmp   = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
4594cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4595cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4596cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi, tmpLo;
4597cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4598cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
45991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Unop.arg,
46001f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4601cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*mode32*/));
4602cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*mode32*/));
4603cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
460426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4605cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fr_src, zero_r1));
4606cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpI64StoD128(Pfp_DCFFIXQ, r_dstHi, r_dstLo,
4607cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                              fr_src));
460826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4609cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
461026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      if (e->Iex.Unop.op == Iop_D64toD128) {
46111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
461226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4613cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Source is 64bit, result is 128 bit.  High 64bit source arg,
461426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          * is ignored by the instruction.  Set high arg to r_src just
461526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          * to meet the vassert tests.
461626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          */
4617cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp128Unary(Pfp_DCTQPQ, r_dstHi, r_dstLo,
461826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                                            r_src, r_src));
461926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
462026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      *rHi = r_dstHi;
462126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      *rLo = r_dstLo;
462226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      return;
462326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   }
462426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4625c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* --------- OPS --------- */
4626c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Binop) {
4627c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_srcHi;
4628c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_srcLo;
4629c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4630c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      switch (e->Iex.Binop.op) {
4631c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_D64HLtoD128:
46321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         r_srcHi = iselDfp64Expr( env, e->Iex.Binop.arg1, IEndianess );
46331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         r_srcLo = iselDfp64Expr( env, e->Iex.Binop.arg2, IEndianess );
4634c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_srcHi;
4635c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_srcLo;
4636c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
4637c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
463826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      case Iop_D128toD64: {
463926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         PPCFpOp fpop = Pfp_DRDPQ;
464026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg fr_dst  = newVRegF(env);
464126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
46421f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
46431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
46441f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
464526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_DfpD128toD64(fpop, fr_dst, r_srcHi, r_srcLo));
464626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
464726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         /* Need to meet the interface spec but the result is
464826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          * just 64-bits so send the result back in both halfs.
464926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          */
465026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rHi = fr_dst;
465126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rLo = fr_dst;
465226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         return;
465326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
465426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      case Iop_ShlD128:
465526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      case Iop_ShrD128: {
465626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg fr_dst_hi = newVRegF(env);
465726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg fr_dst_lo = newVRegF(env);
46581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* shift = iselWordExpr_RI(env, e->Iex.Binop.arg2, IEndianess);
465926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         PPCFpOp fpop = Pfp_DSCLIQ;  /* fix later if necessary */
466026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
46611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg1,
46621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
466326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
466426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         if (e->Iex.Binop.op == Iop_ShrD128)
466526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj            fpop = Pfp_DSCRIQ;
466626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
466726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_DfpShift128(fpop, fr_dst_hi, fr_dst_lo,
466826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                                            r_srcHi, r_srcLo, shift));
466926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
467026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rHi = fr_dst_hi;
467126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rLo = fr_dst_lo;
4672cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
4673cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4674cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_RoundD128toInt: {
4675cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstHi = newVRegF(env);
4676cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstLo = newVRegF(env);
46771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* r_rmc = iselWordExpr_RI(env, e->Iex.Binop.arg1, IEndianess);
4678cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4679cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         // will set R and RMC when issuing instruction
46801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
46811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
4682cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4683cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpRound128(r_dstHi, r_dstLo,
4684cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                            r_srcHi, r_srcLo, r_rmc));
4685cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rHi = r_dstHi;
4686cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rLo = r_dstLo;
4687cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
4688cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4689cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_InsertExpD128: {
4690cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstHi = newVRegF(env);
4691cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstLo = newVRegF(env);
4692cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_srcL  = newVRegF(env);
4693cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4694cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         r_srcHi = newVRegF(env);
4695cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         r_srcLo = newVRegF(env);
4696cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
46971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
46981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
4699cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4700cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Move I64 to float register to issue instruction */
4701cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64) {
47021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg tmp = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
4703cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4704cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4705cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi, tmpLo;
4706cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4707cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
47081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Unop.arg,
47091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4710cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*mode32*/));
4711cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*mode32*/));
4712cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
4713cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4714cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_srcL, zero_r1));
4715cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_InsertExpD128(Pfp_DIEXQ,
4716cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                              r_dstHi, r_dstLo,
4717cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                              r_srcL, r_srcHi, r_srcLo));
4718cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rHi = r_dstHi;
4719cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rLo = r_dstLo;
4720cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
472126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4722c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4723cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         vex_printf( "ERROR: iselDfp128Expr_wrk, UNKNOWN binop case %d\n",
4724c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                     e->Iex.Binop.op );
4725c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4726c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4727c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4728c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4729c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Triop) {
4730420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      IRTriop *triop = e->Iex.Triop.details;
4731c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      PPCFpOp fpop = Pfp_INVALID;
4732cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      HReg r_dstHi = newVRegF(env);
4733cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      HReg r_dstLo = newVRegF(env);
4734cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4735420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4736c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_AddD128:
4737c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPADDQ;
4738c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4739c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_SubD128:
4740c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPSUBQ;
4741c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4742c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_MulD128:
4743c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPMULQ;
4744c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4745c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_DivD128:
4746c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPDIVQ;
4747c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4748c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4749c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4750c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4751c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4752c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (fpop != Pfp_INVALID) {
4753c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_srcRHi = newVRegV( env );
4754c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_srcRLo = newVRegV( env );
4755c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4756c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         /* dst will be used to pass in the left operand and get the result. */
47571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_dstHi, &r_dstLo, env, triop->arg2, IEndianess );
47581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_srcRHi, &r_srcRLo, env, triop->arg3, IEndianess );
47591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, triop->arg1, IEndianess );
4760c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env,
4761c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                   PPCInstr_Dfp128Binary( fpop, r_dstHi, r_dstLo,
4762c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                          r_srcRHi, r_srcRLo ) );
4763c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_dstHi;
4764c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_dstLo;
4765c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
4766c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4767420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4768cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_QuantizeD128:          fpop = Pfp_DQUAQ;  break;
4769cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_SignificanceRoundD128: fpop = Pfp_DRRNDQ; break;
4770cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
4771cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4772cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_DQUAQ) {
4773cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_srcHi = newVRegF(env);
4774cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_srcLo = newVRegF(env);
47751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc = iselWordExpr_RI(env, triop->arg1, IEndianess);
4776cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4777cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         /* dst will be used to pass in the left operand and get the result */
47781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_dstHi, &r_dstLo, env, triop->arg2, IEndianess);
47791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, triop->arg3, IEndianess);
4780cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4781cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         // will set RMC when issuing instruction
4782cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpQuantize128(fpop, r_dstHi, r_dstLo,
4783cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                               r_srcHi, r_srcLo, rmc));
4784cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        *rHi = r_dstHi;
4785cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        *rLo = r_dstLo;
4786cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return;
4787cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4788cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DRRNDQ) {
4789cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcHi = newVRegF(env);
4790cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcLo = newVRegF(env);
47911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc = iselWordExpr_RI(env, triop->arg1, IEndianess);
4792cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4793cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
47941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg i8_val = iselWordExpr_R(env, triop->arg2, IEndianess);
4795cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_zero = newVRegI( env );
4796cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
47971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, triop->arg3, IEndianess);
4798cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4799cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* dst will be used to pass in the left operand and get the result */
4800cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Move I8 to float register to issue instruction.  Note, the
4801cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * instruction only looks at the bottom 6 bits so we really don't
4802cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * have to clear the upper bits since the iselWordExpr_R sets the
4803cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * bottom 8-bits.
4804cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          */
4805cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4806cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4807cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64)
4808cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, i8_val, True/*mode64*/));
4809cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         else
4810cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, i8_val, False/*mode32*/));
4811cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4812cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Have to write to the upper bits to ensure they have been
4813cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * initialized. The instruction ignores all but the lower 6-bits.
4814cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          */
4815cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr( env, PPCInstr_LI( r_zero, 0, env->mode64 ) );
4816cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dstHi, zero_r1));
4817cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dstLo, zero_r1));
4818cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4819cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4820cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4821cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // will set RMC when issuing instruction
4822cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpQuantize128(fpop, r_dstHi, r_dstLo,
4823cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                               r_srcHi, r_srcLo, rmc));
4824cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rHi = r_dstHi;
4825cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rLo = r_dstLo;
4826cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
4827cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4828cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll }
4829c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4830c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   ppIRExpr( e );
483126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   vpanic( "iselDfp128Expr(ppc64)" );
4832c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4833c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4834cd304497d9d869f9b24a002299d3953ee072229bcerion
4835e21595a704c11ce19b8cd73df03fdcbe483517eecerion/*---------------------------------------------------------*/
4836e21595a704c11ce19b8cd73df03fdcbe483517eecerion/*--- ISEL: SIMD (Vector) expressions, 128 bit.         ---*/
4837e21595a704c11ce19b8cd73df03fdcbe483517eecerion/*---------------------------------------------------------*/
4838e21595a704c11ce19b8cd73df03fdcbe483517eecerion
48391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselVecExpr ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
4840e21595a704c11ce19b8cd73df03fdcbe483517eecerion{
48411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselVecExpr_wrk( env, e, IEndianess );
4842e21595a704c11ce19b8cd73df03fdcbe483517eecerion#  if 0
4843e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
4844e21595a704c11ce19b8cd73df03fdcbe483517eecerion#  endif
4845e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(hregClass(r) == HRcVec128);
4846e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(hregIsVirtual(r));
4847e21595a704c11ce19b8cd73df03fdcbe483517eecerion   return r;
4848e21595a704c11ce19b8cd73df03fdcbe483517eecerion}
4849e21595a704c11ce19b8cd73df03fdcbe483517eecerion
4850e21595a704c11ce19b8cd73df03fdcbe483517eecerion/* DO NOT CALL THIS DIRECTLY */
48511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
4852e21595a704c11ce19b8cd73df03fdcbe483517eecerion{
48534628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
48545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   PPCAvOp op = Pav_INVALID;
4855e522d4bbf9e59873859c2f0693450a176fb2b996sewardj   PPCAvFpOp fpop = Pavfp_INVALID;
48565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   IRType  ty = typeOfIRExpr(env->type_env,e);
4857e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(e);
4858e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(ty == Ity_V128);
4859e21595a704c11ce19b8cd73df03fdcbe483517eecerion
4860dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
4861dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
4862e21595a704c11ce19b8cd73df03fdcbe483517eecerion   }
4863e21595a704c11ce19b8cd73df03fdcbe483517eecerion
4864e21595a704c11ce19b8cd73df03fdcbe483517eecerion   if (e->tag == Iex_Get) {
48655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      /* Guest state vectors are 16byte aligned,
48665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         so don't need to worry here */
4867e21595a704c11ce19b8cd73df03fdcbe483517eecerion      HReg dst = newVRegV(env);
4868e21595a704c11ce19b8cd73df03fdcbe483517eecerion      addInstr(env,
48695b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCInstr_AvLdSt( True/*load*/, 16, dst,
48705b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                PPCAMode_IR( e->Iex.Get.offset,
48715b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                             GuestStatePtr(mode64) )));
4872e21595a704c11ce19b8cd73df03fdcbe483517eecerion      return dst;
4873e21595a704c11ce19b8cd73df03fdcbe483517eecerion   }
4874e21595a704c11ce19b8cd73df03fdcbe483517eecerion
48751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
487685175a7453c4cc4a7d29a247766b627d5cb933decarll      /* Need to be able to do V128 unaligned loads. The BE unaligned load
487785175a7453c4cc4a7d29a247766b627d5cb933decarll       * can be accomplised using the following code sequece from the ISA.
487885175a7453c4cc4a7d29a247766b627d5cb933decarll       * It uses the lvx instruction that does two aligned loads and then
48799877fe5792c32f04fa31018a72928903031a12e8carll       * permute the data to store the required data as if it had been an
48809877fe5792c32f04fa31018a72928903031a12e8carll       * unaligned load.
48819877fe5792c32f04fa31018a72928903031a12e8carll       *
48829877fe5792c32f04fa31018a72928903031a12e8carll       *   lvx  Vhi,0,Rb        # load MSQ, using the unaligned address in Rb
48839877fe5792c32f04fa31018a72928903031a12e8carll       *   lvsl Vp, 0,Rb        # Set permute control vector
48849877fe5792c32f04fa31018a72928903031a12e8carll       *   addi Rb,Rb,15        # Address of LSQ
48859877fe5792c32f04fa31018a72928903031a12e8carll       *   lvx  Vlo,0,Rb        # load LSQ
48869877fe5792c32f04fa31018a72928903031a12e8carll       *   vperm Vt,Vhi,Vlo,Vp  # align the data as requested
48879877fe5792c32f04fa31018a72928903031a12e8carll       */
48889877fe5792c32f04fa31018a72928903031a12e8carll
48899877fe5792c32f04fa31018a72928903031a12e8carll      HReg Vhi   = newVRegV(env);
48909877fe5792c32f04fa31018a72928903031a12e8carll      HReg Vlo   = newVRegV(env);
48919877fe5792c32f04fa31018a72928903031a12e8carll      HReg Vp    = newVRegV(env);
4892a50fde5504e829e5154113d7e507f12707089f48cerion      HReg v_dst = newVRegV(env);
48939877fe5792c32f04fa31018a72928903031a12e8carll      HReg rB;
48949877fe5792c32f04fa31018a72928903031a12e8carll      HReg rB_plus_15 = newVRegI(env);
48959877fe5792c32f04fa31018a72928903031a12e8carll
4896a50fde5504e829e5154113d7e507f12707089f48cerion      vassert(e->Iex.Load.ty == Ity_V128);
48979877fe5792c32f04fa31018a72928903031a12e8carll      rB = iselWordExpr_R( env, e->Iex.Load.addr, IEndianess );
48989877fe5792c32f04fa31018a72928903031a12e8carll
48999877fe5792c32f04fa31018a72928903031a12e8carll      // lvx  Vhi, 0, Rb
49009877fe5792c32f04fa31018a72928903031a12e8carll      addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, Vhi,
49019877fe5792c32f04fa31018a72928903031a12e8carll                                     PPCAMode_IR(0, rB)) );
49029877fe5792c32f04fa31018a72928903031a12e8carll
490385175a7453c4cc4a7d29a247766b627d5cb933decarll      if (IEndianess == Iend_LE)
490485175a7453c4cc4a7d29a247766b627d5cb933decarll         // lvsr Vp, 0, Rb
490585175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvSh( False/*right shift*/, Vp,
490685175a7453c4cc4a7d29a247766b627d5cb933decarll                                      PPCAMode_IR(0, rB)) );
490785175a7453c4cc4a7d29a247766b627d5cb933decarll      else
490885175a7453c4cc4a7d29a247766b627d5cb933decarll         // lvsl Vp, 0, Rb
490985175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvSh( True/*left shift*/, Vp,
491085175a7453c4cc4a7d29a247766b627d5cb933decarll                                      PPCAMode_IR(0, rB)) );
49119877fe5792c32f04fa31018a72928903031a12e8carll
49129877fe5792c32f04fa31018a72928903031a12e8carll      // addi Rb_plus_15, Rb, 15
49139877fe5792c32f04fa31018a72928903031a12e8carll      addInstr(env, PPCInstr_Alu( Palu_ADD, rB_plus_15,
49149877fe5792c32f04fa31018a72928903031a12e8carll                                  rB, PPCRH_Imm(True, toUShort(15))) );
49159877fe5792c32f04fa31018a72928903031a12e8carll
49169877fe5792c32f04fa31018a72928903031a12e8carll      // lvx  Vlo, 0, Rb_plus_15
49179877fe5792c32f04fa31018a72928903031a12e8carll      addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, Vlo,
49189877fe5792c32f04fa31018a72928903031a12e8carll                                     PPCAMode_IR(0, rB_plus_15)) );
49199877fe5792c32f04fa31018a72928903031a12e8carll
492085175a7453c4cc4a7d29a247766b627d5cb933decarll      if (IEndianess == Iend_LE)
492185175a7453c4cc4a7d29a247766b627d5cb933decarll         // vperm Vt, Vhi, Vlo, Vp
492285175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvPerm( v_dst, Vlo, Vhi, Vp ));
492385175a7453c4cc4a7d29a247766b627d5cb933decarll      else
492485175a7453c4cc4a7d29a247766b627d5cb933decarll         // vperm Vt, Vhi, Vlo, Vp
492585175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvPerm( v_dst, Vhi, Vlo, Vp ));
492685175a7453c4cc4a7d29a247766b627d5cb933decarll
4927a50fde5504e829e5154113d7e507f12707089f48cerion      return v_dst;
4928a50fde5504e829e5154113d7e507f12707089f48cerion   }
4929a50fde5504e829e5154113d7e507f12707089f48cerion
4930f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   if (e->tag == Iex_Unop) {
4931f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      switch (e->Iex.Unop.op) {
4932f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
4933225a034683024109da729a4d2f080364b9485007cerion      case Iop_NotV128: {
49341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
4935225a034683024109da729a4d2f080364b9485007cerion         HReg dst = newVRegV(env);
49365b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, arg));
4937225a034683024109da729a4d2f080364b9485007cerion         return dst;
4938225a034683024109da729a4d2f080364b9485007cerion      }
4939225a034683024109da729a4d2f080364b9485007cerion
4940dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj      case Iop_CmpNEZ8x16: {
49411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
4942dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         HReg zero = newVRegV(env);
4943dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         HReg dst  = newVRegV(env);
49445b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49455b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin8x16(Pav_CMPEQU, dst, arg, zero));
49465b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
4947dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         return dst;
4948dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj      }
49491bee561912427ca8f8998c89b62d86ba2ee49732sewardj
49501bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_CmpNEZ16x8: {
49511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49521bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg zero = newVRegV(env);
49531bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg dst  = newVRegV(env);
49545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49555b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin16x8(Pav_CMPEQU, dst, arg, zero));
49565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
49571bee561912427ca8f8998c89b62d86ba2ee49732sewardj         return dst;
49581bee561912427ca8f8998c89b62d86ba2ee49732sewardj      }
49591bee561912427ca8f8998c89b62d86ba2ee49732sewardj
49601bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_CmpNEZ32x4: {
49611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49621bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg zero = newVRegV(env);
49631bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg dst  = newVRegV(env);
49645b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32x4(Pav_CMPEQU, dst, arg, zero));
49665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
49671bee561912427ca8f8998c89b62d86ba2ee49732sewardj         return dst;
49681bee561912427ca8f8998c89b62d86ba2ee49732sewardj      }
49691bee561912427ca8f8998c89b62d86ba2ee49732sewardj
49700c74bb5aa3240f693df0568d578baabf0c376dc4carll      case Iop_CmpNEZ64x2: {
49711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49720c74bb5aa3240f693df0568d578baabf0c376dc4carll         HReg zero = newVRegV(env);
49730c74bb5aa3240f693df0568d578baabf0c376dc4carll         HReg dst  = newVRegV(env);
49740c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49750c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvBin64x2(Pav_CMPEQU, dst, arg, zero));
49760c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
49770c74bb5aa3240f693df0568d578baabf0c376dc4carll         return dst;
49780c74bb5aa3240f693df0568d578baabf0c376dc4carll      }
49790c74bb5aa3240f693df0568d578baabf0c376dc4carll
49801ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      case Iop_RecipEst32Fx4: fpop = Pavfp_RCPF;    goto do_32Fx4_unary;
49811ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      case Iop_RSqrtEst32Fx4: fpop = Pavfp_RSQRTF;  goto do_32Fx4_unary;
4982e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_I32UtoFx4:     fpop = Pavfp_CVTU2F;  goto do_32Fx4_unary;
4983e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_I32StoFx4:     fpop = Pavfp_CVTS2F;  goto do_32Fx4_unary;
4984e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_QFtoI32Ux4_RZ: fpop = Pavfp_QCVTF2U; goto do_32Fx4_unary;
4985e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_QFtoI32Sx4_RZ: fpop = Pavfp_QCVTF2S; goto do_32Fx4_unary;
4986e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RM: fpop = Pavfp_ROUNDM;  goto do_32Fx4_unary;
4987e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RP: fpop = Pavfp_ROUNDP;  goto do_32Fx4_unary;
4988e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RN: fpop = Pavfp_ROUNDN;  goto do_32Fx4_unary;
4989e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RZ: fpop = Pavfp_ROUNDZ;  goto do_32Fx4_unary;
49908ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      do_32Fx4_unary:
49918ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      {
49921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49938ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg dst = newVRegV(env);
4994e522d4bbf9e59873859c2f0693450a176fb2b996sewardj         addInstr(env, PPCInstr_AvUn32Fx4(fpop, dst, arg));
49958ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         return dst;
49968ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      }
49978ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
4998225a034683024109da729a4d2f080364b9485007cerion      case Iop_32UtoV128: {
4999197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         HReg r_aligned16, r_zeros;
50001f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
5001225a034683024109da729a4d2f080364b9485007cerion         HReg   dst = newVRegV(env);
50025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode *am_off0, *am_off4, *am_off8, *am_off12;
5003225a034683024109da729a4d2f080364b9485007cerion         sub_from_sp( env, 32 );     // Move SP down
5004225a034683024109da729a4d2f080364b9485007cerion
5005225a034683024109da729a4d2f080364b9485007cerion         /* Get a quadword aligned address within our stack space */
5006197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         r_aligned16 = get_sp_aligned16( env );
50075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off0  = PPCAMode_IR( 0,  r_aligned16 );
50085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off4  = PPCAMode_IR( 4,  r_aligned16 );
50095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off8  = PPCAMode_IR( 8,  r_aligned16 );
50105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off12 = PPCAMode_IR( 12, r_aligned16 );
5011225a034683024109da729a4d2f080364b9485007cerion
5012197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         /* Store zeros */
5013197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         r_zeros = newVRegI(env);
50145b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_LI(r_zeros, 0x0, mode64));
50151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
50161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off0, r_src, mode64 ));
50171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
50181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off0, r_zeros, mode64 ));
50195b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_off4, r_zeros, mode64 ));
50205b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_off8, r_zeros, mode64 ));
5021225a034683024109da729a4d2f080364b9485007cerion
5022225a034683024109da729a4d2f080364b9485007cerion         /* Store r_src in low word of quadword-aligned mem */
50231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
50241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off12, r_zeros, mode64 ));
50251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
50261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off12, r_src, mode64 ));
5027225a034683024109da729a4d2f080364b9485007cerion
5028225a034683024109da729a4d2f080364b9485007cerion         /* Load word into low word of quadword vector reg */
50291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
50301f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_AvLdSt( True/*ld*/, 4, dst, am_off0 ));
50311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
50321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_AvLdSt( True/*ld*/, 4, dst, am_off12 ));
5033225a034683024109da729a4d2f080364b9485007cerion
5034225a034683024109da729a4d2f080364b9485007cerion         add_to_sp( env, 32 );       // Reset SP
5035225a034683024109da729a4d2f080364b9485007cerion         return dst;
5036225a034683024109da729a4d2f080364b9485007cerion      }
5037225a034683024109da729a4d2f080364b9485007cerion
503892d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_Dup8x16:
503992d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_Dup16x8:
504092d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_Dup32x4:
50411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         return mk_AvDuplicateRI(env, e->Iex.Unop.arg, IEndianess);
504227b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
50437deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_CipherSV128: op = Pav_CIPHERSUBV128; goto do_AvCipherV128Un;
50447deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvCipherV128Un: {
50451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
50467deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst = newVRegV(env);
50477deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvCipherV128Unary(op, dst, arg));
50487deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
50497deaf9552b546b847528cf39b38898fb7742b5f5carll      }
50507deaf9552b546b847528cf39b38898fb7742b5f5carll
5051a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz8x16: op = Pav_ZEROCNTBYTE;   goto do_zerocnt;
5052a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz16x8: op = Pav_ZEROCNTHALF;   goto do_zerocnt;
5053a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz32x4: op = Pav_ZEROCNTWORD;   goto do_zerocnt;
5054a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz64x2: op = Pav_ZEROCNTDBL;    goto do_zerocnt;
5055c4fa725f59d51f73e08aa82b48bc63133ceb5579sewardj      case Iop_PwBitMtxXpose64x2: op = Pav_BITMTXXPOSE;  goto do_zerocnt;
50567deaf9552b546b847528cf39b38898fb7742b5f5carll      do_zerocnt:
50577deaf9552b546b847528cf39b38898fb7742b5f5carll      {
50581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll        HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
50597deaf9552b546b847528cf39b38898fb7742b5f5carll        HReg dst = newVRegV(env);
5060c4fa725f59d51f73e08aa82b48bc63133ceb5579sewardj        addInstr(env, PPCInstr_AvUnary(op, dst, arg));
50617deaf9552b546b847528cf39b38898fb7742b5f5carll        return dst;
50627deaf9552b546b847528cf39b38898fb7742b5f5carll      }
50637deaf9552b546b847528cf39b38898fb7742b5f5carll
5064f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      default:
5065f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion         break;
5066f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      } /* switch (e->Iex.Unop.op) */
5067f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   } /* if (e->tag == Iex_Unop) */
5068f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
5069f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   if (e->tag == Iex_Binop) {
5070f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      switch (e->Iex.Binop.op) {
5071f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
5072f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      case Iop_64HLtoV128: {
5073f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         if (!mode64) {
507488a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     r3, r2, r1, r0, r_aligned16;
50755b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            PPCAMode *am_off0, *am_off4, *am_off8, *am_off12;
507688a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     dst = newVRegV(env);
5077f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* do this via the stack (easy, convenient, etc) */
5078f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            sub_from_sp( env, 32 );        // Move SP down
5079f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5080f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            // get a quadword aligned address within our stack space
5081f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            r_aligned16 = get_sp_aligned16( env );
50825b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off0  = PPCAMode_IR( 0,  r_aligned16 );
50835b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off4  = PPCAMode_IR( 4,  r_aligned16 );
50845b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off8  = PPCAMode_IR( 8,  r_aligned16 );
50855b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off12 = PPCAMode_IR( 12, r_aligned16 );
5086f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5087f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* Do the less significant 64 bits */
50881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&r1, &r0, env, e->Iex.Binop.arg2, IEndianess);
50895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off12, r0, mode64 ));
50905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off8,  r1, mode64 ));
5091f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* Do the more significant 64 bits */
50921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&r3, &r2, env, e->Iex.Binop.arg1, IEndianess);
50935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off4, r2, mode64 ));
50945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off0, r3, mode64 ));
5095f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5096f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* Fetch result back from stack. */
50975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AvLdSt(True/*ld*/, 16, dst, am_off0));
5098f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5099f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            add_to_sp( env, 32 );          // Reset SP
5100f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            return dst;
5101f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         } else {
51021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     rHi = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
51031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     rLo = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
510488a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     dst = newVRegV(env);
510588a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     r_aligned16;
510688a9908b9b2a58daee177e33f90e59f4f9627259cerion            PPCAMode *am_off0, *am_off8;
510788a9908b9b2a58daee177e33f90e59f4f9627259cerion            /* do this via the stack (easy, convenient, etc) */
510888a9908b9b2a58daee177e33f90e59f4f9627259cerion            sub_from_sp( env, 32 );        // Move SP down
510988a9908b9b2a58daee177e33f90e59f4f9627259cerion
511088a9908b9b2a58daee177e33f90e59f4f9627259cerion            // get a quadword aligned address within our stack space
511188a9908b9b2a58daee177e33f90e59f4f9627259cerion            r_aligned16 = get_sp_aligned16( env );
511288a9908b9b2a58daee177e33f90e59f4f9627259cerion            am_off0  = PPCAMode_IR( 0,  r_aligned16 );
511388a9908b9b2a58daee177e33f90e59f4f9627259cerion            am_off8  = PPCAMode_IR( 8,  r_aligned16 );
511488a9908b9b2a58daee177e33f90e59f4f9627259cerion
511588a9908b9b2a58daee177e33f90e59f4f9627259cerion            /* Store 2*I64 to stack */
51161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            if (IEndianess == Iend_LE) {
51171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off0, rLo, mode64 ));
51181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off8, rHi, mode64 ));
51191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            } else {
51201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off0, rHi, mode64 ));
51211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off8, rLo, mode64 ));
51221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            }
512388a9908b9b2a58daee177e33f90e59f4f9627259cerion            /* Fetch result back from stack. */
512488a9908b9b2a58daee177e33f90e59f4f9627259cerion            addInstr(env, PPCInstr_AvLdSt(True/*ld*/, 16, dst, am_off0));
512588a9908b9b2a58daee177e33f90e59f4f9627259cerion
512688a9908b9b2a58daee177e33f90e59f4f9627259cerion            add_to_sp( env, 32 );          // Reset SP
512788a9908b9b2a58daee177e33f90e59f4f9627259cerion            return dst;
5128f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
5129f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      }
5130f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
5131e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_Max32Fx4:   fpop = Pavfp_MAXF;   goto do_32Fx4;
5132e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_Min32Fx4:   fpop = Pavfp_MINF;   goto do_32Fx4;
5133e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_CmpEQ32Fx4: fpop = Pavfp_CMPEQF; goto do_32Fx4;
5134e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_CmpGT32Fx4: fpop = Pavfp_CMPGTF; goto do_32Fx4;
5135e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_CmpGE32Fx4: fpop = Pavfp_CMPGEF; goto do_32Fx4;
51368ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      do_32Fx4:
51378ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      {
51381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argL = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
51391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argR = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
51408ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg dst = newVRegV(env);
5141e522d4bbf9e59873859c2f0693450a176fb2b996sewardj         addInstr(env, PPCInstr_AvBin32Fx4(fpop, dst, argL, argR));
51428ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         return dst;
51438ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      }
51448ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
51458ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      case Iop_CmpLE32Fx4: {
51461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argL = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
51471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argR = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
51488ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg dst = newVRegV(env);
51498ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
51508ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         /* stay consistent with native ppc compares:
51518ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion            if a left/right lane holds a nan, return zeros for that lane
51528ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion            so: le == NOT(gt OR isNan)
51538ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion          */
51548ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg isNanLR = newVRegV(env);
51551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg isNanL = isNan(env, argL, IEndianess);
51561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg isNanR = isNan(env, argR, IEndianess);
51575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_OR, isNanLR,
51585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                         isNanL, isNanR));
51598ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
51605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32Fx4(Pavfp_CMPGTF, dst,
51615b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           argL, argR));
51625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_OR, dst, dst, isNanLR));
51635b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
51648ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         return dst;
51658ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      }
516636991efdccc3af11ee9691dfa5297872dfb88312cerion
5167225a034683024109da729a4d2f080364b9485007cerion      case Iop_AndV128:    op = Pav_AND;      goto do_AvBin;
5168225a034683024109da729a4d2f080364b9485007cerion      case Iop_OrV128:     op = Pav_OR;       goto do_AvBin;
5169225a034683024109da729a4d2f080364b9485007cerion      case Iop_XorV128:    op = Pav_XOR;      goto do_AvBin;
517036991efdccc3af11ee9691dfa5297872dfb88312cerion      do_AvBin: {
51711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
51721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
517336991efdccc3af11ee9691dfa5297872dfb88312cerion         HReg dst  = newVRegV(env);
51745b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(op, dst, arg1, arg2));
517536991efdccc3af11ee9691dfa5297872dfb88312cerion         return dst;
517636991efdccc3af11ee9691dfa5297872dfb88312cerion      }
517736991efdccc3af11ee9691dfa5297872dfb88312cerion
51780a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shl8x16:    op = Pav_SHL;    goto do_AvBin8x16;
51790a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shr8x16:    op = Pav_SHR;    goto do_AvBin8x16;
51800a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Sar8x16:    op = Pav_SAR;    goto do_AvBin8x16;
51811bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_Rol8x16:    op = Pav_ROTL;   goto do_AvBin8x16;
518292d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_InterleaveHI8x16: op = Pav_MRGHI;  goto do_AvBin8x16;
518392d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_InterleaveLO8x16: op = Pav_MRGLO;  goto do_AvBin8x16;
5184f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Add8x16:    op = Pav_ADDU;   goto do_AvBin8x16;
5185f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd8Ux16:  op = Pav_QADDU;  goto do_AvBin8x16;
5186f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd8Sx16:  op = Pav_QADDS;  goto do_AvBin8x16;
5187f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Sub8x16:    op = Pav_SUBU;   goto do_AvBin8x16;
5188f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub8Ux16:  op = Pav_QSUBU;  goto do_AvBin8x16;
5189f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub8Sx16:  op = Pav_QSUBS;  goto do_AvBin8x16;
519036991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg8Ux16:   op = Pav_AVGU;   goto do_AvBin8x16;
519136991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg8Sx16:   op = Pav_AVGS;   goto do_AvBin8x16;
519236991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max8Ux16:   op = Pav_MAXU;   goto do_AvBin8x16;
519336991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max8Sx16:   op = Pav_MAXS;   goto do_AvBin8x16;
519436991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min8Ux16:   op = Pav_MINU;   goto do_AvBin8x16;
519536991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min8Sx16:   op = Pav_MINS;   goto do_AvBin8x16;
519624d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven8Ux16: op = Pav_OMULU;  goto do_AvBin8x16;
519724d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven8Sx16: op = Pav_OMULS;  goto do_AvBin8x16;
51980c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpEQ8x16:  op = Pav_CMPEQU; goto do_AvBin8x16;
51990c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT8Ux16: op = Pav_CMPGTU; goto do_AvBin8x16;
52000c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT8Sx16: op = Pav_CMPGTS; goto do_AvBin8x16;
52017deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd8x16: op = Pav_POLYMULADD; goto do_AvBin8x16;
520236991efdccc3af11ee9691dfa5297872dfb88312cerion      do_AvBin8x16: {
52031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
52041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
520527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         HReg dst  = newVRegV(env);
52065b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin8x16(op, dst, arg1, arg2));
520736991efdccc3af11ee9691dfa5297872dfb88312cerion         return dst;
520836991efdccc3af11ee9691dfa5297872dfb88312cerion      }
520936991efdccc3af11ee9691dfa5297872dfb88312cerion
52100a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shl16x8:    op = Pav_SHL;    goto do_AvBin16x8;
52110a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shr16x8:    op = Pav_SHR;    goto do_AvBin16x8;
52120a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Sar16x8:    op = Pav_SAR;    goto do_AvBin16x8;
52131bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_Rol16x8:    op = Pav_ROTL;   goto do_AvBin16x8;
52145f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_NarrowBin16to8x16:    op = Pav_PACKUU;  goto do_AvBin16x8;
52155f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin16Uto8Ux16: op = Pav_QPACKUU; goto do_AvBin16x8;
52165f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin16Sto8Sx16: op = Pav_QPACKSS; goto do_AvBin16x8;
5217c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveHI16x8:  op = Pav_MRGHI;  goto do_AvBin16x8;
5218c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveLO16x8:  op = Pav_MRGLO;  goto do_AvBin16x8;
5219f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Add16x8:    op = Pav_ADDU;   goto do_AvBin16x8;
5220f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd16Ux8:  op = Pav_QADDU;  goto do_AvBin16x8;
5221f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd16Sx8:  op = Pav_QADDS;  goto do_AvBin16x8;
5222f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Sub16x8:    op = Pav_SUBU;   goto do_AvBin16x8;
5223f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub16Ux8:  op = Pav_QSUBU;  goto do_AvBin16x8;
5224f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub16Sx8:  op = Pav_QSUBS;  goto do_AvBin16x8;
522536991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg16Ux8:   op = Pav_AVGU;   goto do_AvBin16x8;
522636991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg16Sx8:   op = Pav_AVGS;   goto do_AvBin16x8;
522736991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max16Ux8:   op = Pav_MAXU;   goto do_AvBin16x8;
522836991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max16Sx8:   op = Pav_MAXS;   goto do_AvBin16x8;
522936991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min16Ux8:   op = Pav_MINU;   goto do_AvBin16x8;
523036991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min16Sx8:   op = Pav_MINS;   goto do_AvBin16x8;
523124d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven16Ux8: op = Pav_OMULU;  goto do_AvBin16x8;
523224d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven16Sx8: op = Pav_OMULS;  goto do_AvBin16x8;
52330c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpEQ16x8:  op = Pav_CMPEQU; goto do_AvBin16x8;
52340c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT16Ux8: op = Pav_CMPGTU; goto do_AvBin16x8;
52350c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT16Sx8: op = Pav_CMPGTS; goto do_AvBin16x8;
52367deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd16x8: op = Pav_POLYMULADD; goto do_AvBin16x8;
523736991efdccc3af11ee9691dfa5297872dfb88312cerion      do_AvBin16x8: {
52381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
52391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
524036991efdccc3af11ee9691dfa5297872dfb88312cerion         HReg dst  = newVRegV(env);
52415b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin16x8(op, dst, arg1, arg2));
5242225a034683024109da729a4d2f080364b9485007cerion         return dst;
5243225a034683024109da729a4d2f080364b9485007cerion      }
5244d3e52410a03147c36dbf977a37e77a4de246f7c9cerion
52450a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shl32x4:    op = Pav_SHL;    goto do_AvBin32x4;
52460a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shr32x4:    op = Pav_SHR;    goto do_AvBin32x4;
52470a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Sar32x4:    op = Pav_SAR;    goto do_AvBin32x4;
52481bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_Rol32x4:    op = Pav_ROTL;   goto do_AvBin32x4;
52495f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_NarrowBin32to16x8:    op = Pav_PACKUU;  goto do_AvBin32x4;
52505f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin32Uto16Ux8: op = Pav_QPACKUU; goto do_AvBin32x4;
52515f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin32Sto16Sx8: op = Pav_QPACKSS; goto do_AvBin32x4;
5252c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveHI32x4:  op = Pav_MRGHI;  goto do_AvBin32x4;
5253c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveLO32x4:  op = Pav_MRGLO;  goto do_AvBin32x4;
5254f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Add32x4:    op = Pav_ADDU;   goto do_AvBin32x4;
5255f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd32Ux4:  op = Pav_QADDU;  goto do_AvBin32x4;
5256f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd32Sx4:  op = Pav_QADDS;  goto do_AvBin32x4;
5257f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Sub32x4:    op = Pav_SUBU;   goto do_AvBin32x4;
5258f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub32Ux4:  op = Pav_QSUBU;  goto do_AvBin32x4;
5259f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub32Sx4:  op = Pav_QSUBS;  goto do_AvBin32x4;
526036991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg32Ux4:   op = Pav_AVGU;   goto do_AvBin32x4;
526136991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg32Sx4:   op = Pav_AVGS;   goto do_AvBin32x4;
526236991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max32Ux4:   op = Pav_MAXU;   goto do_AvBin32x4;
526336991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max32Sx4:   op = Pav_MAXS;   goto do_AvBin32x4;
526436991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min32Ux4:   op = Pav_MINU;   goto do_AvBin32x4;
526536991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min32Sx4:   op = Pav_MINS;   goto do_AvBin32x4;
526648ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Mul32x4:    op = Pav_MULU;   goto do_AvBin32x4;
526748ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_MullEven32Ux4: op = Pav_OMULU;  goto do_AvBin32x4;
526848ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_MullEven32Sx4: op = Pav_OMULS;  goto do_AvBin32x4;
52690c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpEQ32x4:  op = Pav_CMPEQU; goto do_AvBin32x4;
52700c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT32Ux4: op = Pav_CMPGTU; goto do_AvBin32x4;
52710c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT32Sx4: op = Pav_CMPGTS; goto do_AvBin32x4;
527248ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CatOddLanes32x4:  op = Pav_CATODD;  goto do_AvBin32x4;
527348ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CatEvenLanes32x4: op = Pav_CATEVEN; goto do_AvBin32x4;
52747deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd32x4: op = Pav_POLYMULADD; goto do_AvBin32x4;
5275d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      do_AvBin32x4: {
52761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
52771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
5278d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         HReg dst  = newVRegV(env);
52795b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32x4(op, dst, arg1, arg2));
5280d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         return dst;
5281d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      }
5282d3e52410a03147c36dbf977a37e77a4de246f7c9cerion
528348ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Shl64x2:    op = Pav_SHL;    goto do_AvBin64x2;
528448ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Shr64x2:    op = Pav_SHR;    goto do_AvBin64x2;
528548ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Sar64x2:    op = Pav_SAR;    goto do_AvBin64x2;
528648ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Rol64x2:    op = Pav_ROTL;   goto do_AvBin64x2;
52870c74bb5aa3240f693df0568d578baabf0c376dc4carll      case Iop_NarrowBin64to32x4:    op = Pav_PACKUU;  goto do_AvBin64x2;
528848ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_QNarrowBin64Sto32Sx4: op = Pav_QPACKSS; goto do_AvBin64x2;
528948ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_QNarrowBin64Uto32Ux4: op = Pav_QPACKUU; goto do_AvBin64x2;
529048ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_InterleaveHI64x2:  op = Pav_MRGHI;  goto do_AvBin64x2;
529148ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_InterleaveLO64x2:  op = Pav_MRGLO;  goto do_AvBin64x2;
52920c74bb5aa3240f693df0568d578baabf0c376dc4carll      case Iop_Add64x2:    op = Pav_ADDU;   goto do_AvBin64x2;
529348ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Sub64x2:    op = Pav_SUBU;   goto do_AvBin64x2;
529448ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Max64Ux2:   op = Pav_MAXU;   goto do_AvBin64x2;
529548ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Max64Sx2:   op = Pav_MAXS;   goto do_AvBin64x2;
529648ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Min64Ux2:   op = Pav_MINU;   goto do_AvBin64x2;
529748ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Min64Sx2:   op = Pav_MINS;   goto do_AvBin64x2;
529848ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CmpEQ64x2:  op = Pav_CMPEQU; goto do_AvBin64x2;
529948ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CmpGT64Ux2: op = Pav_CMPGTU; goto do_AvBin64x2;
530048ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CmpGT64Sx2: op = Pav_CMPGTS; goto do_AvBin64x2;
53017deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd64x2: op = Pav_POLYMULADD; goto do_AvBin64x2;
53020c74bb5aa3240f693df0568d578baabf0c376dc4carll      do_AvBin64x2: {
53031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
53050c74bb5aa3240f693df0568d578baabf0c376dc4carll         HReg dst  = newVRegV(env);
53060c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvBin64x2(op, dst, arg1, arg2));
53070c74bb5aa3240f693df0568d578baabf0c376dc4carll         return dst;
53080c74bb5aa3240f693df0568d578baabf0c376dc4carll      }
53090c74bb5aa3240f693df0568d578baabf0c376dc4carll
531092d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_ShlN8x16: op = Pav_SHL; goto do_AvShift8x16;
531192d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_SarN8x16: op = Pav_SAR; goto do_AvShift8x16;
531292d9d876af80d14fa2f319f7109964f2d6231f15cerion      do_AvShift8x16: {
53131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
531492d9d876af80d14fa2f319f7109964f2d6231f15cerion         HReg dst    = newVRegV(env);
53151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
53165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin8x16(op, dst, r_src, v_shft));
531792d9d876af80d14fa2f319f7109964f2d6231f15cerion         return dst;
531892d9d876af80d14fa2f319f7109964f2d6231f15cerion      }
531992d9d876af80d14fa2f319f7109964f2d6231f15cerion
53203c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_ShlN16x8: op = Pav_SHL; goto do_AvShift16x8;
53213c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_ShrN16x8: op = Pav_SHR; goto do_AvShift16x8;
53223c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_SarN16x8: op = Pav_SAR; goto do_AvShift16x8;
53233c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      do_AvShift16x8: {
53241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53253c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion         HReg dst    = newVRegV(env);
53261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
53275b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin16x8(op, dst, r_src, v_shft));
53283c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion         return dst;
53293c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      }
53303c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion
53313c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_ShlN32x4: op = Pav_SHL; goto do_AvShift32x4;
5332d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      case Iop_ShrN32x4: op = Pav_SHR; goto do_AvShift32x4;
53333c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_SarN32x4: op = Pav_SAR; goto do_AvShift32x4;
5334d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      do_AvShift32x4: {
53351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
5336d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         HReg dst    = newVRegV(env);
53371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
53385b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32x4(op, dst, r_src, v_shft));
5339d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         return dst;
5340d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      }
5341d3e52410a03147c36dbf977a37e77a4de246f7c9cerion
534248ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_ShlN64x2: op = Pav_SHL; goto do_AvShift64x2;
534348ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_ShrN64x2: op = Pav_SHR; goto do_AvShift64x2;
534448ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_SarN64x2: op = Pav_SAR; goto do_AvShift64x2;
534548ae46b56cef87c90638b25d6b2462c475033da8carll      do_AvShift64x2: {
53461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
534748ae46b56cef87c90638b25d6b2462c475033da8carll         HReg dst    = newVRegV(env);
53481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
534948ae46b56cef87c90638b25d6b2462c475033da8carll         addInstr(env, PPCInstr_AvBin64x2(op, dst, r_src, v_shft));
535048ae46b56cef87c90638b25d6b2462c475033da8carll         return dst;
535148ae46b56cef87c90638b25d6b2462c475033da8carll      }
535248ae46b56cef87c90638b25d6b2462c475033da8carll
535327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      case Iop_ShrV128: op = Pav_SHR; goto do_AvShiftV128;
535492d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_ShlV128: op = Pav_SHL; goto do_AvShiftV128;
535527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      do_AvShiftV128: {
535627b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         HReg dst    = newVRegV(env);
53571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
535992d9d876af80d14fa2f319f7109964f2d6231f15cerion         /* Note: shift value gets masked by 127 */
53605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(op, dst, r_src, v_shft));
536127b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         return dst;
536227b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      }
536327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
5364dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj      case Iop_Perm8x16: {
536592d9d876af80d14fa2f319f7109964f2d6231f15cerion         HReg dst   = newVRegV(env);
53661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_ctl = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
53685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvPerm(dst, v_src, v_src, v_ctl));
536992d9d876af80d14fa2f319f7109964f2d6231f15cerion         return dst;
537092d9d876af80d14fa2f319f7109964f2d6231f15cerion      }
537192d9d876af80d14fa2f319f7109964f2d6231f15cerion
53727deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_CipherV128:  op = Pav_CIPHERV128;   goto do_AvCipherV128;
53737deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_CipherLV128: op = Pav_CIPHERLV128;  goto do_AvCipherV128;
53747deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_NCipherV128: op = Pav_NCIPHERV128;  goto do_AvCipherV128;
53757deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_NCipherLV128:op = Pav_NCIPHERLV128; goto do_AvCipherV128;
53767deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvCipherV128: {
53771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
53797deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst  = newVRegV(env);
53807deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvCipherV128Binary(op, dst, arg1, arg2));
53817deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
53827deaf9552b546b847528cf39b38898fb7742b5f5carll      }
53837deaf9552b546b847528cf39b38898fb7742b5f5carll
53847deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_SHA256:op = Pav_SHA256; goto do_AvHashV128;
53857deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_SHA512:op = Pav_SHA512; goto do_AvHashV128;
53867deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvHashV128: {
53871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53887deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst  = newVRegV(env);
53891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* s_field = iselWordExpr_RI(env, e->Iex.Binop.arg2, IEndianess);
53907deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvHashV128Binary(op, dst, arg1, s_field));
53917deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
53927deaf9552b546b847528cf39b38898fb7742b5f5carll      }
5393f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      default:
5394f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion         break;
5395f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      } /* switch (e->Iex.Binop.op) */
5396f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   } /* if (e->tag == Iex_Binop) */
5397f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
53987deaf9552b546b847528cf39b38898fb7742b5f5carll   if (e->tag == Iex_Triop) {
53997deaf9552b546b847528cf39b38898fb7742b5f5carll      IRTriop *triop = e->Iex.Triop.details;
54007deaf9552b546b847528cf39b38898fb7742b5f5carll      switch (triop->op) {
54017deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_BCDAdd:op = Pav_BCDAdd; goto do_AvBCDV128;
54027deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_BCDSub:op = Pav_BCDSub; goto do_AvBCDV128;
54037deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvBCDV128: {
54041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, triop->arg1, IEndianess);
54051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, triop->arg2, IEndianess);
54067deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst  = newVRegV(env);
54071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* ps = iselWordExpr_RI(env, triop->arg3, IEndianess);
54087deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvBCDV128Trinary(op, dst, arg1, arg2, ps));
54097deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
54107deaf9552b546b847528cf39b38898fb7742b5f5carll      }
54117deaf9552b546b847528cf39b38898fb7742b5f5carll
541220a760ec66a13a93147a40d3c3530be21d7fe411sewardj      case Iop_Add32Fx4: fpop = Pavfp_ADDF; goto do_32Fx4_with_rm;
541320a760ec66a13a93147a40d3c3530be21d7fe411sewardj      case Iop_Sub32Fx4: fpop = Pavfp_SUBF; goto do_32Fx4_with_rm;
541420a760ec66a13a93147a40d3c3530be21d7fe411sewardj      case Iop_Mul32Fx4: fpop = Pavfp_MULF; goto do_32Fx4_with_rm;
541520a760ec66a13a93147a40d3c3530be21d7fe411sewardj      do_32Fx4_with_rm:
541620a760ec66a13a93147a40d3c3530be21d7fe411sewardj      {
54171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argL = iselVecExpr(env, triop->arg2, IEndianess);
54181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argR = iselVecExpr(env, triop->arg3, IEndianess);
541920a760ec66a13a93147a40d3c3530be21d7fe411sewardj         HReg dst  = newVRegV(env);
542020a760ec66a13a93147a40d3c3530be21d7fe411sewardj         /* FIXME: this is bogus, in the sense that Altivec ignores
542120a760ec66a13a93147a40d3c3530be21d7fe411sewardj            FPSCR.RM, at least for some FP operations.  So setting the
542220a760ec66a13a93147a40d3c3530be21d7fe411sewardj            RM is pointless.  This is only really correct in the case
542320a760ec66a13a93147a40d3c3530be21d7fe411sewardj            where the RM is known, at JIT time, to be Irrm_NEAREST,
542420a760ec66a13a93147a40d3c3530be21d7fe411sewardj            since -- at least for Altivec FP add/sub/mul -- the
542520a760ec66a13a93147a40d3c3530be21d7fe411sewardj            emitted insn is hardwired to round to nearest. */
54261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode(env, triop->arg1, IEndianess);
542720a760ec66a13a93147a40d3c3530be21d7fe411sewardj         addInstr(env, PPCInstr_AvBin32Fx4(fpop, dst, argL, argR));
542820a760ec66a13a93147a40d3c3530be21d7fe411sewardj         return dst;
542920a760ec66a13a93147a40d3c3530be21d7fe411sewardj      }
543020a760ec66a13a93147a40d3c3530be21d7fe411sewardj
54317deaf9552b546b847528cf39b38898fb7742b5f5carll      default:
54327deaf9552b546b847528cf39b38898fb7742b5f5carll         break;
54337deaf9552b546b847528cf39b38898fb7742b5f5carll      } /* switch (e->Iex.Triop.op) */
54347deaf9552b546b847528cf39b38898fb7742b5f5carll   } /* if (e->tag == Iex_Trinop) */
54357deaf9552b546b847528cf39b38898fb7742b5f5carll
54367deaf9552b546b847528cf39b38898fb7742b5f5carll
5437cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   if (e->tag == Iex_Const ) {
5438cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion      vassert(e->Iex.Const.con->tag == Ico_V128);
5439cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion      if (e->Iex.Const.con->Ico.V128 == 0x0000) {
5440cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion         return generate_zeroes_V128(env);
5441d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj      }
5442d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj      else if (e->Iex.Const.con->Ico.V128 == 0xffff) {
5443d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj         return generate_ones_V128(env);
5444cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion      }
5445cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   }
5446cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion
54475b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselVecExpr(ppc) (subarch = %s): can't reduce\n",
54485117ce116f47141cb23d1b49cc826e19323add97sewardj              LibVEX_ppVexHwCaps(mode64 ? VexArchPPC64 : VexArchPPC32,
54495117ce116f47141cb23d1b49cc826e19323add97sewardj                                 env->hwcaps));
5450e21595a704c11ce19b8cd73df03fdcbe483517eecerion   ppIRExpr(e);
54515b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselVecExpr_wrk(ppc)");
5452e21595a704c11ce19b8cd73df03fdcbe483517eecerion}
5453bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
5454bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
5455bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
5456bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- ISEL: Statements                                  ---*/
5457bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
5458bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
54591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void iselStmt ( ISelEnv* env, IRStmt* stmt, IREndness IEndianess )
5460bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion{
54614628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
5462bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   if (vex_traceflags & VEX_TRACE_VCODE) {
54632c49e036c365df707cd8e6622d66382f380557b2cerion      vex_printf("\n -- ");
5464bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      ppIRStmt(stmt);
5465bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      vex_printf("\n");
5466bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
5467a50fde5504e829e5154113d7e507f12707089f48cerion
5468bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   switch (stmt->tag) {
5469bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
54702c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- STORE --------- */
5471af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj   case Ist_Store: {
5472e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRType    tya   = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
5473e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRType    tyd   = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
5474e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IREndness end   = stmt->Ist.Store.end;
5475af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj
54761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      if (end != IEndianess)
5477e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         goto stmt_fail;
5478e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      if (!mode64 && (tya != Ity_I32))
5479e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         goto stmt_fail;
5480e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      if (mode64 && (tya != Ity_I64))
5481af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         goto stmt_fail;
5482ed623dbefb52ca3211490d656abc999a129df060cerion
5483f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (tyd == Ity_I8 || tyd == Ity_I16 || tyd == Ity_I32 ||
5484f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          (mode64 && (tyd == Ity_I64))) {
5485e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
54861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
54871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
54881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, stmt->Ist.Store.data, IEndianess);
54895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( toUChar(sizeofIRType(tyd)),
5490e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       am_addr, r_src, mode64 ));
54912c49e036c365df707cd8e6622d66382f380557b2cerion         return;
54922c49e036c365df707cd8e6622d66382f380557b2cerion      }
5493094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (tyd == Ity_F64) {
5494e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
54951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
54961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
54971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, stmt->Ist.Store.data, IEndianess);
54985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
54995b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_FpLdSt(False/*store*/, 8, fr_src, am_addr));
5500094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5501094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
5502094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (tyd == Ity_F32) {
5503e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
55041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselFltExpr(env, stmt->Ist.Store.data, IEndianess);
55075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_FpLdSt(False/*store*/, 4, fr_src, am_addr));
5509094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5510094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
5511f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (tyd == Ity_D64) {
5512f704eb2bab3d06d983c850b0bcf243e178060f75carll         PPCAMode* am_addr
55131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, stmt->Ist.Store.data, IEndianess);
5516f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env,
5517f704eb2bab3d06d983c850b0bcf243e178060f75carll                  PPCInstr_FpLdSt(False/*store*/, 8, fr_src, am_addr));
5518f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5519f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
5520f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (tyd == Ity_D32) {
5521f704eb2bab3d06d983c850b0bcf243e178060f75carll         PPCAMode* am_addr
55221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr(env, stmt->Ist.Store.data, IEndianess);
5525f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env,
5526f704eb2bab3d06d983c850b0bcf243e178060f75carll                  PPCInstr_FpLdSt(False/*store*/, 4, fr_src, am_addr));
5527f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5528f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
5529e21595a704c11ce19b8cd73df03fdcbe483517eecerion      if (tyd == Ity_V128) {
5530e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
55311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, stmt->Ist.Store.data, IEndianess);
55345b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55355b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt(False/*store*/, 16, v_src, am_addr));
5536e21595a704c11ce19b8cd73df03fdcbe483517eecerion         return;
5537e21595a704c11ce19b8cd73df03fdcbe483517eecerion      }
5538e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      if (tyd == Ity_I64 && !mode64) {
5539e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         /* Just calculate the address in the register.  Life is too
5540e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj            short to arse around trying and possibly failing to adjust
5541e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj            the offset in a 'reg+offset' style amode. */
5542e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         HReg rHi32, rLo32;
55431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_addr = iselWordExpr_R(env, stmt->Ist.Store.addr, IEndianess);
55441f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr( &rHi32, &rLo32, env, stmt->Ist.Store.data,
55451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess );
5546e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         addInstr(env, PPCInstr_Store( 4/*byte-store*/,
5547e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       PPCAMode_IR( 0, r_addr ),
5548e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       rHi32,
5549e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       False/*32-bit insn please*/) );
5550e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         addInstr(env, PPCInstr_Store( 4/*byte-store*/,
5551e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       PPCAMode_IR( 4, r_addr ),
5552e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       rLo32,
5553e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       False/*32-bit insn please*/) );
5554e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         return;
5555e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      }
55562c49e036c365df707cd8e6622d66382f380557b2cerion      break;
55572c49e036c365df707cd8e6622d66382f380557b2cerion   }
5558cd304497d9d869f9b24a002299d3953ee072229bcerion
5559cd304497d9d869f9b24a002299d3953ee072229bcerion   /* --------- PUT --------- */
5560cd304497d9d869f9b24a002299d3953ee072229bcerion   case Ist_Put: {
5561cd304497d9d869f9b24a002299d3953ee072229bcerion      IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);
5562f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (ty == Ity_I8  || ty == Ity_I16 ||
5563f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          ty == Ity_I32 || ((ty == Ity_I64) && mode64)) {
55641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, stmt->Ist.Put.data, IEndianess);
55655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
55665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                          GuestStatePtr(mode64) );
55675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( toUChar(sizeofIRType(ty)),
55685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                       am_addr, r_src, mode64 ));
5569cd304497d9d869f9b24a002299d3953ee072229bcerion         return;
5570cd304497d9d869f9b24a002299d3953ee072229bcerion      }
5571f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (!mode64 && ty == Ity_I64) {
557202d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion         HReg rHi, rLo;
55735b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr  = PPCAMode_IR( stmt->Ist.Put.offset,
55745b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           GuestStatePtr(mode64) );
55755b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr4 = advance4(env, am_addr);
55761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&rHi,&rLo, env, stmt->Ist.Put.data, IEndianess);
55775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_addr,  rHi, mode64 ));
55785b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_addr4, rLo, mode64 ));
557902d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion         return;
558002d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion     }
5581a50fde5504e829e5154113d7e507f12707089f48cerion     if (ty == Ity_V128) {
55825b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         /* Guest state vectors are 16byte aligned,
55835b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            so don't need to worry here */
55841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, stmt->Ist.Put.data, IEndianess);
55855b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr  = PPCAMode_IR( stmt->Ist.Put.offset,
55865b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           GuestStatePtr(mode64) );
55875b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55885b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt(False/*store*/, 16, v_src, am_addr));
5589a50fde5504e829e5154113d7e507f12707089f48cerion         return;
5590a50fde5504e829e5154113d7e507f12707089f48cerion      }
5591094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (ty == Ity_F64) {
55921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, stmt->Ist.Put.data, IEndianess);
55935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
55945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                          GuestStatePtr(mode64) );
55955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
55965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                        fr_src, am_addr ));
5597094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5598094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
5599f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (ty == Ity_D32) {
5600f704eb2bab3d06d983c850b0bcf243e178060f75carll         /* The 32-bit value is stored in a 64-bit register */
56011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr( env, stmt->Ist.Put.data, IEndianess );
5602f704eb2bab3d06d983c850b0bcf243e178060f75carll         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
5603f704eb2bab3d06d983c850b0bcf243e178060f75carll                                          GuestStatePtr(mode64) );
5604f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr( env, PPCInstr_FpLdSt( False/*store*/, 8,
5605f704eb2bab3d06d983c850b0bcf243e178060f75carll                                         fr_src, am_addr ) );
5606f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5607f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
5608c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (ty == Ity_D64) {
56091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr( env, stmt->Ist.Put.data, IEndianess );
5610c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
5611c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                          GuestStatePtr(mode64) );
5612c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_FpLdSt( False/*store*/, 8, fr_src, am_addr ) );
5613c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5614c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
5615cd304497d9d869f9b24a002299d3953ee072229bcerion      break;
5616cd304497d9d869f9b24a002299d3953ee072229bcerion   }
5617ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
56186e53088a92d40be75cc362986956ac149b3fa94bsewardj   /* --------- Indexed PUT --------- */
5619aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   case Ist_PutI: {
5620d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRPutI *puti = stmt->Ist.PutI.details;
5621d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
5622aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      PPCAMode* dst_am
5623aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         = genGuestArrayOffset(
5624d6f38b3f822f7d57adfc0da3410995d85d6a4597florian              env, puti->descr,
56251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll              puti->ix, puti->bias,
56261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll              IEndianess );
5627d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRType ty = typeOfIRExpr(env->type_env, puti->data);
5628aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      if (mode64 && ty == Ity_I64) {
56291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, puti->data, IEndianess);
5630aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         addInstr(env, PPCInstr_Store( toUChar(8),
5631aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                       dst_am, r_src, mode64 ));
5632aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         return;
5633aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      }
5634aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      if ((!mode64) && ty == Ity_I32) {
56351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, puti->data, IEndianess);
5636aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         addInstr(env, PPCInstr_Store( toUChar(4),
5637aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                       dst_am, r_src, mode64 ));
5638aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         return;
56396e53088a92d40be75cc362986956ac149b3fa94bsewardj      }
56406e53088a92d40be75cc362986956ac149b3fa94bsewardj      break;
5641aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   }
5642cd304497d9d869f9b24a002299d3953ee072229bcerion
5643cd304497d9d869f9b24a002299d3953ee072229bcerion   /* --------- TMP --------- */
5644dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   case Ist_WrTmp: {
5645dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      IRTemp tmp = stmt->Ist.WrTmp.tmp;
5646cd304497d9d869f9b24a002299d3953ee072229bcerion      IRType ty = typeOfIRTemp(env->type_env, tmp);
5647f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (ty == Ity_I8  || ty == Ity_I16 ||
5648f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          ty == Ity_I32 || ((ty == Ity_I64) && mode64)) {
5649a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = lookupIRTemp(env, tmp);
56501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, stmt->Ist.WrTmp.data, IEndianess);
5651a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         addInstr(env, mk_iMOVds_RR( r_dst, r_src ));
5652cd304497d9d869f9b24a002299d3953ee072229bcerion         return;
5653cd304497d9d869f9b24a002299d3953ee072229bcerion      }
5654f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (!mode64 && ty == Ity_I64) {
565584ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         HReg r_srcHi, r_srcLo, r_dstHi, r_dstLo;
5656c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
56571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&r_srcHi,&r_srcLo, env, stmt->Ist.WrTmp.data,
56581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                       IEndianess);
56592bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         lookupIRTempPair( &r_dstHi, &r_dstLo, env, tmp);
566084ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         addInstr(env, mk_iMOVds_RR(r_dstHi, r_srcHi) );
566184ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         addInstr(env, mk_iMOVds_RR(r_dstLo, r_srcLo) );
566284ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         return;
566384ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      }
5664bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      if (mode64 && ty == Ity_I128) {
5665bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg r_srcHi, r_srcLo, r_dstHi, r_dstLo;
56661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt128Expr(&r_srcHi,&r_srcLo, env, stmt->Ist.WrTmp.data,
56671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
56682bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         lookupIRTempPair( &r_dstHi, &r_dstLo, env, tmp);
5669bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         addInstr(env, mk_iMOVds_RR(r_dstHi, r_srcHi) );
5670bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         addInstr(env, mk_iMOVds_RR(r_dstLo, r_srcLo) );
5671bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return;
5672bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
5673c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (!mode64 && ty == Ity_I128) {
5674c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_srcHi, r_srcMedHi, r_srcMedLo, r_srcLo;
5675c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_dstHi, r_dstMedHi, r_dstMedLo, r_dstLo;
5676c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
5677c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         iselInt128Expr_to_32x4(&r_srcHi, &r_srcMedHi,
5678c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                &r_srcMedLo, &r_srcLo,
56791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                env, stmt->Ist.WrTmp.data, IEndianess);
5680c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
5681c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         lookupIRTempQuad( &r_dstHi, &r_dstMedHi, &r_dstMedLo,
5682c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                           &r_dstLo, env, tmp);
5683c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
5684c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstHi,    r_srcHi) );
5685c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstMedHi, r_srcMedHi) );
5686c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstMedLo, r_srcMedLo) );
5687c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstLo,    r_srcLo) );
5688c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5689c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
56909abfcbca0696407c4b781b9395298c5edffa33a0cerion      if (ty == Ity_I1) {
56911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cond = iselCondCode(env, stmt->Ist.WrTmp.data,
56921f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IEndianess);
5693a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = lookupIRTemp(env, tmp);
56945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Set(cond, r_dst));
56959abfcbca0696407c4b781b9395298c5edffa33a0cerion         return;
56969abfcbca0696407c4b781b9395298c5edffa33a0cerion      }
5697094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (ty == Ity_F64) {
5698094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg fr_dst = lookupIRTemp(env, tmp);
56991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, stmt->Ist.WrTmp.data, IEndianess);
57005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpUnary(Pfp_MOV, fr_dst, fr_src));
5701094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5702094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
57036587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      if (ty == Ity_F32) {
57046587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         HReg fr_dst = lookupIRTemp(env, tmp);
57051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselFltExpr(env, stmt->Ist.WrTmp.data, IEndianess);
57065b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpUnary(Pfp_MOV, fr_dst, fr_src));
57076587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         return;
57086587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      }
5709f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (ty == Ity_D32) {
5710f704eb2bab3d06d983c850b0bcf243e178060f75carll         HReg fr_dst = lookupIRTemp(env, tmp);
57111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr(env, stmt->Ist.WrTmp.data, IEndianess);
5712f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_MOV, fr_dst, fr_src));
5713f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5714f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
57156587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      if (ty == Ity_V128) {
57166587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         HReg v_dst = lookupIRTemp(env, tmp);
57171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, stmt->Ist.WrTmp.data, IEndianess);
57185b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_MOV, v_dst, v_src));
57196587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         return;
57206587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      }
5721c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (ty == Ity_D64) {
5722c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg fr_dst = lookupIRTemp( env, tmp );
57231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr( env, stmt->Ist.WrTmp.data, IEndianess );
5724c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Unary( Pfp_MOV, fr_dst, fr_src ) );
5725c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5726c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
5727c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (ty == Ity_D128) {
5728c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg fr_srcHi, fr_srcLo, fr_dstHi, fr_dstLo;
5729c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj	 //         lookupDfp128IRTempPair( &fr_dstHi, &fr_dstLo, env, tmp );
5730c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         lookupIRTempPair( &fr_dstHi, &fr_dstLo, env, tmp );
57311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &fr_srcHi, &fr_srcLo, env, stmt->Ist.WrTmp.data,
57321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                         IEndianess );
5733c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Unary( Pfp_MOV, fr_dstHi, fr_srcHi ) );
5734c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Unary( Pfp_MOV, fr_dstLo, fr_srcLo ) );
5735c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5736c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
5737cd304497d9d869f9b24a002299d3953ee072229bcerion      break;
5738cd304497d9d869f9b24a002299d3953ee072229bcerion   }
5739cd304497d9d869f9b24a002299d3953ee072229bcerion
5740e768e92e054cde495849a5c842a477d287677f78sewardj   /* --------- Load Linked or Store Conditional --------- */
5741e768e92e054cde495849a5c842a477d287677f78sewardj   case Ist_LLSC: {
5742e768e92e054cde495849a5c842a477d287677f78sewardj      IRTemp res    = stmt->Ist.LLSC.result;
5743e768e92e054cde495849a5c842a477d287677f78sewardj      IRType tyRes  = typeOfIRTemp(env->type_env, res);
5744e768e92e054cde495849a5c842a477d287677f78sewardj      IRType tyAddr = typeOfIRExpr(env->type_env, stmt->Ist.LLSC.addr);
5745e768e92e054cde495849a5c842a477d287677f78sewardj
57461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      if (stmt->Ist.LLSC.end != IEndianess)
5747e768e92e054cde495849a5c842a477d287677f78sewardj         goto stmt_fail;
5748e768e92e054cde495849a5c842a477d287677f78sewardj      if (!mode64 && (tyAddr != Ity_I32))
5749e768e92e054cde495849a5c842a477d287677f78sewardj         goto stmt_fail;
5750e768e92e054cde495849a5c842a477d287677f78sewardj      if (mode64 && (tyAddr != Ity_I64))
5751e768e92e054cde495849a5c842a477d287677f78sewardj         goto stmt_fail;
5752e768e92e054cde495849a5c842a477d287677f78sewardj
5753e768e92e054cde495849a5c842a477d287677f78sewardj      if (stmt->Ist.LLSC.storedata == NULL) {
5754e768e92e054cde495849a5c842a477d287677f78sewardj         /* LL */
57551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_addr = iselWordExpr_R( env, stmt->Ist.LLSC.addr, IEndianess );
5756e768e92e054cde495849a5c842a477d287677f78sewardj         HReg r_dst  = lookupIRTemp(env, res);
5757d826889bd512ded2fbbc4781c595ecf0513f46f6carll         if (tyRes == Ity_I8) {
5758d826889bd512ded2fbbc4781c595ecf0513f46f6carll            addInstr(env, PPCInstr_LoadL( 1, r_dst, r_addr, mode64 ));
5759d826889bd512ded2fbbc4781c595ecf0513f46f6carll            return;
5760d826889bd512ded2fbbc4781c595ecf0513f46f6carll         }
5761d826889bd512ded2fbbc4781c595ecf0513f46f6carll         if (tyRes == Ity_I16) {
5762d826889bd512ded2fbbc4781c595ecf0513f46f6carll            addInstr(env, PPCInstr_LoadL( 2, r_dst, r_addr, mode64 ));
5763d826889bd512ded2fbbc4781c595ecf0513f46f6carll            return;
5764d826889bd512ded2fbbc4781c595ecf0513f46f6carll         }
5765e768e92e054cde495849a5c842a477d287677f78sewardj         if (tyRes == Ity_I32) {
5766e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_LoadL( 4, r_dst, r_addr, mode64 ));
5767e768e92e054cde495849a5c842a477d287677f78sewardj            return;
5768e768e92e054cde495849a5c842a477d287677f78sewardj         }
5769e768e92e054cde495849a5c842a477d287677f78sewardj         if (tyRes == Ity_I64 && mode64) {
5770e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_LoadL( 8, r_dst, r_addr, mode64 ));
5771e768e92e054cde495849a5c842a477d287677f78sewardj            return;
5772e768e92e054cde495849a5c842a477d287677f78sewardj         }
5773e768e92e054cde495849a5c842a477d287677f78sewardj         /* fallthru */;
5774e768e92e054cde495849a5c842a477d287677f78sewardj      } else {
5775e768e92e054cde495849a5c842a477d287677f78sewardj         /* SC */
5776e768e92e054cde495849a5c842a477d287677f78sewardj         HReg   r_res  = lookupIRTemp(env, res); /* :: Ity_I1 */
57771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_a    = iselWordExpr_R(env, stmt->Ist.LLSC.addr, IEndianess);
57781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src  = iselWordExpr_R(env, stmt->Ist.LLSC.storedata,
57791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IEndianess);
5780e768e92e054cde495849a5c842a477d287677f78sewardj         HReg   r_tmp  = newVRegI(env);
5781e768e92e054cde495849a5c842a477d287677f78sewardj         IRType tyData = typeOfIRExpr(env->type_env,
5782e768e92e054cde495849a5c842a477d287677f78sewardj                                      stmt->Ist.LLSC.storedata);
5783e768e92e054cde495849a5c842a477d287677f78sewardj         vassert(tyRes == Ity_I1);
5784d826889bd512ded2fbbc4781c595ecf0513f46f6carll         if (tyData == Ity_I8 || tyData == Ity_I16 || tyData == Ity_I32 ||
5785d826889bd512ded2fbbc4781c595ecf0513f46f6carll            (tyData == Ity_I64 && mode64)) {
5786d826889bd512ded2fbbc4781c595ecf0513f46f6carll            int size = 0;
5787d826889bd512ded2fbbc4781c595ecf0513f46f6carll
5788d826889bd512ded2fbbc4781c595ecf0513f46f6carll            if (tyData == Ity_I64)
5789d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 8;
5790d826889bd512ded2fbbc4781c595ecf0513f46f6carll            else if (tyData == Ity_I32)
5791d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 4;
5792d826889bd512ded2fbbc4781c595ecf0513f46f6carll            else if (tyData == Ity_I16)
5793d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 2;
5794d826889bd512ded2fbbc4781c595ecf0513f46f6carll            else if (tyData == Ity_I8)
5795d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 1;
5796d826889bd512ded2fbbc4781c595ecf0513f46f6carll
5797d826889bd512ded2fbbc4781c595ecf0513f46f6carll            addInstr(env, PPCInstr_StoreC( size,
5798e768e92e054cde495849a5c842a477d287677f78sewardj                                           r_a, r_src, mode64 ));
5799e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_MfCR( r_tmp ));
5800e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_Shft(
5801e768e92e054cde495849a5c842a477d287677f78sewardj                             Pshft_SHR,
5802e768e92e054cde495849a5c842a477d287677f78sewardj                             env->mode64 ? False : True
5803e768e92e054cde495849a5c842a477d287677f78sewardj                                /*F:64-bit, T:32-bit shift*/,
5804e768e92e054cde495849a5c842a477d287677f78sewardj                             r_tmp, r_tmp,
5805e768e92e054cde495849a5c842a477d287677f78sewardj                             PPCRH_Imm(False/*unsigned*/, 29)));
5806e768e92e054cde495849a5c842a477d287677f78sewardj            /* Probably unnecessary, since the IR dest type is Ity_I1,
5807e768e92e054cde495849a5c842a477d287677f78sewardj               and so we are entitled to leave whatever junk we like
5808e768e92e054cde495849a5c842a477d287677f78sewardj               drifting round in the upper 31 or 63 bits of r_res.
5809e768e92e054cde495849a5c842a477d287677f78sewardj               However, for the sake of conservativeness .. */
5810e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_Alu(
5811e768e92e054cde495849a5c842a477d287677f78sewardj                             Palu_AND,
5812e768e92e054cde495849a5c842a477d287677f78sewardj                             r_res, r_tmp,
5813e768e92e054cde495849a5c842a477d287677f78sewardj                             PPCRH_Imm(False/*signed*/, 1)));
5814e768e92e054cde495849a5c842a477d287677f78sewardj            return;
5815e768e92e054cde495849a5c842a477d287677f78sewardj         }
5816e768e92e054cde495849a5c842a477d287677f78sewardj         /* fallthru */
5817e768e92e054cde495849a5c842a477d287677f78sewardj      }
5818e768e92e054cde495849a5c842a477d287677f78sewardj      goto stmt_fail;
5819e768e92e054cde495849a5c842a477d287677f78sewardj      /*NOTREACHED*/
5820e768e92e054cde495849a5c842a477d287677f78sewardj   }
5821e768e92e054cde495849a5c842a477d287677f78sewardj
5822ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- Call to DIRTY helper --------- */
5823ed623dbefb52ca3211490d656abc999a129df060cerion   case Ist_Dirty: {
5824ed623dbefb52ca3211490d656abc999a129df060cerion      IRDirty* d = stmt->Ist.Dirty.details;
5825ed623dbefb52ca3211490d656abc999a129df060cerion
5826cfe046e178666280b87da998b1b52ecda03ecd89sewardj      /* Figure out the return type, if any. */
5827cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRType retty = Ity_INVALID;
5828cfe046e178666280b87da998b1b52ecda03ecd89sewardj      if (d->tmp != IRTemp_INVALID)
5829cfe046e178666280b87da998b1b52ecda03ecd89sewardj         retty = typeOfIRTemp(env->type_env, d->tmp);
5830cfe046e178666280b87da998b1b52ecda03ecd89sewardj
58317842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj      /* Throw out any return types we don't know about.  The set of
58327842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         acceptable return types is the same in both 32- and 64-bit
58337842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         mode, so we don't need to inspect mode64 to make a
58347842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         decision. */
583574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      Bool retty_ok = False;
58367842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj      switch (retty) {
58377842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         case Ity_INVALID: /* function doesn't return anything */
58387842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         case Ity_V128:
58397842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         case Ity_I64: case Ity_I32: case Ity_I16: case Ity_I8:
58407842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj            retty_ok = True; break;
58417842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         default:
58427842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj            break;
5843cfe046e178666280b87da998b1b52ecda03ecd89sewardj      }
584474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      if (!retty_ok)
5845cfe046e178666280b87da998b1b52ecda03ecd89sewardj         break; /* will go to stmt_fail: */
5846cfe046e178666280b87da998b1b52ecda03ecd89sewardj
584774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      /* Marshal args, do the call, clear stack, set the return value
584874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         to 0x555..555 if this is a conditional call that returns a
584974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         value and the call is skipped. */
585074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      UInt   addToSp = 0;
585174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      RetLoc rloc    = mk_RetLoc_INVALID();
58521f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      doHelperCall( &addToSp, &rloc, env, d->guard, d->cee, retty, d->args,
58531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                    IEndianess );
585474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(is_sane_RetLoc(rloc));
5855ed623dbefb52ca3211490d656abc999a129df060cerion
5856ed623dbefb52ca3211490d656abc999a129df060cerion      /* Now figure out what to do with the returned value, if any. */
585774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      switch (retty) {
585874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_INVALID: {
585974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* No return value.  Nothing to do. */
586074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(d->tmp == IRTemp_INVALID);
586174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(rloc.pri == RLPri_None);
586274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(addToSp == 0);
586374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
586474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
586574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_I32: case Ity_I16: case Ity_I8: {
586674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* The returned value is in %r3.  Park it in the register
586774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               associated with tmp. */
586874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            HReg r_dst = lookupIRTemp(env, d->tmp);
586974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
587074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(rloc.pri == RLPri_Int);
587174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(addToSp == 0);
587274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
587374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
587474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_I64:
587574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            if (mode64) {
587674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               /* The returned value is in %r3.  Park it in the register
587774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  associated with tmp. */
587874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               HReg r_dst = lookupIRTemp(env, d->tmp);
587974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
588074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(rloc.pri == RLPri_Int);
588174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(addToSp == 0);
588274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            } else {
588374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               /* The returned value is in %r3:%r4.  Park it in the
588474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  register-pair associated with tmp. */
588574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               HReg r_dstHi = INVALID_HREG;
588674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               HReg r_dstLo = INVALID_HREG;
588774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               lookupIRTempPair( &r_dstHi, &r_dstLo, env, d->tmp);
588874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR(r_dstHi, hregPPC_GPR3(mode64)));
588974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR(r_dstLo, hregPPC_GPR4(mode64)));
589074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(rloc.pri == RLPri_2Int);
589174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(addToSp == 0);
589274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            }
589374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
589474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_V128: {
589574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* The returned value is on the stack, and *retloc tells
589674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               us where.  Fish it off the stack and then move the
589774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               stack pointer upwards to clear it, as directed by
589874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               doHelperCall. */
589974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(rloc.pri == RLPri_V128SpRel);
590074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(addToSp >= 16);
590174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            HReg      dst = lookupIRTemp(env, d->tmp);
590274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            PPCAMode* am  = PPCAMode_IR(rloc.spOff, StackFramePtr(mode64));
590374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, dst, am ));
590474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            add_to_sp(env, addToSp);
590574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
590674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
590774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         default:
590874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /*NOTREACHED*/
590974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(0);
5910ed623dbefb52ca3211490d656abc999a129df060cerion      }
5911ed623dbefb52ca3211490d656abc999a129df060cerion   }
5912cd304497d9d869f9b24a002299d3953ee072229bcerion
591392f5dc7ca4f50145028c4baebc783d196dfb67a2cerion   /* --------- MEM FENCE --------- */
5914c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj   case Ist_MBE:
5915c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      switch (stmt->Ist.MBE.event) {
5916c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj         case Imbe_Fence:
5917c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            addInstr(env, PPCInstr_MFence());
5918c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            return;
5919c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj         default:
5920c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            break;
5921c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      }
5922c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      break;
5923cd304497d9d869f9b24a002299d3953ee072229bcerion
5924ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- INSTR MARK --------- */
5925ed623dbefb52ca3211490d656abc999a129df060cerion   /* Doesn't generate any executable code ... */
5926ed623dbefb52ca3211490d656abc999a129df060cerion   case Ist_IMark:
5927ed623dbefb52ca3211490d656abc999a129df060cerion       return;
5928ed623dbefb52ca3211490d656abc999a129df060cerion
5929cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj   /* --------- ABI HINT --------- */
5930cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj   /* These have no meaning (denotation in the IR) and so we ignore
5931cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj      them ... if any actually made it this far. */
5932cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj   case Ist_AbiHint:
5933cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj       return;
5934cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj
5935ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- NO-OP --------- */
5936ed623dbefb52ca3211490d656abc999a129df060cerion   /* Fairly self-explanatory, wouldn't you say? */
5937ed623dbefb52ca3211490d656abc999a129df060cerion   case Ist_NoOp:
5938ed623dbefb52ca3211490d656abc999a129df060cerion       return;
5939ed623dbefb52ca3211490d656abc999a129df060cerion
5940b536af93912b69421440c27aa0533ad77d678f85cerion   /* --------- EXIT --------- */
5941b536af93912b69421440c27aa0533ad77d678f85cerion   case Ist_Exit: {
59423dee849ec7c38746749065e67dc53b75daa7617dsewardj      IRConst* dst = stmt->Ist.Exit.dst;
59433dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (!mode64 && dst->tag != Ico_U32)
59445b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         vpanic("iselStmt(ppc): Ist_Exit: dst is not a 32-bit value");
59453dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (mode64 && dst->tag != Ico_U64)
5946f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vpanic("iselStmt(ppc64): Ist_Exit: dst is not a 64-bit value");
59473dee849ec7c38746749065e67dc53b75daa7617dsewardj
59481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCCondCode cc    = iselCondCode(env, stmt->Ist.Exit.guard, IEndianess);
59493dee849ec7c38746749065e67dc53b75daa7617dsewardj      PPCAMode*   amCIA = PPCAMode_IR(stmt->Ist.Exit.offsIP,
59503dee849ec7c38746749065e67dc53b75daa7617dsewardj                                      hregPPC_GPR31(mode64));
59513dee849ec7c38746749065e67dc53b75daa7617dsewardj
59523dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Case: boring transfer to known address */
59533dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (stmt->Ist.Exit.jk == Ijk_Boring
59543dee849ec7c38746749065e67dc53b75daa7617dsewardj          || stmt->Ist.Exit.jk == Ijk_Call
59553dee849ec7c38746749065e67dc53b75daa7617dsewardj          /* || stmt->Ist.Exit.jk == Ijk_Ret */) {
59563dee849ec7c38746749065e67dc53b75daa7617dsewardj         if (env->chainingAllowed) {
59573dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. almost always true .. */
59583dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* Skip the event check at the dst if this is a forwards
59593dee849ec7c38746749065e67dc53b75daa7617dsewardj               edge. */
59603dee849ec7c38746749065e67dc53b75daa7617dsewardj            Bool toFastEP
59613dee849ec7c38746749065e67dc53b75daa7617dsewardj               = mode64
59623dee849ec7c38746749065e67dc53b75daa7617dsewardj               ? (((Addr64)stmt->Ist.Exit.dst->Ico.U64) > (Addr64)env->max_ga)
59633dee849ec7c38746749065e67dc53b75daa7617dsewardj               : (((Addr32)stmt->Ist.Exit.dst->Ico.U32) > (Addr32)env->max_ga);
59643dee849ec7c38746749065e67dc53b75daa7617dsewardj            if (0) vex_printf("%s", toFastEP ? "Y" : ",");
59653dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XDirect(
59663dee849ec7c38746749065e67dc53b75daa7617dsewardj                             mode64 ? (Addr64)stmt->Ist.Exit.dst->Ico.U64
59673dee849ec7c38746749065e67dc53b75daa7617dsewardj                                    : (Addr64)stmt->Ist.Exit.dst->Ico.U32,
59683dee849ec7c38746749065e67dc53b75daa7617dsewardj                             amCIA, cc, toFastEP));
59693dee849ec7c38746749065e67dc53b75daa7617dsewardj         } else {
59703dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. very occasionally .. */
59713dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* We can't use chaining, so ask for an assisted transfer,
59723dee849ec7c38746749065e67dc53b75daa7617dsewardj               as that's the only alternative that is allowable. */
59731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r = iselWordExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst),
59741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IEndianess);
59753dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, cc, Ijk_Boring));
59763dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
59773dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
59783dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
59793dee849ec7c38746749065e67dc53b75daa7617dsewardj
59803dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Case: assisted transfer to arbitrary address */
59813dee849ec7c38746749065e67dc53b75daa7617dsewardj      switch (stmt->Ist.Exit.jk) {
59822f6902b260141dc063d131b3ec79af6f292a4a31sewardj         /* Keep this list in sync with that in iselNext below */
59832f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_ClientReq:
5984f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj         case Ijk_EmFail:
59852f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_EmWarn:
59862f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_NoDecode:
59872f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_NoRedir:
59882f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_SigBUS:
59892f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_SigTRAP:
59902f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_Sys_syscall:
599105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         case Ijk_InvalICache:
59923dee849ec7c38746749065e67dc53b75daa7617dsewardj         {
59931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r = iselWordExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst),
59941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IEndianess);
59953dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, cc,
59963dee849ec7c38746749065e67dc53b75daa7617dsewardj                                             stmt->Ist.Exit.jk));
59973dee849ec7c38746749065e67dc53b75daa7617dsewardj            return;
59983dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
59993dee849ec7c38746749065e67dc53b75daa7617dsewardj         default:
60003dee849ec7c38746749065e67dc53b75daa7617dsewardj            break;
60013dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
60023dee849ec7c38746749065e67dc53b75daa7617dsewardj
60033dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Do we ever expect to see any other kind? */
60043dee849ec7c38746749065e67dc53b75daa7617dsewardj      goto stmt_fail;
6005b536af93912b69421440c27aa0533ad77d678f85cerion   }
6006bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6007bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   default: break;
6008bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
6009af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj  stmt_fail:
6010bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   ppIRStmt(stmt);
60115b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselStmt(ppc)");
6012bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
6013bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6014bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6015bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6016bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- ISEL: Basic block terminators (Nexts)             ---*/
6017bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6018bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
60193dee849ec7c38746749065e67dc53b75daa7617dsewardjstatic void iselNext ( ISelEnv* env,
60201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                       IRExpr* next, IRJumpKind jk, Int offsIP,
60211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                       IREndness IEndianess)
60222c49e036c365df707cd8e6622d66382f380557b2cerion{
60232c49e036c365df707cd8e6622d66382f380557b2cerion   if (vex_traceflags & VEX_TRACE_VCODE) {
60243dee849ec7c38746749065e67dc53b75daa7617dsewardj      vex_printf( "\n-- PUT(%d) = ", offsIP);
60253dee849ec7c38746749065e67dc53b75daa7617dsewardj      ppIRExpr( next );
60263dee849ec7c38746749065e67dc53b75daa7617dsewardj      vex_printf( "; exit-");
60272c49e036c365df707cd8e6622d66382f380557b2cerion      ppIRJumpKind(jk);
60283dee849ec7c38746749065e67dc53b75daa7617dsewardj      vex_printf( "\n");
60293dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
60303dee849ec7c38746749065e67dc53b75daa7617dsewardj
60313dee849ec7c38746749065e67dc53b75daa7617dsewardj   PPCCondCode always = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
60323dee849ec7c38746749065e67dc53b75daa7617dsewardj
60333dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* Case: boring transfer to known address */
60343dee849ec7c38746749065e67dc53b75daa7617dsewardj   if (next->tag == Iex_Const) {
60353dee849ec7c38746749065e67dc53b75daa7617dsewardj      IRConst* cdst = next->Iex.Const.con;
60363dee849ec7c38746749065e67dc53b75daa7617dsewardj      vassert(cdst->tag == (env->mode64 ? Ico_U64 :Ico_U32));
60373dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (jk == Ijk_Boring || jk == Ijk_Call) {
60383dee849ec7c38746749065e67dc53b75daa7617dsewardj         /* Boring transfer to known address */
60393dee849ec7c38746749065e67dc53b75daa7617dsewardj         PPCAMode* amCIA = PPCAMode_IR(offsIP, hregPPC_GPR31(env->mode64));
60403dee849ec7c38746749065e67dc53b75daa7617dsewardj         if (env->chainingAllowed) {
60413dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. almost always true .. */
60423dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* Skip the event check at the dst if this is a forwards
60433dee849ec7c38746749065e67dc53b75daa7617dsewardj               edge. */
60443dee849ec7c38746749065e67dc53b75daa7617dsewardj            Bool toFastEP
60453dee849ec7c38746749065e67dc53b75daa7617dsewardj               = env->mode64
60463dee849ec7c38746749065e67dc53b75daa7617dsewardj               ? (((Addr64)cdst->Ico.U64) > (Addr64)env->max_ga)
60473dee849ec7c38746749065e67dc53b75daa7617dsewardj               : (((Addr32)cdst->Ico.U32) > (Addr32)env->max_ga);
60483dee849ec7c38746749065e67dc53b75daa7617dsewardj            if (0) vex_printf("%s", toFastEP ? "X" : ".");
60493dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XDirect(
60503dee849ec7c38746749065e67dc53b75daa7617dsewardj                             env->mode64 ? (Addr64)cdst->Ico.U64
60513dee849ec7c38746749065e67dc53b75daa7617dsewardj                                         : (Addr64)cdst->Ico.U32,
60523dee849ec7c38746749065e67dc53b75daa7617dsewardj                             amCIA, always, toFastEP));
60533dee849ec7c38746749065e67dc53b75daa7617dsewardj         } else {
60543dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. very occasionally .. */
60553dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* We can't use chaining, so ask for an assisted transfer,
60563dee849ec7c38746749065e67dc53b75daa7617dsewardj               as that's the only alternative that is allowable. */
60571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r = iselWordExpr_R(env, next, IEndianess);
60583dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, always,
60593dee849ec7c38746749065e67dc53b75daa7617dsewardj                                             Ijk_Boring));
60603dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
60613dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
60623dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
60632c49e036c365df707cd8e6622d66382f380557b2cerion   }
60643dee849ec7c38746749065e67dc53b75daa7617dsewardj
60653dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* Case: call/return (==boring) transfer to any address */
60663dee849ec7c38746749065e67dc53b75daa7617dsewardj   switch (jk) {
60673dee849ec7c38746749065e67dc53b75daa7617dsewardj      case Ijk_Boring: case Ijk_Ret: case Ijk_Call: {
60681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg       r     = iselWordExpr_R(env, next, IEndianess);
60693dee849ec7c38746749065e67dc53b75daa7617dsewardj         PPCAMode*  amCIA = PPCAMode_IR(offsIP, hregPPC_GPR31(env->mode64));
60703dee849ec7c38746749065e67dc53b75daa7617dsewardj         if (env->chainingAllowed) {
60713dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XIndir(r, amCIA, always));
60723dee849ec7c38746749065e67dc53b75daa7617dsewardj         } else {
60733dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, always,
60743dee849ec7c38746749065e67dc53b75daa7617dsewardj                                             Ijk_Boring));
60753dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
60763dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
60773dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
60783dee849ec7c38746749065e67dc53b75daa7617dsewardj      default:
60793dee849ec7c38746749065e67dc53b75daa7617dsewardj         break;
60803dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
60813dee849ec7c38746749065e67dc53b75daa7617dsewardj
60822f6902b260141dc063d131b3ec79af6f292a4a31sewardj   /* Case: assisted transfer to arbitrary address */
60833dee849ec7c38746749065e67dc53b75daa7617dsewardj   switch (jk) {
60842f6902b260141dc063d131b3ec79af6f292a4a31sewardj      /* Keep this list in sync with that for Ist_Exit above */
60852f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_ClientReq:
60862f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_EmFail:
60872f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_EmWarn:
60882f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_NoDecode:
60893dee849ec7c38746749065e67dc53b75daa7617dsewardj      case Ijk_NoRedir:
60902f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_SigBUS:
60912f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_SigTRAP:
60922f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_Sys_syscall:
609305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj      case Ijk_InvalICache:
60943dee849ec7c38746749065e67dc53b75daa7617dsewardj      {
60951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg      r     = iselWordExpr_R(env, next, IEndianess);
60963dee849ec7c38746749065e67dc53b75daa7617dsewardj         PPCAMode* amCIA = PPCAMode_IR(offsIP, hregPPC_GPR31(env->mode64));
60973dee849ec7c38746749065e67dc53b75daa7617dsewardj         addInstr(env, PPCInstr_XAssisted(r, amCIA, always, jk));
60983dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
60993dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
61003dee849ec7c38746749065e67dc53b75daa7617dsewardj      default:
61013dee849ec7c38746749065e67dc53b75daa7617dsewardj         break;
61023dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
61033dee849ec7c38746749065e67dc53b75daa7617dsewardj
61043dee849ec7c38746749065e67dc53b75daa7617dsewardj   vex_printf( "\n-- PUT(%d) = ", offsIP);
61053dee849ec7c38746749065e67dc53b75daa7617dsewardj   ppIRExpr( next );
61063dee849ec7c38746749065e67dc53b75daa7617dsewardj   vex_printf( "; exit-");
61073dee849ec7c38746749065e67dc53b75daa7617dsewardj   ppIRJumpKind(jk);
61083dee849ec7c38746749065e67dc53b75daa7617dsewardj   vex_printf( "\n");
61093dee849ec7c38746749065e67dc53b75daa7617dsewardj   vassert(0); // are we expecting any other kind?
6110bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
6111bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6112bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6113bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6114bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- Insn selector top-level                           ---*/
6115bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6116bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61173dee849ec7c38746749065e67dc53b75daa7617dsewardj/* Translate an entire SB to ppc code. */
6118cacba8e675988fbf21b08feea1f317a9c896c053florianHInstrArray* iselSB_PPC ( const IRSB* bb,
61199e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          VexArch      arch_host,
6120d8c64e082224b2e688abdef9219cc76fd82b373bflorian                          const VexArchInfo* archinfo_host,
6121d8c64e082224b2e688abdef9219cc76fd82b373bflorian                          const VexAbiInfo*  vbi,
61229e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Int offs_Host_EvC_Counter,
61239e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Int offs_Host_EvC_FailAddr,
61249e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Bool chainingAllowed,
61259e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Bool addProfInc,
6126dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian                          Addr max_ga)
61271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
6128bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion{
61293dee849ec7c38746749065e67dc53b75daa7617dsewardj   Int       i, j;
61303dee849ec7c38746749065e67dc53b75daa7617dsewardj   HReg      hregLo, hregMedLo, hregMedHi, hregHi;
61313dee849ec7c38746749065e67dc53b75daa7617dsewardj   ISelEnv*  env;
61323dee849ec7c38746749065e67dc53b75daa7617dsewardj   UInt      hwcaps_host = archinfo_host->hwcaps;
61333dee849ec7c38746749065e67dc53b75daa7617dsewardj   Bool      mode64 = False;
61343dee849ec7c38746749065e67dc53b75daa7617dsewardj   UInt      mask32, mask64;
61353dee849ec7c38746749065e67dc53b75daa7617dsewardj   PPCAMode *amCounter, *amFailAddr;
61361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   IREndness IEndianess;
6137bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61388f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   vassert(arch_host == VexArchPPC32 || arch_host == VexArchPPC64);
61398f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   mode64 = arch_host == VexArchPPC64;
61408f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj
61418f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   /* do some sanity checks */
61425117ce116f47141cb23d1b49cc826e19323add97sewardj   mask32 = VEX_HWCAPS_PPC32_F | VEX_HWCAPS_PPC32_V
6143c66d6fa5d9397f167b162483cf3419051cc01a80sewardj            | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX
61440c74bb5aa3240f693df0568d578baabf0c376dc4carll            | VEX_HWCAPS_PPC32_DFP | VEX_HWCAPS_PPC32_ISA2_07;
61450c74bb5aa3240f693df0568d578baabf0c376dc4carll
61465117ce116f47141cb23d1b49cc826e19323add97sewardj
614766d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj   mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX
61480c74bb5aa3240f693df0568d578baabf0c376dc4carll            | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP
61490c74bb5aa3240f693df0568d578baabf0c376dc4carll            | VEX_HWCAPS_PPC64_ISA2_07;
61505117ce116f47141cb23d1b49cc826e19323add97sewardj
61518f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   if (mode64) {
61528f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj      vassert((hwcaps_host & mask32) == 0);
61538f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   } else {
61548f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj      vassert((hwcaps_host & mask64) == 0);
61558f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   }
6156bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61579b76916dcc1628e133d57db001563429c6e3a590sewardj   /* Check that the host's endianness is as expected. */
61581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   vassert((archinfo_host->endness == VexEndnessBE) ||
61591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll	   (archinfo_host->endness == VexEndnessLE));
61601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
61611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (archinfo_host->endness == VexEndnessBE)
61621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll     IEndianess = Iend_BE;
61631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   else
61641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll     IEndianess = Iend_LE;
61659b76916dcc1628e133d57db001563429c6e3a590sewardj
6166bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Make up an initial environment to use. */
6167d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   env = LibVEX_Alloc_inline(sizeof(ISelEnv));
6168bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->vreg_ctr = 0;
6169bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61704628ccd1bafb946378f91849b92ffcfea0267b2ecerion   /* Are we being ppc32 or ppc64? */
61714628ccd1bafb946378f91849b92ffcfea0267b2ecerion   env->mode64 = mode64;
61724628ccd1bafb946378f91849b92ffcfea0267b2ecerion
6173bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Set up output code array. */
6174bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->code = newHInstrArray();
6175bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6176bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Copy BB's type env. */
6177bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->type_env = bb->tyenv;
6178bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6179bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Make up an IRTemp -> virtual HReg mapping.  This doesn't
6180c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    * change as we go along.
6181c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    *
6182c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    * vregmap2 and vregmap3 are only used in 32 bit mode
6183c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    * for supporting I128 in 32-bit mode
6184c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    */
6185bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->n_vregmap = bb->tyenv->types_used;
6186d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   env->vregmapLo    = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
6187d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   env->vregmapMedLo = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
61883dee849ec7c38746749065e67dc53b75daa7617dsewardj   if (mode64) {
61893dee849ec7c38746749065e67dc53b75daa7617dsewardj      env->vregmapMedHi = NULL;
61903dee849ec7c38746749065e67dc53b75daa7617dsewardj      env->vregmapHi    = NULL;
61913dee849ec7c38746749065e67dc53b75daa7617dsewardj   } else {
6192d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian      env->vregmapMedHi = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
6193d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian      env->vregmapHi    = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
6194c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
6195bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6196bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* and finally ... */
61973dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->chainingAllowed = chainingAllowed;
61983dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->max_ga          = max_ga;
61993dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->hwcaps          = hwcaps_host;
62003dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->previous_rm     = NULL;
62013dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->vbi             = vbi;
6202bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6203bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* For each IR temporary, allocate a suitably-kinded virtual
6204bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      register. */
6205bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   j = 0;
6206bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   for (i = 0; i < env->n_vregmap; i++) {
6207c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      hregLo = hregMedLo = hregMedHi = hregHi = INVALID_HREG;
6208bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      switch (bb->tyenv->types[i]) {
6209ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_I1:
6210ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_I8:
6211ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_I16:
6212bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Ity_I32:
6213a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         if (mode64) {
6214a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo = mkHReg(True, HRcInt64, 0, j++);
6215a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         } else {
6216a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo = mkHReg(True, HRcInt32, 0, j++);
6217bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         }
6218a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6219f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Ity_I64:
6220a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         if (mode64) {
6221a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt64, 0, j++);
6222a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         } else {
6223a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt32, 0, j++);
6224a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedLo = mkHReg(True, HRcInt32, 0, j++);
6225c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         }
6226a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6227c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Ity_I128:
6228a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         if (mode64) {
6229a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt64, 0, j++);
6230a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedLo = mkHReg(True, HRcInt64, 0, j++);
6231a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         } else {
6232a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt32, 0, j++);
6233a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedLo = mkHReg(True, HRcInt32, 0, j++);
6234a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedHi = mkHReg(True, HRcInt32, 0, j++);
6235a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregHi    = mkHReg(True, HRcInt32, 0, j++);
6236f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
6237a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6238ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_F32:
6239a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_F64:
6240a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo = mkHReg(True, HRcFlt64, 0, j++);
6241a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6242a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_V128:
6243a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo = mkHReg(True, HRcVec128, 0, j++);
6244a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6245f704eb2bab3d06d983c850b0bcf243e178060f75carll      case Ity_D32:
6246a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_D64:
6247a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo = mkHReg(True, HRcFlt64, 0, j++);
6248a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6249a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_D128:
6250a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo    = mkHReg(True, HRcFlt64, 0, j++);
6251a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregMedLo = mkHReg(True, HRcFlt64, 0, j++);
6252a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6253ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      default:
6254ab9132df645da753ae6b0421d551ea5c024aa6e6cerion         ppIRType(bb->tyenv->types[i]);
62555b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         vpanic("iselBB(ppc): IRTemp type");
6256bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      }
6257c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      env->vregmapLo[i]    = hregLo;
6258c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      env->vregmapMedLo[i] = hregMedLo;
6259c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (!mode64) {
6260c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         env->vregmapMedHi[i] = hregMedHi;
6261c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         env->vregmapHi[i]    = hregHi;
6262c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
6263bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
6264bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->vreg_ctr = j;
6265bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
62663dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* The very first instruction must be an event check. */
62673dee849ec7c38746749065e67dc53b75daa7617dsewardj   amCounter  = PPCAMode_IR(offs_Host_EvC_Counter, hregPPC_GPR31(mode64));
62683dee849ec7c38746749065e67dc53b75daa7617dsewardj   amFailAddr = PPCAMode_IR(offs_Host_EvC_FailAddr, hregPPC_GPR31(mode64));
62693dee849ec7c38746749065e67dc53b75daa7617dsewardj   addInstr(env, PPCInstr_EvCheck(amCounter, amFailAddr));
62703dee849ec7c38746749065e67dc53b75daa7617dsewardj
62713dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* Possibly a block counter increment (for profiling).  At this
62723dee849ec7c38746749065e67dc53b75daa7617dsewardj      point we don't know the address of the counter, so just pretend
62733dee849ec7c38746749065e67dc53b75daa7617dsewardj      it is zero.  It will have to be patched later, but before this
62743dee849ec7c38746749065e67dc53b75daa7617dsewardj      translation is used, by a call to LibVEX_patchProfCtr. */
62753dee849ec7c38746749065e67dc53b75daa7617dsewardj   if (addProfInc) {
62763dee849ec7c38746749065e67dc53b75daa7617dsewardj      addInstr(env, PPCInstr_ProfInc());
62773dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
62787f000af9c21e3b5059e0b2d26bcb9ca378ae0e54cerion
6279bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Ok, finally we can iterate over the statements. */
6280bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   for (i = 0; i < bb->stmts_used; i++)
62811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      iselStmt(env, bb->stmts[i], IEndianess);
6282bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
62831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselNext(env, bb->next, bb->jumpkind, bb->offsIP, IEndianess);
6284bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6285bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* record the number of vregs we used. */
6286bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->code->n_vregs = env->vreg_ctr;
6287bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   return env->code;
6288bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
6289bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6290bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6291bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------------*/
6292cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                     host_ppc_isel.c ---*/
6293bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------------*/
6294