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
10785952d4bf502fa756b2ac58595fd31fe0f88559sewardj   Copyright (C) 2004-2015 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? */
247836f940a13e89c722508e2ed3c75323f79bbc1688florian   UInt v = u & 0xFFFF;
247936f940a13e89c722508e2ed3c75323f79bbc1688florian
248036f940a13e89c722508e2ed3c75323f79bbc1688florian   v = (Int)(v << 16) >> 16;   /* sign extend */
248136f940a13e89c722508e2ed3c75323f79bbc1688florian
248236f940a13e89c722508e2ed3c75323f79bbc1688florian   return u == v;
2483a5f957df568527d44219383f4a04a8f4028b80a2sewardj}
2484a5f957df568527d44219383f4a04a8f4028b80a2sewardj
24852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardjstatic Bool uLong_fits_in_16_bits ( ULong u )
24862bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj{
24872bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* Is u the same as the sign-extend of its lower 16 bits? */
248836f940a13e89c722508e2ed3c75323f79bbc1688florian   ULong v = u & 0xFFFFULL;
248936f940a13e89c722508e2ed3c75323f79bbc1688florian
249036f940a13e89c722508e2ed3c75323f79bbc1688florian   v = (Long)(v << 48) >> 48;   /* sign extend */
249136f940a13e89c722508e2ed3c75323f79bbc1688florian
249236f940a13e89c722508e2ed3c75323f79bbc1688florian   return u == v;
24932bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj}
24942bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
249534085e398dd703798a0d6a60e039075e03397c8fsewardjstatic Bool uLong_is_4_aligned ( ULong u )
249634085e398dd703798a0d6a60e039075e03397c8fsewardj{
249734085e398dd703798a0d6a60e039075e03397c8fsewardj   return toBool((u & 3ULL) == 0);
249834085e398dd703798a0d6a60e039075e03397c8fsewardj}
249934085e398dd703798a0d6a60e039075e03397c8fsewardj
25004628ccd1bafb946378f91849b92ffcfea0267b2ecerionstatic Bool sane_AMode ( ISelEnv* env, PPCAMode* am )
2501cd304497d9d869f9b24a002299d3953ee072229bcerion{
25024628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
2503cd304497d9d869f9b24a002299d3953ee072229bcerion   switch (am->tag) {
2504f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pam_IR:
25052bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Using uInt_fits_in_16_bits in 64-bit mode seems a bit bogus,
25062bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         somehow, but I think it's OK. */
25074628ccd1bafb946378f91849b92ffcfea0267b2ecerion      return toBool( hregClass(am->Pam.IR.base) == HRcGPR(mode64) &&
2508f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion                     hregIsVirtual(am->Pam.IR.base) &&
25092bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                     uInt_fits_in_16_bits(am->Pam.IR.index) );
2510f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pam_RR:
25114628ccd1bafb946378f91849b92ffcfea0267b2ecerion      return toBool( hregClass(am->Pam.RR.base) == HRcGPR(mode64) &&
25124628ccd1bafb946378f91849b92ffcfea0267b2ecerion                     hregIsVirtual(am->Pam.RR.base) &&
25134628ccd1bafb946378f91849b92ffcfea0267b2ecerion                     hregClass(am->Pam.RR.index) == HRcGPR(mode64) &&
2514e6be61f7fef74148e92c8c027702bec9cd99dffaflorian                     hregIsVirtual(am->Pam.RR.index) );
2515f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
25165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("sane_AMode: unknown ppc amode tag");
2517cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2518cd304497d9d869f9b24a002299d3953ee072229bcerion}
2519cd304497d9d869f9b24a002299d3953ee072229bcerion
252034085e398dd703798a0d6a60e039075e03397c8fsewardjstatic
25211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllPPCAMode* iselWordExpr_AMode ( ISelEnv* env, IRExpr* e, IRType xferTy,
25221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                               IREndness IEndianess )
2523cd304497d9d869f9b24a002299d3953ee072229bcerion{
25241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   PPCAMode* am = iselWordExpr_AMode_wrk(env, e, xferTy, IEndianess);
25254628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(sane_AMode(env, am));
2526cd304497d9d869f9b24a002299d3953ee072229bcerion   return am;
2527cd304497d9d869f9b24a002299d3953ee072229bcerion}
2528cd304497d9d869f9b24a002299d3953ee072229bcerion
2529cd304497d9d869f9b24a002299d3953ee072229bcerion/* DO NOT CALL THIS DIRECTLY ! */
25301f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCAMode* iselWordExpr_AMode_wrk ( ISelEnv* env, IRExpr* e,
25311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          IRType xferTy, IREndness IEndianess )
2532cd304497d9d869f9b24a002299d3953ee072229bcerion{
2533cd304497d9d869f9b24a002299d3953ee072229bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
25342bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25352bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   if (env->mode64) {
25362bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
253734085e398dd703798a0d6a60e039075e03397c8fsewardj      /* If the data load/store type is I32 or I64, this amode might
253834085e398dd703798a0d6a60e039075e03397c8fsewardj         be destined for use in ld/ldu/lwa/st/stu.  In which case
253934085e398dd703798a0d6a60e039075e03397c8fsewardj         insist that if it comes out as an _IR, the immediate must
254034085e398dd703798a0d6a60e039075e03397c8fsewardj         have its bottom two bits be zero.  This does assume that for
254134085e398dd703798a0d6a60e039075e03397c8fsewardj         any other type (I8/I16/I128/F32/F64/V128) the amode will not
254234085e398dd703798a0d6a60e039075e03397c8fsewardj         be parked in any such instruction.  But that seems a
254334085e398dd703798a0d6a60e039075e03397c8fsewardj         reasonable assumption.  */
254434085e398dd703798a0d6a60e039075e03397c8fsewardj      Bool aligned4imm = toBool(xferTy == Ity_I32 || xferTy == Ity_I64);
254534085e398dd703798a0d6a60e039075e03397c8fsewardj
25462bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      vassert(ty == Ity_I64);
2547ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
25482bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add64(expr,i), where i == sign-extend of (i & 0xFFFF) */
25492bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25502bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add64
25512bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->tag == Iex_Const
25522bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U64
255334085e398dd703798a0d6a60e039075e03397c8fsewardj          && (aligned4imm  ? uLong_is_4_aligned(e->Iex.Binop.arg2
255434085e398dd703798a0d6a60e039075e03397c8fsewardj                                                 ->Iex.Const.con->Ico.U64)
255534085e398dd703798a0d6a60e039075e03397c8fsewardj                           : True)
25562bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && uLong_fits_in_16_bits(e->Iex.Binop.arg2
25572bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                    ->Iex.Const.con->Ico.U64)) {
25582bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_IR( (Int)e->Iex.Binop.arg2->Iex.Const.con->Ico.U64,
25591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             iselWordExpr_R(env, e->Iex.Binop.arg1,
25601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess) );
25612bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
256233aa6da1102a12139debec996c33e4effa16f77ccerion
25632bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add64(expr,expr) */
25642bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25652bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add64) {
25661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
25671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_idx  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
25682bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_RR( r_idx, r_base );
25692bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
25702bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25712bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   } else {
25722bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25732bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      vassert(ty == Ity_I32);
25742bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */
25762bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25772bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add32
25782bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->tag == Iex_Const
25792bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32
25802bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && uInt_fits_in_16_bits(e->Iex.Binop.arg2
25812bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                   ->Iex.Const.con->Ico.U32)) {
25822bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_IR( (Int)e->Iex.Binop.arg2->Iex.Const.con->Ico.U32,
25831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             iselWordExpr_R(env, e->Iex.Binop.arg1,
25841f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess) );
25852bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
25862bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
25872bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      /* Add32(expr,expr) */
25882bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (e->tag == Iex_Binop
25892bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj          && e->Iex.Binop.op == Iop_Add32) {
25901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
25911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_idx  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
25922bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return PPCAMode_RR( r_idx, r_base );
25932bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
25942bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
2595cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2596cd304497d9d869f9b24a002299d3953ee072229bcerion
2597cd304497d9d869f9b24a002299d3953ee072229bcerion   /* Doesn't match anything in particular.  Generate it into
2598cd304497d9d869f9b24a002299d3953ee072229bcerion      a register and use that. */
25991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCAMode_IR( 0, iselWordExpr_R(env,e,IEndianess) );
2600cd304497d9d869f9b24a002299d3953ee072229bcerion}
2601cd304497d9d869f9b24a002299d3953ee072229bcerion
2602cd304497d9d869f9b24a002299d3953ee072229bcerion
2603b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* --------------------- RH --------------------- */
2604b51f0f4f33256638ed953156a2635aa739b232f1sewardj
26052bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* Compute an I8/I16/I32 (and I64, in 64-bit mode) into a RH
26062bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   (reg-or-halfword-immediate).  It's important to specify whether the
26072bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   immediate is to be regarded as signed or not.  If yes, this will
26082bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   never return -32768 as an immediate; this guaranteed that all
26092bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   signed immediates that are return can have their sign inverted if
26102bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   need be. */
2611b51f0f4f33256638ed953156a2635aa739b232f1sewardj
26121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH ( ISelEnv* env, Bool syned, IRExpr* e,
26131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                IREndness IEndianess )
2614b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
26151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll  PPCRH* ri = iselWordExpr_RH_wrk(env, syned, e, IEndianess);
2616b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* sanity checks ... */
2617b51f0f4f33256638ed953156a2635aa739b232f1sewardj   switch (ri->tag) {
2618f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Imm:
2619f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(ri->Prh.Imm.syned == syned);
2620f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (syned)
2621f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vassert(ri->Prh.Imm.imm16 != 0x8000);
2622f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2623f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Reg:
26244628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Prh.Reg.reg) == HRcGPR(env->mode64));
2625f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Prh.Reg.reg));
2626f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2627f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
26285b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("iselIntExpr_RH: unknown ppc RH tag");
2629b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2630b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2631b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2632b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* DO NOT CALL THIS DIRECTLY ! */
26331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH_wrk ( ISelEnv* env, Bool syned, IRExpr* e,
26341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IREndness IEndianess )
2635b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
2636f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   ULong u;
2637f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   Long  l;
2638b51f0f4f33256638ed953156a2635aa739b232f1sewardj   IRType ty = typeOfIRExpr(env->type_env,e);
2639f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8  || ty == Ity_I16 ||
26404628ccd1bafb946378f91849b92ffcfea0267b2ecerion           ty == Ity_I32 || ((ty == Ity_I64) && env->mode64));
2641b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2642b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* special case: immediate */
2643b51f0f4f33256638ed953156a2635aa739b232f1sewardj   if (e->tag == Iex_Const) {
26445b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IRConst* con = e->Iex.Const.con;
2645b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* What value are we aiming to generate? */
26465b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (con->tag) {
2647f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* Note: Not sign-extending - we carry 'syned' around */
26484628ccd1bafb946378f91849b92ffcfea0267b2ecerion      case Ico_U64: vassert(env->mode64);
26495b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                    u =              con->Ico.U64; break;
26505b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U32: u = 0xFFFFFFFF & con->Ico.U32; break;
26515b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U16: u = 0x0000FFFF & con->Ico.U16; break;
26525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U8:  u = 0x000000FF & con->Ico.U8; break;
26535b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default:      vpanic("iselIntExpr_RH.Iex_Const(ppch)");
2654b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
2655f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      l = (Long)u;
2656b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* Now figure out if it's representable. */
2657b51f0f4f33256638ed953156a2635aa739b232f1sewardj      if (!syned && u <= 65535) {
26585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         return PPCRH_Imm(False/*unsigned*/, toUShort(u & 0xFFFF));
2659b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
2660f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (syned && l >= -32767 && l <= 32767) {
26615b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         return PPCRH_Imm(True/*signed*/, toUShort(u & 0xFFFF));
2662b51f0f4f33256638ed953156a2635aa739b232f1sewardj      }
2663b51f0f4f33256638ed953156a2635aa739b232f1sewardj      /* no luck; use the Slow Way. */
2664b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2665b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2666b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* default case: calculate into a register and return that */
26671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRH_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2668b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2669b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2670b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2671cd304497d9d869f9b24a002299d3953ee072229bcerion/* --------------------- RIs --------------------- */
2672cd304497d9d869f9b24a002299d3953ee072229bcerion
26735b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion/* Calculate an expression into an PPCRI operand.  As with
26742bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   iselIntExpr_R, the expression can have type 32, 16 or 8 bits, or,
26752bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   in 64-bit mode, 64 bits. */
2676cd304497d9d869f9b24a002299d3953ee072229bcerion
26771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRI* iselWordExpr_RI ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
2678cd304497d9d869f9b24a002299d3953ee072229bcerion{
26791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   PPCRI* ri = iselWordExpr_RI_wrk(env, e, IEndianess);
2680cd304497d9d869f9b24a002299d3953ee072229bcerion   /* sanity checks ... */
2681cd304497d9d869f9b24a002299d3953ee072229bcerion   switch (ri->tag) {
2682f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pri_Imm:
2683f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2684f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Pri_Reg:
26854628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Pri.Reg) == HRcGPR(env->mode64));
2686f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Pri.Reg));
2687f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2688f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
26895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("iselIntExpr_RI: unknown ppc RI tag");
2690cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2691cd304497d9d869f9b24a002299d3953ee072229bcerion}
2692cd304497d9d869f9b24a002299d3953ee072229bcerion
2693cd304497d9d869f9b24a002299d3953ee072229bcerion/* DO NOT CALL THIS DIRECTLY ! */
26941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRI* iselWordExpr_RI_wrk ( ISelEnv* env, IRExpr* e,
26951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IREndness IEndianess )
2696cd304497d9d869f9b24a002299d3953ee072229bcerion{
2697f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   Long  l;
2698cd304497d9d869f9b24a002299d3953ee072229bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
2699f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8  || ty == Ity_I16 ||
27004628ccd1bafb946378f91849b92ffcfea0267b2ecerion           ty == Ity_I32 || ((ty == Ity_I64) && env->mode64));
2701cd304497d9d869f9b24a002299d3953ee072229bcerion
2702cd304497d9d869f9b24a002299d3953ee072229bcerion   /* special case: immediate */
2703cd304497d9d869f9b24a002299d3953ee072229bcerion   if (e->tag == Iex_Const) {
27045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IRConst* con = e->Iex.Const.con;
27055b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (con->tag) {
27064628ccd1bafb946378f91849b92ffcfea0267b2ecerion      case Ico_U64: vassert(env->mode64);
27075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                    l = (Long)            con->Ico.U64; break;
27085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U32: l = (Long)(Int)       con->Ico.U32; break;
27095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U16: l = (Long)(Int)(Short)con->Ico.U16; break;
27105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      case Ico_U8:  l = (Long)(Int)(Char )con->Ico.U8;  break;
27115b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default:      vpanic("iselIntExpr_RI.Iex_Const(ppch)");
2712cd304497d9d869f9b24a002299d3953ee072229bcerion      }
27135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      return PPCRI_Imm((ULong)l);
2714cd304497d9d869f9b24a002299d3953ee072229bcerion   }
2715cd304497d9d869f9b24a002299d3953ee072229bcerion
2716cd304497d9d869f9b24a002299d3953ee072229bcerion   /* default case: calculate into a register and return that */
27171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRI_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2718cd304497d9d869f9b24a002299d3953ee072229bcerion}
2719cd304497d9d869f9b24a002299d3953ee072229bcerion
2720cd304497d9d869f9b24a002299d3953ee072229bcerion
2721b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* --------------------- RH5u --------------------- */
2722b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2723b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter
2724b51f0f4f33256638ed953156a2635aa739b232f1sewardj   being an immediate in the range 1 .. 31 inclusive.  Used for doing
27252bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   shift amounts.  Only used in 32-bit mode. */
2726b51f0f4f33256638ed953156a2635aa739b232f1sewardj
27271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH5u ( ISelEnv* env, IRExpr* e,
27281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                  IREndness IEndianess )
2729b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
27302bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   PPCRH* ri;
27312bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   vassert(!env->mode64);
27321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   ri = iselWordExpr_RH5u_wrk(env, e, IEndianess);
2733b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* sanity checks ... */
2734b51f0f4f33256638ed953156a2635aa739b232f1sewardj   switch (ri->tag) {
2735f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Imm:
2736f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(ri->Prh.Imm.imm16 >= 1 && ri->Prh.Imm.imm16 <= 31);
2737f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(!ri->Prh.Imm.syned);
2738f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2739f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Reg:
27404628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Prh.Reg.reg) == HRcGPR(env->mode64));
2741f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Prh.Reg.reg));
2742f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2743f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
27445b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      vpanic("iselIntExpr_RH5u: unknown ppc RI tag");
2745b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2746b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2747b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2748b51f0f4f33256638ed953156a2635aa739b232f1sewardj/* DO NOT CALL THIS DIRECTLY ! */
27491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH5u_wrk ( ISelEnv* env, IRExpr* e,
27501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      IREndness IEndianess )
2751b51f0f4f33256638ed953156a2635aa739b232f1sewardj{
2752b51f0f4f33256638ed953156a2635aa739b232f1sewardj   IRType ty = typeOfIRExpr(env->type_env,e);
2753b51f0f4f33256638ed953156a2635aa739b232f1sewardj   vassert(ty == Ity_I8);
2754b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2755b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* special case: immediate */
2756b51f0f4f33256638ed953156a2635aa739b232f1sewardj   if (e->tag == Iex_Const
2757b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && e->Iex.Const.con->tag == Ico_U8
2758b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && e->Iex.Const.con->Ico.U8 >= 1
2759b51f0f4f33256638ed953156a2635aa739b232f1sewardj       && e->Iex.Const.con->Ico.U8 <= 31) {
27605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      return PPCRH_Imm(False/*unsigned*/, e->Iex.Const.con->Ico.U8);
2761b51f0f4f33256638ed953156a2635aa739b232f1sewardj   }
2762b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2763b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* default case: calculate into a register and return that */
27641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRH_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2765b51f0f4f33256638ed953156a2635aa739b232f1sewardj}
2766b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2767b51f0f4f33256638ed953156a2635aa739b232f1sewardj
2768f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* --------------------- RH6u --------------------- */
2769f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2770f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* Compute an I8 into a reg-or-6-bit-unsigned-immediate, the latter
2771f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   being an immediate in the range 1 .. 63 inclusive.  Used for doing
27722bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   shift amounts.  Only used in 64-bit mode. */
2773f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
27741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH6u ( ISelEnv* env, IRExpr* e,
27751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                  IREndness IEndianess )
2776f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
27772bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   PPCRH* ri;
27782bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   vassert(env->mode64);
27791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   ri = iselWordExpr_RH6u_wrk(env, e, IEndianess);
2780f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* sanity checks ... */
2781f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   switch (ri->tag) {
2782f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Imm:
2783f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(ri->Prh.Imm.imm16 >= 1 && ri->Prh.Imm.imm16 <= 63);
2784f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(!ri->Prh.Imm.syned);
2785f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2786f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   case Prh_Reg:
27874628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(hregClass(ri->Prh.Reg.reg) == HRcGPR(env->mode64));
2788f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vassert(hregIsVirtual(ri->Prh.Reg.reg));
2789f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return ri;
2790f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   default:
2791f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      vpanic("iselIntExpr_RH6u: unknown ppc64 RI tag");
2792f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
2793f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
2794f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2795f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* DO NOT CALL THIS DIRECTLY ! */
27961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCRH* iselWordExpr_RH6u_wrk ( ISelEnv* env, IRExpr* e,
27971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      IREndness IEndianess )
2798f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
2799f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   IRType ty = typeOfIRExpr(env->type_env,e);
2800f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(ty == Ity_I8);
2801f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2802f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* special case: immediate */
2803f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Const
2804f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && e->Iex.Const.con->tag == Ico_U8
2805f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && e->Iex.Const.con->Ico.U8 >= 1
2806f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && e->Iex.Const.con->Ico.U8 <= 63) {
28075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      return PPCRH_Imm(False/*unsigned*/, e->Iex.Const.con->Ico.U8);
2808f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
2809f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2810f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* default case: calculate into a register and return that */
28111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return PPCRH_Reg( iselWordExpr_R ( env, e, IEndianess ) );
2812f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
2813f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2814f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
28152c49e036c365df707cd8e6622d66382f380557b2cerion/* --------------------- CONDCODE --------------------- */
28162c49e036c365df707cd8e6622d66382f380557b2cerion
28172c49e036c365df707cd8e6622d66382f380557b2cerion/* Generate code to evaluated a bit-typed expression, returning the
28182c49e036c365df707cd8e6622d66382f380557b2cerion   condition code which would correspond when the expression would
28192c49e036c365df707cd8e6622d66382f380557b2cerion   notionally have returned 1. */
28202c49e036c365df707cd8e6622d66382f380557b2cerion
28211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCCondCode iselCondCode ( ISelEnv* env, IRExpr* e,
28221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                  IREndness IEndianess )
28232c49e036c365df707cd8e6622d66382f380557b2cerion{
28242c49e036c365df707cd8e6622d66382f380557b2cerion   /* Uh, there's nothing we can sanity check here, unfortunately. */
28251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   return iselCondCode_wrk(env,e, IEndianess);
28262c49e036c365df707cd8e6622d66382f380557b2cerion}
28272c49e036c365df707cd8e6622d66382f380557b2cerion
28282c49e036c365df707cd8e6622d66382f380557b2cerion/* DO NOT CALL THIS DIRECTLY ! */
28291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic PPCCondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e,
28301f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                      IREndness IEndianess )
28312c49e036c365df707cd8e6622d66382f380557b2cerion{
28322c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(e);
28332c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(typeOfIRExpr(env->type_env,e) == Ity_I1);
28342c49e036c365df707cd8e6622d66382f380557b2cerion
28358c51ed42ea3f276e406e5c2fc80458de2e079255cerion   /* Constant 1:Bit */
28368c51ed42ea3f276e406e5c2fc80458de2e079255cerion   if (e->tag == Iex_Const && e->Iex.Const.con->Ico.U1 == True) {
28378c51ed42ea3f276e406e5c2fc80458de2e079255cerion      // Make a compare that will always be true:
2838b51f0f4f33256638ed953156a2635aa739b232f1sewardj      HReg r_zero = newVRegI(env);
28394628ccd1bafb946378f91849b92ffcfea0267b2ecerion      addInstr(env, PPCInstr_LI(r_zero, 0, env->mode64));
28405b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28415b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r_zero, PPCRH_Reg(r_zero)));
2842b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ );
28438c51ed42ea3f276e406e5c2fc80458de2e079255cerion   }
28442c49e036c365df707cd8e6622d66382f380557b2cerion
28452c49e036c365df707cd8e6622d66382f380557b2cerion   /* Not1(...) */
28462c49e036c365df707cd8e6622d66382f380557b2cerion   if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_Not1) {
28472c49e036c365df707cd8e6622d66382f380557b2cerion      /* Generate code for the arg, and negate the test condition */
28481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCCondCode cond = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
284933aa6da1102a12139debec996c33e4effa16f77ccerion      cond.test = invertCondTest(cond.test);
2850ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      return cond;
28512c49e036c365df707cd8e6622d66382f380557b2cerion   }
28522c49e036c365df707cd8e6622d66382f380557b2cerion
28532bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: 32to1 or 64to1 --- */
2854ed623dbefb52ca3211490d656abc999a129df060cerion
28552bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* 32to1, 64to1 */
2856bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion   if (e->tag == Iex_Unop &&
2857bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion       (e->Iex.Unop.op == Iop_32to1 || e->Iex.Unop.op == Iop_64to1)) {
28581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
285920ef5472eac767474c93b7835364a23f24c0ec5dsewardj      HReg tmp = newVRegI(env);
286020ef5472eac767474c93b7835364a23f24c0ec5dsewardj      /* could do better, probably -- andi. */
28615b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Alu(Palu_AND, tmp,
28625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 src, PPCRH_Imm(False,1)));
28635b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28645b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, tmp, PPCRH_Imm(False,1)));
286520ef5472eac767474c93b7835364a23f24c0ec5dsewardj      return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ );
286620ef5472eac767474c93b7835364a23f24c0ec5dsewardj   }
286720ef5472eac767474c93b7835364a23f24c0ec5dsewardj
286802d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   /* --- patterns rooted at: CmpNEZ8 --- */
286902d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion
287002d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   /* CmpNEZ8(x) */
2871009230b9758291b594e60d7c0243a73d53e81854sewardj   /* Note this cloned as CmpNE8(x,0) below. */
2872b51f0f4f33256638ed953156a2635aa739b232f1sewardj   /* could do better -- andi. */
287302d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   if (e->tag == Iex_Unop
287402d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion       && e->Iex.Unop.op == Iop_CmpNEZ8) {
28751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg arg = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
28762bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      HReg tmp = newVRegI(env);
28772bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      addInstr(env, PPCInstr_Alu(Palu_AND, tmp, arg,
28785b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 PPCRH_Imm(False,0xFF)));
28795b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28802bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                 7/*cr*/, tmp, PPCRH_Imm(False,0)));
2881b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
288202d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion   }
288302d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion
2884ed623dbefb52ca3211490d656abc999a129df060cerion   /* --- patterns rooted at: CmpNEZ32 --- */
2885ed623dbefb52ca3211490d656abc999a129df060cerion
2886ed623dbefb52ca3211490d656abc999a129df060cerion   /* CmpNEZ32(x) */
2887ed623dbefb52ca3211490d656abc999a129df060cerion   if (e->tag == Iex_Unop
2888ed623dbefb52ca3211490d656abc999a129df060cerion       && e->Iex.Unop.op == Iop_CmpNEZ32) {
28891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg r1 = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
28905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
28915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r1, PPCRH_Imm(False,0)));
2892b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
2893ed623dbefb52ca3211490d656abc999a129df060cerion   }
2894ed623dbefb52ca3211490d656abc999a129df060cerion
28952bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: Cmp*32* --- */
2896ed623dbefb52ca3211490d656abc999a129df060cerion
2897b536af93912b69421440c27aa0533ad77d678f85cerion   /* Cmp*32*(x,y) */
2898b536af93912b69421440c27aa0533ad77d678f85cerion   if (e->tag == Iex_Binop
2899b536af93912b69421440c27aa0533ad77d678f85cerion       && (e->Iex.Binop.op == Iop_CmpEQ32
2900b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpNE32
2901b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLT32S
2902b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLT32U
2903b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLE32S
2904b536af93912b69421440c27aa0533ad77d678f85cerion           || e->Iex.Binop.op == Iop_CmpLE32U)) {
2905bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      Bool syned = (e->Iex.Binop.op == Iop_CmpLT32S ||
2906bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion                    e->Iex.Binop.op == Iop_CmpLE32S);
29071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg   r1  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
29081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCRH* ri2 = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2, IEndianess);
29095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(syned, True/*32bit cmp*/,
29105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r1, ri2));
2911ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
2912b536af93912b69421440c27aa0533ad77d678f85cerion      switch (e->Iex.Binop.op) {
2913f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpEQ32:  return mk_PPCCondCode( Pct_TRUE,  Pcf_7EQ );
2914f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpNE32:  return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
291566d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj      case Iop_CmpLT32U: case Iop_CmpLT32S:
291666d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj         return mk_PPCCondCode( Pct_TRUE,  Pcf_7LT );
291766d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj      case Iop_CmpLE32U: case Iop_CmpLE32S:
291866d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj         return mk_PPCCondCode( Pct_FALSE, Pcf_7GT );
29195b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default: vpanic("iselCondCode(ppc): CmpXX32");
2920b536af93912b69421440c27aa0533ad77d678f85cerion      }
2921b536af93912b69421440c27aa0533ad77d678f85cerion   }
2922b536af93912b69421440c27aa0533ad77d678f85cerion
29232bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: CmpNEZ64 --- */
29242bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
29252bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* CmpNEZ64 */
29262bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   if (e->tag == Iex_Unop
29272bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj       && e->Iex.Unop.op == Iop_CmpNEZ64) {
29282bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      if (!env->mode64) {
29292bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         HReg hi, lo;
29302bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         HReg tmp = newVRegI(env);
29311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr( &hi, &lo, env, e->Iex.Unop.arg, IEndianess );
2932b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, tmp, lo, PPCRH_Reg(hi)));
29332bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         addInstr(env, PPCInstr_Cmp(False/*sign*/, True/*32bit cmp*/,
29342bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                    7/*cr*/, tmp,PPCRH_Imm(False,0)));
29352bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
29362bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      } else {  // mode64
29371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
29382bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         addInstr(env, PPCInstr_Cmp(False/*sign*/, False/*64bit cmp*/,
29392bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                    7/*cr*/, r_src,PPCRH_Imm(False,0)));
29402bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
29412bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj      }
29422bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   }
29432bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
29442bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   /* --- patterns rooted at: Cmp*64* --- */
29452bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj
2946f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* Cmp*64*(x,y) */
2947f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Binop
2948f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion       && (e->Iex.Binop.op == Iop_CmpEQ64
2949f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpNE64
2950f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLT64S
2951f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLT64U
2952f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLE64S
2953f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion           || e->Iex.Binop.op == Iop_CmpLE64U)) {
2954bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      Bool   syned = (e->Iex.Binop.op == Iop_CmpLT64S ||
2955bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion                      e->Iex.Binop.op == Iop_CmpLE64S);
29561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg    r1 = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
29571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCRH* ri2 = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2, IEndianess);
29584628ccd1bafb946378f91849b92ffcfea0267b2ecerion      vassert(env->mode64);
29595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_Cmp(syned, False/*64bit cmp*/,
29605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                 7/*cr*/, r1, ri2));
2961f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2962f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      switch (e->Iex.Binop.op) {
2963f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpEQ64:  return mk_PPCCondCode( Pct_TRUE,  Pcf_7EQ );
2964f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpNE64:  return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
2965f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpLT64U: return mk_PPCCondCode( Pct_TRUE,  Pcf_7LT );
2966f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_CmpLE64U: return mk_PPCCondCode( Pct_FALSE, Pcf_7GT );
29675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      default: vpanic("iselCondCode(ppc): CmpXX64");
2968f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
2969f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
2970f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
2971009230b9758291b594e60d7c0243a73d53e81854sewardj   /* --- patterns rooted at: CmpNE8 --- */
2972009230b9758291b594e60d7c0243a73d53e81854sewardj
2973009230b9758291b594e60d7c0243a73d53e81854sewardj   /* CmpNE8(x,0) */
2974009230b9758291b594e60d7c0243a73d53e81854sewardj   /* Note this is a direct copy of CmpNEZ8 above. */
2975009230b9758291b594e60d7c0243a73d53e81854sewardj   /* could do better -- andi. */
2976009230b9758291b594e60d7c0243a73d53e81854sewardj   if (e->tag == Iex_Binop
2977009230b9758291b594e60d7c0243a73d53e81854sewardj       && e->Iex.Binop.op == Iop_CmpNE8
2978009230b9758291b594e60d7c0243a73d53e81854sewardj       && isZeroU8(e->Iex.Binop.arg2)) {
29791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg arg = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
2980009230b9758291b594e60d7c0243a73d53e81854sewardj      HReg tmp = newVRegI(env);
2981009230b9758291b594e60d7c0243a73d53e81854sewardj      addInstr(env, PPCInstr_Alu(Palu_AND, tmp, arg,
2982009230b9758291b594e60d7c0243a73d53e81854sewardj                                 PPCRH_Imm(False,0xFF)));
2983009230b9758291b594e60d7c0243a73d53e81854sewardj      addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
2984009230b9758291b594e60d7c0243a73d53e81854sewardj                                 7/*cr*/, tmp, PPCRH_Imm(False,0)));
2985009230b9758291b594e60d7c0243a73d53e81854sewardj      return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
2986009230b9758291b594e60d7c0243a73d53e81854sewardj   }
2987009230b9758291b594e60d7c0243a73d53e81854sewardj
29889abfcbca0696407c4b781b9395298c5edffa33a0cerion   /* var */
2989dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
2990dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      HReg r_src      = lookupIRTemp(env, e->Iex.RdTmp.tmp);
2991be112dd3758ab345310b57f95bc43086e0191de9cerion      HReg src_masked = newVRegI(env);
29925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env,
29935b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCInstr_Alu(Palu_AND, src_masked,
29945b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                            r_src, PPCRH_Imm(False,1)));
29955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env,
29965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/,
29975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                            7/*cr*/, src_masked, PPCRH_Imm(False,1)));
2998b51f0f4f33256638ed953156a2635aa739b232f1sewardj      return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ );
29999abfcbca0696407c4b781b9395298c5edffa33a0cerion   }
3000cd304497d9d869f9b24a002299d3953ee072229bcerion
3001f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vex_printf("iselCondCode(ppc): No such tag(%u)\n", e->tag);
30022c49e036c365df707cd8e6622d66382f380557b2cerion   ppIRExpr(e);
3003f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vpanic("iselCondCode(ppc)");
3004f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
3005f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3006f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3007f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/*---------------------------------------------------------*/
30082bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/*--- ISEL: Integer expressions (128 bit)               ---*/
3009f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/*---------------------------------------------------------*/
3010f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
30112bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 64-bit mode ONLY: compute a 128-bit value into a register pair,
30122bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   which is returned as the first two parameters.  As with
30132bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   iselWordExpr_R, these may be either real or virtual regs; in any
30142bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   case they must not be changed by subsequent code emitted by the
30152bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   caller.  */
3016f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
30175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt128Expr ( HReg* rHi, HReg* rLo,
30181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                             ISelEnv* env, IRExpr* e, IREndness IEndianess )
3019f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
30204628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(env->mode64);
30211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselInt128Expr_wrk(rHi, rLo, env, e, IEndianess);
3022f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion#  if 0
3023f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3024f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion#  endif
30254628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(*rHi) == HRcGPR(env->mode64));
3026f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregIsVirtual(*rHi));
30274628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(hregClass(*rLo) == HRcGPR(env->mode64));
3028f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(hregIsVirtual(*rLo));
3029f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion}
3030f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3031f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion/* DO NOT CALL THIS DIRECTLY ! */
30325b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt128Expr_wrk ( HReg* rHi, HReg* rLo,
30331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 ISelEnv* env, IRExpr* e, IREndness IEndianess )
3034f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion{
3035f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(e);
3036f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vassert(typeOfIRExpr(env->type_env,e) == Ity_I128);
3037f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3038f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* read 128-bit IRTemp */
3039dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3040dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      lookupIRTempPair( rHi, rLo, env, e->Iex.RdTmp.tmp);
3041f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      return;
3042f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   }
3043f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3044f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* --------- BINARY ops --------- */
3045f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Binop) {
3046f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      switch (e->Iex.Binop.op) {
3047f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* 64 x 64 -> 128 multiply */
3048f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_MullU64:
3049f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_MullS64: {
3050f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg     tLo     = newVRegI(env);
3051f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg     tHi     = newVRegI(env);
3052f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         Bool     syned   = toBool(e->Iex.Binop.op == Iop_MullS64);
30531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg     r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
30541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg     r_srcR  = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
30555b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(False/*signedness irrelevant*/,
30565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     False/*lo64*/, False/*64bit mul*/,
30575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, r_srcL, r_srcR));
30585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_MulL(syned,
30595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     True/*hi64*/, False/*64bit mul*/,
30605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tHi, r_srcL, r_srcR));
3061f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3062f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3063f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3064f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3065f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3066347da2cdf69bf23e882d957fbe923bb959a199e9sewardj      /* 64HLto128(e1,e2) */
3067347da2cdf69bf23e882d957fbe923bb959a199e9sewardj      case Iop_64HLto128:
30681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
30691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
3070347da2cdf69bf23e882d957fbe923bb959a199e9sewardj         return;
3071f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
3072f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
3073f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3074f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   } /* if (e->tag == Iex_Binop) */
3075f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3076f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3077f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   /* --------- UNARY ops --------- */
3078f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   if (e->tag == Iex_Unop) {
3079f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      switch (e->Iex.Unop.op) {
3080f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
3081f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
3082f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3083f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   } /* if (e->tag == Iex_Unop) */
3084f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3085f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vex_printf("iselInt128Expr(ppc64): No such tag(%u)\n", e->tag);
3086f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   ppIRExpr(e);
3087f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion   vpanic("iselInt128Expr(ppc64)");
30882c49e036c365df707cd8e6622d66382f380557b2cerion}
30892c49e036c365df707cd8e6622d66382f380557b2cerion
30902c49e036c365df707cd8e6622d66382f380557b2cerion
30912c49e036c365df707cd8e6622d66382f380557b2cerion/*---------------------------------------------------------*/
30922c49e036c365df707cd8e6622d66382f380557b2cerion/*--- ISEL: Integer expressions (64 bit)                ---*/
30932c49e036c365df707cd8e6622d66382f380557b2cerion/*---------------------------------------------------------*/
30942c49e036c365df707cd8e6622d66382f380557b2cerion
3095c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* 32-bit mode ONLY: compute a 128-bit value into a register quad */
3096c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselInt128Expr_to_32x4 ( HReg* rHi, HReg* rMedHi, HReg* rMedLo,
30971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     HReg* rLo, ISelEnv* env, IRExpr* e,
30981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IREndness IEndianess )
3099c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
3100c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(!env->mode64);
31011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselInt128Expr_to_32x4_wrk(rHi, rMedHi, rMedLo, rLo, env, e, IEndianess);
3102c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj#  if 0
3103c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3104c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj#  endif
3105c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rHi) == HRcInt32);
3106c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rHi));
3107c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rMedHi) == HRcInt32);
3108c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rMedHi));
3109c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rMedLo) == HRcInt32);
3110c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rMedLo));
3111c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(*rLo) == HRcInt32);
3112c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregIsVirtual(*rLo));
3113c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
3114c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3115c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void iselInt128Expr_to_32x4_wrk ( HReg* rHi, HReg* rMedHi,
3116c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                         HReg* rMedLo, HReg* rLo,
31171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         ISelEnv* env, IRExpr* e,
31181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IREndness IEndianess )
3119c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
3120c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(e);
3121c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(typeOfIRExpr(env->type_env,e) == Ity_I128);
3122c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3123c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* read 128-bit IRTemp */
3124c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_RdTmp) {
3125c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      lookupIRTempQuad( rHi, rMedHi, rMedLo, rLo, env, e->Iex.RdTmp.tmp);
3126c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return;
3127c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
3128c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3129c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Binop) {
3130c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3131c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      IROp op_binop = e->Iex.Binop.op;
3132c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      switch (op_binop) {
3133c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_64HLto128:
31341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(rHi, rMedHi, env, e->Iex.Binop.arg1, IEndianess);
31351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(rMedLo, rLo, env, e->Iex.Binop.arg2, IEndianess);
3136c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
3137c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
3138c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         vex_printf("iselInt128Expr_to_32x4_wrk: Binop case 0x%x not found\n",
3139c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                    op_binop);
3140c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
3141c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
3142c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
3143c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3144c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vex_printf("iselInt128Expr_to_32x4_wrk: e->tag 0x%x not found\n", e->tag);
3145c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   return;
3146c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
3147c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
31482bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj/* 32-bit mode ONLY: compute a 64-bit value into a register pair,
31492bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   which is returned as the first two parameters.  As with
31502bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   iselIntExpr_R, these may be either real or virtual regs; in any
31512bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   case they must not be changed by subsequent code emitted by the
31522bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj   caller.  */
31532c49e036c365df707cd8e6622d66382f380557b2cerion
31545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt64Expr ( HReg* rHi, HReg* rLo,
31551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                            ISelEnv* env, IRExpr* e,
31561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                            IREndness IEndianess )
31572c49e036c365df707cd8e6622d66382f380557b2cerion{
31584628ccd1bafb946378f91849b92ffcfea0267b2ecerion   vassert(!env->mode64);
31591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselInt64Expr_wrk(rHi, rLo, env, e, IEndianess);
31602c49e036c365df707cd8e6622d66382f380557b2cerion#  if 0
31612c49e036c365df707cd8e6622d66382f380557b2cerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
31622c49e036c365df707cd8e6622d66382f380557b2cerion#  endif
31632c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregClass(*rHi) == HRcInt32);
31642c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregIsVirtual(*rHi));
31652c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregClass(*rLo) == HRcInt32);
31662c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(hregIsVirtual(*rLo));
31672c49e036c365df707cd8e6622d66382f380557b2cerion}
31682c49e036c365df707cd8e6622d66382f380557b2cerion
31692c49e036c365df707cd8e6622d66382f380557b2cerion/* DO NOT CALL THIS DIRECTLY ! */
31705b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerionstatic void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo,
31711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                ISelEnv* env, IRExpr* e,
31721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                IREndness IEndianess )
31732c49e036c365df707cd8e6622d66382f380557b2cerion{
31742c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(e);
31752c49e036c365df707cd8e6622d66382f380557b2cerion   vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
31762c49e036c365df707cd8e6622d66382f380557b2cerion
3177e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj   /* 64-bit load */
31781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
3179e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      HReg tLo    = newVRegI(env);
3180e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      HReg tHi    = newVRegI(env);
31811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg r_addr = iselWordExpr_R(env, e->Iex.Load.addr, IEndianess);
3182e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      vassert(!env->mode64);
3183e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      addInstr(env, PPCInstr_Load( 4/*byte-load*/,
3184e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   tHi, PPCAMode_IR( 0, r_addr ),
3185e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   False/*32-bit insn please*/) );
3186e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      addInstr(env, PPCInstr_Load( 4/*byte-load*/,
3187e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   tLo, PPCAMode_IR( 4, r_addr ),
3188e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                   False/*32-bit insn please*/) );
3189e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      *rHi = tHi;
3190e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      *rLo = tLo;
3191e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      return;
3192e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj   }
3193e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj
31944a49b0393204185f87664ea58f2b7a2ae1d37338cerion   /* 64-bit literal */
31954a49b0393204185f87664ea58f2b7a2ae1d37338cerion   if (e->tag == Iex_Const) {
31964a49b0393204185f87664ea58f2b7a2ae1d37338cerion      ULong w64 = e->Iex.Const.con->Ico.U64;
31974a49b0393204185f87664ea58f2b7a2ae1d37338cerion      UInt  wHi = ((UInt)(w64 >> 32)) & 0xFFFFFFFF;
31984a49b0393204185f87664ea58f2b7a2ae1d37338cerion      UInt  wLo = ((UInt)w64) & 0xFFFFFFFF;
31994a49b0393204185f87664ea58f2b7a2ae1d37338cerion      HReg  tLo = newVRegI(env);
32004a49b0393204185f87664ea58f2b7a2ae1d37338cerion      HReg  tHi = newVRegI(env);
32014a49b0393204185f87664ea58f2b7a2ae1d37338cerion      vassert(e->Iex.Const.con->tag == Ico_U64);
3202aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      addInstr(env, PPCInstr_LI(tHi, (Long)(Int)wHi, False/*mode32*/));
3203aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      addInstr(env, PPCInstr_LI(tLo, (Long)(Int)wLo, False/*mode32*/));
32044a49b0393204185f87664ea58f2b7a2ae1d37338cerion      *rHi = tHi;
32054a49b0393204185f87664ea58f2b7a2ae1d37338cerion      *rLo = tLo;
32064a49b0393204185f87664ea58f2b7a2ae1d37338cerion      return;
32074a49b0393204185f87664ea58f2b7a2ae1d37338cerion   }
32082c49e036c365df707cd8e6622d66382f380557b2cerion
32092c49e036c365df707cd8e6622d66382f380557b2cerion   /* read 64-bit IRTemp */
3210dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3211dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      lookupIRTempPair( rHi, rLo, env, e->Iex.RdTmp.tmp);
32122c49e036c365df707cd8e6622d66382f380557b2cerion      return;
32132c49e036c365df707cd8e6622d66382f380557b2cerion   }
32142c49e036c365df707cd8e6622d66382f380557b2cerion
321584ad616686a2c29be1c2b1f65f72ae79820a84c4cerion   /* 64-bit GET */
321684ad616686a2c29be1c2b1f65f72ae79820a84c4cerion   if (e->tag == Iex_Get) {
32175b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
32182bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                       GuestStatePtr(False/*mode32*/) );
32195b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr4 = advance4(env, am_addr);
322084ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      HReg tLo = newVRegI(env);
322184ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      HReg tHi = newVRegI(env);
32227fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj      addInstr(env, PPCInstr_Load( 4, tHi, am_addr,  False/*mode32*/ ));
32237fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj      addInstr(env, PPCInstr_Load( 4, tLo, am_addr4, False/*mode32*/ ));
322484ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      *rHi = tHi;
322584ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      *rLo = tLo;
322684ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      return;
322784ad616686a2c29be1c2b1f65f72ae79820a84c4cerion   }
32282c49e036c365df707cd8e6622d66382f380557b2cerion
322999dd03e04a6914d90d5fee727d61d76905334becflorian   /* 64-bit ITE */
323099dd03e04a6914d90d5fee727d61d76905334becflorian   if (e->tag == Iex_ITE) { // VFD
3231a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      HReg e0Lo, e0Hi, eXLo, eXHi;
32321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      iselInt64Expr(&eXHi, &eXLo, env, e->Iex.ITE.iftrue, IEndianess);
32331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      iselInt64Expr(&e0Hi, &e0Lo, env, e->Iex.ITE.iffalse, IEndianess);
3234a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      HReg tLo = newVRegI(env);
3235a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      HReg tHi = newVRegI(env);
323660733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, mk_iMOVds_RR(tHi,e0Hi));
323760733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, mk_iMOVds_RR(tLo,e0Lo));
32381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCCondCode cc = iselCondCode(env, e->Iex.ITE.cond, IEndianess);
323960733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, PPCInstr_CMov(cc,tHi,PPCRI_Reg(eXHi)));
324060733f8ba991e6af82b22a8d08ee91739925d240sewardj      addInstr(env, PPCInstr_CMov(cc,tLo,PPCRI_Reg(eXLo)));
3241a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      *rHi = tHi;
3242a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      *rLo = tLo;
3243a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj      return;
3244a9135fd7c3aabfb2e9f5dd51968e60d8fd02e135sewardj   }
32452c49e036c365df707cd8e6622d66382f380557b2cerion
32462c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- BINARY ops --------- */
32472c49e036c365df707cd8e6622d66382f380557b2cerion   if (e->tag == Iex_Binop) {
32485b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      IROp op_binop = e->Iex.Binop.op;
32495b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      switch (op_binop) {
32507c6dbff15934256b028a69e906cd3f80275c84absewardj         /* 32 x 32 -> 64 multiply */
32517c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_MullU32:
32527c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_MullS32: {
32537c6dbff15934256b028a69e906cd3f80275c84absewardj            HReg     tLo     = newVRegI(env);
32547c6dbff15934256b028a69e906cd3f80275c84absewardj            HReg     tHi     = newVRegI(env);
32557c6dbff15934256b028a69e906cd3f80275c84absewardj            Bool     syned   = toBool(op_binop == Iop_MullS32);
32561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1,
32571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IEndianess);
32581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     r_srcR  = iselWordExpr_R(env, e->Iex.Binop.arg2,
32591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                              IEndianess);
32607c6dbff15934256b028a69e906cd3f80275c84absewardj            addInstr(env, PPCInstr_MulL(False/*signedness irrelevant*/,
32617c6dbff15934256b028a69e906cd3f80275c84absewardj                                        False/*lo32*/, True/*32bit mul*/,
32627c6dbff15934256b028a69e906cd3f80275c84absewardj                                        tLo, r_srcL, r_srcR));
32637c6dbff15934256b028a69e906cd3f80275c84absewardj            addInstr(env, PPCInstr_MulL(syned,
32647c6dbff15934256b028a69e906cd3f80275c84absewardj                                        True/*hi32*/, True/*32bit mul*/,
32657c6dbff15934256b028a69e906cd3f80275c84absewardj                                        tHi, r_srcL, r_srcR));
32667c6dbff15934256b028a69e906cd3f80275c84absewardj            *rHi = tHi;
32677c6dbff15934256b028a69e906cd3f80275c84absewardj            *rLo = tLo;
32687c6dbff15934256b028a69e906cd3f80275c84absewardj            return;
32697c6dbff15934256b028a69e906cd3f80275c84absewardj         }
3270a21951955194861590440a464efb23f20ff30fc9sewardj
3271a21951955194861590440a464efb23f20ff30fc9sewardj         /* Or64/And64/Xor64 */
3272a21951955194861590440a464efb23f20ff30fc9sewardj         case Iop_Or64:
3273a21951955194861590440a464efb23f20ff30fc9sewardj         case Iop_And64:
3274a21951955194861590440a464efb23f20ff30fc9sewardj         case Iop_Xor64: {
3275a21951955194861590440a464efb23f20ff30fc9sewardj            HReg xLo, xHi, yLo, yHi;
3276a21951955194861590440a464efb23f20ff30fc9sewardj            HReg tLo = newVRegI(env);
3277a21951955194861590440a464efb23f20ff30fc9sewardj            HReg tHi = newVRegI(env);
32785b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            PPCAluOp op = (op_binop == Iop_Or64) ? Palu_OR :
32795b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                          (op_binop == Iop_And64) ? Palu_AND : Palu_XOR;
32801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1, IEndianess);
32811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2, IEndianess);
32825b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Alu(op, tHi, xHi, PPCRH_Reg(yHi)));
32835b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Alu(op, tLo, xLo, PPCRH_Reg(yLo)));
3284a21951955194861590440a464efb23f20ff30fc9sewardj            *rHi = tHi;
3285a21951955194861590440a464efb23f20ff30fc9sewardj            *rLo = tLo;
3286a21951955194861590440a464efb23f20ff30fc9sewardj            return;
3287a21951955194861590440a464efb23f20ff30fc9sewardj         }
3288a21951955194861590440a464efb23f20ff30fc9sewardj
3289478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         /* Add64 */
32904a49b0393204185f87664ea58f2b7a2ae1d37338cerion         case Iop_Add64: {
32914a49b0393204185f87664ea58f2b7a2ae1d37338cerion            HReg xLo, xHi, yLo, yHi;
32924a49b0393204185f87664ea58f2b7a2ae1d37338cerion            HReg tLo = newVRegI(env);
32934a49b0393204185f87664ea58f2b7a2ae1d37338cerion            HReg tHi = newVRegI(env);
32941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1, IEndianess);
32951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2, IEndianess);
32965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AddSubC( True/*add*/, True /*set carry*/,
32975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                            tLo, xLo, yLo));
32985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AddSubC( True/*add*/, False/*read carry*/,
32995b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                            tHi, xHi, yHi));
33004a49b0393204185f87664ea58f2b7a2ae1d37338cerion            *rHi = tHi;
33014a49b0393204185f87664ea58f2b7a2ae1d37338cerion            *rLo = tLo;
33024a49b0393204185f87664ea58f2b7a2ae1d37338cerion            return;
33034a49b0393204185f87664ea58f2b7a2ae1d37338cerion         }
3304ed623dbefb52ca3211490d656abc999a129df060cerion
3305ed623dbefb52ca3211490d656abc999a129df060cerion         /* 32HLto64(e1,e2) */
3306ed623dbefb52ca3211490d656abc999a129df060cerion         case Iop_32HLto64:
33071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
33081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
3309ed623dbefb52ca3211490d656abc999a129df060cerion            return;
3310ed623dbefb52ca3211490d656abc999a129df060cerion
33114aa412af1d8166cc11f39a6e721df49431d23618sewardj         /* F64toI64[S|U] */
33124aa412af1d8166cc11f39a6e721df49431d23618sewardj         case Iop_F64toI64S: case Iop_F64toI64U: {
3313c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      tLo     = newVRegI(env);
3314c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      tHi     = newVRegI(env);
3315c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      r1      = StackFramePtr(env->mode64);
3316c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
3317c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
33181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg      fsrc    = iselDblExpr(env, e->Iex.Binop.arg2,
33191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                            IEndianess);
3320c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg      ftmp    = newVRegF(env);
3321c74373da820d4004fbfab13e136b78bbf3618104sewardj
3322c74373da820d4004fbfab13e136b78bbf3618104sewardj            vassert(!env->mode64);
3323c74373da820d4004fbfab13e136b78bbf3618104sewardj            /* Set host rounding mode */
33241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
3325c74373da820d4004fbfab13e136b78bbf3618104sewardj
3326c74373da820d4004fbfab13e136b78bbf3618104sewardj            sub_from_sp( env, 16 );
33274aa412af1d8166cc11f39a6e721df49431d23618sewardj            addInstr(env, PPCInstr_FpCftI(False/*F->I*/, False/*int64*/,
33284aa412af1d8166cc11f39a6e721df49431d23618sewardj                                          (op_binop == Iop_F64toI64S) ? True : False,
332966d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj                                          True, ftmp, fsrc));
3330c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
3331c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3332c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3333c74373da820d4004fbfab13e136b78bbf3618104sewardj            add_to_sp( env, 16 );
3334c74373da820d4004fbfab13e136b78bbf3618104sewardj
3335b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
3336b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
3337c74373da820d4004fbfab13e136b78bbf3618104sewardj            *rHi = tHi;
3338c74373da820d4004fbfab13e136b78bbf3618104sewardj            *rLo = tLo;
3339c74373da820d4004fbfab13e136b78bbf3618104sewardj            return;
3340c74373da820d4004fbfab13e136b78bbf3618104sewardj         }
3341cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         case Iop_D64toI64S: {
3342cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg      tLo     = newVRegI(env);
3343cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg      tHi     = newVRegI(env);
3344cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg      r1      = StackFramePtr(env->mode64);
3345cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
3346cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
33471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
3348cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmp    = newVRegF(env);
3349c74373da820d4004fbfab13e136b78bbf3618104sewardj
3350cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            vassert(!env->mode64);
33511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
3352cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Dfp64Unary(Pfp_DCTFIX, tmp, fr_src));
3353cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3354cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            sub_from_sp( env, 16 );
3355cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
3356cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3357cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3358cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            add_to_sp( env, 16 );
3359cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rHi = tHi;
3360cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rLo = tLo;
3361cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            return;
3362cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
3363cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         case Iop_D128toI64S: {
3364cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCFpOp fpop = Pfp_DCTFIXQ;
3365cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg r_srcHi = newVRegF(env);
3366cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg r_srcLo = newVRegF(env);
3367cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tLo     = newVRegI(env);
3368cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tHi     = newVRegI(env);
3369cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg ftmp    = newVRegF(env);
3370cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3371cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
3372cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
33731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
33741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
33751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
3376cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_DfpD128toD64(fpop, ftmp, r_srcHi, r_srcLo));
3377cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3378cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the D64 result into an integer register pair
3379cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            sub_from_sp( env, 16 );
3380cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));
3381cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3382cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3383cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            add_to_sp( env, 16 );
3384cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rHi = tHi;
3385cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            *rLo = tLo;
3386cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            return;
3387cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
33887c6dbff15934256b028a69e906cd3f80275c84absewardj         default:
33897c6dbff15934256b028a69e906cd3f80275c84absewardj            break;
33902c49e036c365df707cd8e6622d66382f380557b2cerion      }
33912c49e036c365df707cd8e6622d66382f380557b2cerion   } /* if (e->tag == Iex_Binop) */
33922c49e036c365df707cd8e6622d66382f380557b2cerion
33932c49e036c365df707cd8e6622d66382f380557b2cerion
3394ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- UNARY ops --------- */
3395ed623dbefb52ca3211490d656abc999a129df060cerion   if (e->tag == Iex_Unop) {
3396ed623dbefb52ca3211490d656abc999a129df060cerion      switch (e->Iex.Unop.op) {
3397ed623dbefb52ca3211490d656abc999a129df060cerion
3398eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      /* CmpwNEZ64(e) */
3399eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      case Iop_CmpwNEZ64: {
3400eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg argHi, argLo;
3401eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg tmp1  = newVRegI(env);
3402eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         HReg tmp2  = newVRegI(env);
34031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&argHi, &argLo, env, e->Iex.Unop.arg, IEndianess);
3404eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         /* tmp1 = argHi | argLo */
3405eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, tmp1, argHi, PPCRH_Reg(argLo)));
3406eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         /* tmp2 = (tmp1 | -tmp1) >>s 31 */
3407eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Unary(Pun_NEG,tmp2,tmp1));
3408eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, tmp2, tmp2, PPCRH_Reg(tmp1)));
3409eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
3410eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                     tmp2, tmp2, PPCRH_Imm(False, 31)));
3411eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         *rHi = tmp2;
3412eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         *rLo = tmp2; /* yes, really tmp2 */
3413eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj         return;
3414eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj      }
3415eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj
3416478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      /* Left64 */
3417478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      case Iop_Left64: {
3418478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg argHi, argLo;
3419478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg zero32 = newVRegI(env);
3420478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg resHi  = newVRegI(env);
3421478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         HReg resLo  = newVRegI(env);
34221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&argHi, &argLo, env, e->Iex.Unop.arg, IEndianess);
3423478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         vassert(env->mode64 == False);
3424478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_LI(zero32, 0, env->mode64));
3425478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         /* resHi:resLo = - argHi:argLo */
3426478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_AddSubC( False/*sub*/, True/*set carry*/,
3427478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj                                         resLo, zero32, argLo ));
3428478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_AddSubC( False/*sub*/, False/*read carry*/,
3429478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj                                         resHi, zero32, argHi ));
3430478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         /* resHi:resLo |= srcHi:srcLo */
3431478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, resLo, resLo, PPCRH_Reg(argLo)));
3432478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         addInstr(env, PPCInstr_Alu(Palu_OR, resHi, resHi, PPCRH_Reg(argHi)));
3433478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         *rHi = resHi;
3434478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         *rLo = resLo;
3435478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj         return;
3436478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj      }
3437478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj
3438f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* 32Sto64(e) */
3439f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_32Sto64: {
3440f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
34411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
34425b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
34435b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tHi, src, PPCRH_Imm(False,31)));
3444f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3445f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = src;
3446f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3447f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3448cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_ExtractExpD64: {
3449cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg tmp    = newVRegF(env);
34501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
3451cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tLo     = newVRegI(env);
3452cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tHi     = newVRegI(env);
3453cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3454cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
3455cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3456cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DXEX, tmp, fr_src));
3457cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3458cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the D64 result into a integer register pair
3459cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
3460cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
3461cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3462cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3463cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
3464cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rHi = tHi;
3465cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rLo = tLo;
3466cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return;
3467cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
3468cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_ExtractExpD128: {
3469cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      r_srcHi;
3470cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      r_srcLo;
3471cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tmp     = newVRegF(env);
3472cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tLo     = newVRegI(env);
3473cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg      tHi     = newVRegI(env);
3474cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3475cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
3476cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
34771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Unop.arg, IEndianess);
3478cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_ExtractExpD128(Pfp_DXEXQ, tmp,
3479cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                                  r_srcHi, r_srcLo));
3480cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
3481cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the D64 result into a integer register pair
3482cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
3483cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, tmp, zero_r1));
3484cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tHi, zero_r1, False/*mode32*/));
3485cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/));
3486cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
3487cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rHi = tHi;
3488cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         *rLo = tLo;
3489cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return;
3490cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      }
34916587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion
3492f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* 32Uto64(e) */
3493f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_32Uto64: {
3494f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
34951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg tLo = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
34962bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         addInstr(env, PPCInstr_LI(tHi, 0, False/*mode32*/));
3497f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3498f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3499f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3500f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
35016587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion
3502c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_128to64: {
3503c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         /* Narrow, return the low 64-bit half as a 32-bit
3504c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj          * register pair */
3505c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Hi    = INVALID_HREG;
3506c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedHi = INVALID_HREG;
3507c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedLo = INVALID_HREG;
3508c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Lo    = INVALID_HREG;
3509c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3510c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         iselInt128Expr_to_32x4(&r_Hi, &r_MedHi, &r_MedLo, &r_Lo,
35111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                env, e->Iex.Unop.arg, IEndianess);
3512c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_MedLo;
3513c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_Lo;
3514c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
3515c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
3516c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3517c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_128HIto64: {
3518c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         /* Narrow, return the high 64-bit half as a 32-bit
3519c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj          *  register pair */
3520c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Hi    = INVALID_HREG;
3521c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedHi = INVALID_HREG;
3522c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_MedLo = INVALID_HREG;
3523c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_Lo    = INVALID_HREG;
3524c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3525c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         iselInt128Expr_to_32x4(&r_Hi, &r_MedHi, &r_MedLo, &r_Lo,
35261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                env, e->Iex.Unop.arg, IEndianess);
3527c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_Hi;
3528c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_MedHi;
3529c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
3530c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
3531c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
3532f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* V128{HI}to64 */
3533f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_V128HIto64:
3534f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_V128to64: {
3535f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_aligned16;
3536f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         Int  off = e->Iex.Unop.op==Iop_V128HIto64 ? 0 : 8;
3537f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tLo = newVRegI(env);
3538f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
35391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg vec = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
35405b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode *am_off0, *am_offLO, *am_offHI;
3541f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         sub_from_sp( env, 32 );     // Move SP down 32 bytes
3542f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3543f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // get a quadword aligned address within our stack space
3544f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         r_aligned16 = get_sp_aligned16( env );
35455b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off0  = PPCAMode_IR( 0,     r_aligned16 );
35465b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_offHI = PPCAMode_IR( off,   r_aligned16 );
35475b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_offLO = PPCAMode_IR( off+4, r_aligned16 );
3548f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3549f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // store as Vec128
35505b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
35515b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 ));
3552f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3553f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // load hi,lo words (of hi/lo half of vec) as Ity_I32's
35545b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
35557fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                  PPCInstr_Load( 4, tHi, am_offHI, False/*mode32*/ ));
35565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
35577fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                  PPCInstr_Load( 4, tLo, am_offLO, False/*mode32*/ ));
3558f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3559f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         add_to_sp( env, 32 );       // Reset SP
3560f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3561f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3562f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3563f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3564a21951955194861590440a464efb23f20ff30fc9sewardj
3565f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* could do better than this, but for now ... */
3566f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_1Sto64: {
3567f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tLo = newVRegI(env);
3568f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg tHi = newVRegI(env);
35691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cond = iselCondCode(env, e->Iex.Unop.arg, IEndianess);
35705b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Set(cond,tLo));
35715b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
35725b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, tLo, PPCRH_Imm(False,31)));
35735b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,
35745b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                     tLo, tLo, PPCRH_Imm(False,31)));
3575f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         addInstr(env, mk_iMOVds_RR(tHi, tLo));
3576f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = tHi;
3577f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = tLo;
3578f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3579f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
35801bee561912427ca8f8998c89b62d86ba2ee49732sewardj
3581d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj      case Iop_Not64: {
3582d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         HReg xLo, xHi;
3583d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         HReg tmpLo = newVRegI(env);
3584d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         HReg tmpHi = newVRegI(env);
35851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&xHi, &xLo, env, e->Iex.Unop.arg, IEndianess);
3586d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         addInstr(env, PPCInstr_Unary(Pun_NOT,tmpLo,xLo));
3587d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         addInstr(env, PPCInstr_Unary(Pun_NOT,tmpHi,xHi));
3588d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         *rHi = tmpHi;
3589d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         *rLo = tmpLo;
3590d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj         return;
3591d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj      }
3592d34e44983f263a835622ba1e3f7f945ffa7553cdsewardj
3593f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* ReinterpF64asI64(e) */
3594f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      /* Given an IEEE754 double, produce an I64 with the same bit
3595f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         pattern. */
3596f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Iop_ReinterpF64asI64: {
35975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode *am_addr0, *am_addr1;
35981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src  = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
3599f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_dstLo = newVRegI(env);
3600f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_dstHi = newVRegI(env);
3601f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3602f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         sub_from_sp( env, 16 );     // Move SP down 16 bytes
36032bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         am_addr0 = PPCAMode_IR( 0, StackFramePtr(False/*mode32*/) );
36042bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         am_addr1 = PPCAMode_IR( 4, StackFramePtr(False/*mode32*/) );
3605f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3606f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // store as F64
36075b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
36085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                        fr_src, am_addr0 ));
3609f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3610f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         // load hi,lo as Ity_I32's
36117fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         addInstr(env, PPCInstr_Load( 4, r_dstHi,
36122bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                      am_addr0, False/*mode32*/ ));
36137fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         addInstr(env, PPCInstr_Load( 4, r_dstLo,
36142bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj                                      am_addr1, False/*mode32*/ ));
3615f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rHi = r_dstHi;
3616f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         *rLo = r_dstLo;
3617f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
3618f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         add_to_sp( env, 16 );       // Reset SP
3619f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return;
3620f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3621094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
36225eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      case Iop_ReinterpD64asI64: {
36231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src  = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
36244c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCAMode *am_addr0, *am_addr1;
36254c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg r_dstLo = newVRegI(env);
36264c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg r_dstHi = newVRegI(env);
36275eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36285eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36295eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         sub_from_sp( env, 16 );     // Move SP down 16 bytes
36305eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         am_addr0 = PPCAMode_IR( 0, StackFramePtr(False/*mode32*/) );
36315eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         am_addr1 = PPCAMode_IR( 4, StackFramePtr(False/*mode32*/) );
36325eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36335eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         // store as D64
36345eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
36355eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                        fr_src, am_addr0 ));
36364c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36375eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         // load hi,lo as Ity_I32's
36385eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         addInstr(env, PPCInstr_Load( 4, r_dstHi,
36395eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                      am_addr0, False/*mode32*/ ));
36405eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         addInstr(env, PPCInstr_Load( 4, r_dstLo,
36415eff1c502e995d1f9668cc9def72d5db59f21b13sewardj                                      am_addr1, False/*mode32*/ ));
36425eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         *rHi = r_dstHi;
36435eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         *rLo = r_dstLo;
36444c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36455eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         add_to_sp( env, 16 );       // Reset SP
36465eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36475eff1c502e995d1f9668cc9def72d5db59f21b13sewardj         return;
36485eff1c502e995d1f9668cc9def72d5db59f21b13sewardj      }
36495eff1c502e995d1f9668cc9def72d5db59f21b13sewardj
36504c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      case Iop_BCDtoDPB: {
36514c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCCondCode cc;
36524c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         UInt        argiregs;
36534c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        argregs[2];
36544c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Int         argreg;
36554c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tLo = newVRegI(env);
36564c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tHi = newVRegI(env);
36574c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpHi;
36584c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpLo;
36594c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Bool        mode64 = env->mode64;
36604c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36614c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[0] = hregPPC_GPR3(mode64);
36624c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[1] = hregPPC_GPR4(mode64);
36634c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36644c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs = 0;
36654c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argreg = 0;
36664c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr( &tmpHi, &tmpLo, env, e->Iex.Unop.arg, IEndianess );
36684c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36694c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= ( 1 << (argreg+3 ) );
36704c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( argregs[argreg++], tmpHi ) );
36714c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36724c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= ( 1 << (argreg+3 ) );
36734c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( argregs[argreg], tmpLo ) );
36744c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36754c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
36764c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE) {
367893a09742b0de3d61718882c2d999f64be402564dflorian             addInstr( env, PPCInstr_Call( cc, (Addr)h_calc_BCDtoDPB,
36791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           argiregs,
36801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           mk_RetLoc_simple(RLPri_2Int) ) );
36811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         } else {
368293a09742b0de3d61718882c2d999f64be402564dflorian             Addr64 target;
368393a09742b0de3d61718882c2d999f64be402564dflorian             target = mode64 ? (Addr)h_calc_BCDtoDPB :
368493a09742b0de3d61718882c2d999f64be402564dflorian               toUInt( (Addr)h_calc_BCDtoDPB );
368593a09742b0de3d61718882c2d999f64be402564dflorian             addInstr( env, PPCInstr_Call( cc, target,
36861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           argiregs,
36871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                           mk_RetLoc_simple(RLPri_2Int) ) );
36881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         }
36891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
36904c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( tHi, argregs[argreg-1] ) );
36914c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr( env, mk_iMOVds_RR( tLo, argregs[argreg] ) );
36924c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36934c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rHi = tHi;
36944c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rLo = tLo;
36954c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         return;
36964c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      }
36974c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
36984c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      case Iop_DPBtoBCD: {
36994c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         PPCCondCode cc;
37004c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         UInt        argiregs;
37014c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        argregs[2];
37024c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Int         argreg;
37034c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tLo = newVRegI(env);
37044c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tHi = newVRegI(env);
37054c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpHi;
37064c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         HReg        tmpLo;
37074c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         Bool        mode64 = env->mode64;
37084c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37094c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[0] = hregPPC_GPR3(mode64);
37104c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argregs[1] = hregPPC_GPR4(mode64);
37114c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37124c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs = 0;
37134c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argreg = 0;
37144c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Unop.arg, IEndianess);
37164c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37174c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= (1 << (argreg+3));
37184c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR( argregs[argreg++], tmpHi ));
37194c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37204c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         argiregs |= (1 << (argreg+3));
37214c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR( argregs[argreg], tmpLo));
37224c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37234c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
37244c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE) {
372693a09742b0de3d61718882c2d999f64be402564dflorian             addInstr(env, PPCInstr_Call( cc, (Addr)h_calc_DPBtoBCD,
37271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          argiregs,
37281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          mk_RetLoc_simple(RLPri_2Int) ) );
37291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         } else {
373093a09742b0de3d61718882c2d999f64be402564dflorian             Addr64 target;
373193a09742b0de3d61718882c2d999f64be402564dflorian             target = mode64 ? (Addr)h_calc_DPBtoBCD :
373293a09742b0de3d61718882c2d999f64be402564dflorian               toUInt( (Addr)h_calc_DPBtoBCD );
373393a09742b0de3d61718882c2d999f64be402564dflorian             addInstr(env, PPCInstr_Call( cc, target, argiregs,
37341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                          mk_RetLoc_simple(RLPri_2Int) ) );
37351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         }
37364c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37374c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR(tHi, argregs[argreg-1]));
37384c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         addInstr(env, mk_iMOVds_RR(tLo, argregs[argreg]));
37394c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
37404c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rHi = tHi;
37414c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         *rLo = tLo;
37424c96e61dd85c172b999d6afc88ce6640aeba9962sewardj         return;
37434c96e61dd85c172b999d6afc88ce6640aeba9962sewardj      }
37444c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
3745f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      default:
3746f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         break;
3747ed623dbefb52ca3211490d656abc999a129df060cerion      }
3748ed623dbefb52ca3211490d656abc999a129df060cerion   } /* if (e->tag == Iex_Unop) */
3749ed623dbefb52ca3211490d656abc999a129df060cerion
37505b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselInt64Expr(ppc): No such tag(%u)\n", e->tag);
37512c49e036c365df707cd8e6622d66382f380557b2cerion   ppIRExpr(e);
37525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselInt64Expr(ppc)");
37532c49e036c365df707cd8e6622d66382f380557b2cerion}
3754cd304497d9d869f9b24a002299d3953ee072229bcerion
3755b536af93912b69421440c27aa0533ad77d678f85cerion
3756094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3757094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*--- ISEL: Floating point expressions (32 bit)         ---*/
3758094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3759094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3760094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* Nothing interesting here; really just wrappers for
3761094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   64-bit stuff. */
3762094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
37631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselFltExpr ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3764094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
37651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll  HReg r = iselFltExpr_wrk( env, e, IEndianess );
3766094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  if 0
3767094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3768094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  endif
3769094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregClass(r) == HRcFlt64); /* yes, really Flt64 */
3770094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregIsVirtual(r));
3771094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   return r;
3772094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
3773094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3774094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* DO NOT CALL THIS DIRECTLY */
37751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselFltExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3776094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
37777d810d793616af057ce861746aa985df3304cb86sewardj   Bool        mode64 = env->mode64;
37787d810d793616af057ce861746aa985df3304cb86sewardj
3779094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
3780094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(ty == Ity_F32);
3781094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3782dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3783dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
3784094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3785094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
37861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
37875b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr;
3788094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
3789af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj      vassert(e->Iex.Load.ty == Ity_F32);
37901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_F32/*xfer*/,
37911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
37925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, r_dst, am_addr));
3793094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
3794094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3795094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3796094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Get) {
3797094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
37985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
37994628ccd1bafb946378f91849b92ffcfea0267b2ecerion                                       GuestStatePtr(env->mode64) );
38005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt( True/*load*/, 4, r_dst, am_addr ));
3801094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
3802094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3803094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3804b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_TruncF64asF32) {
3805b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      /* This is quite subtle.  The only way to do the relevant
3806b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         truncation is to do a single-precision store and then a
3807b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         double precision load to get it back into a register.  The
3808b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         problem is, if the data is then written to memory a second
3809b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         time, as in
3810b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3811b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            STbe(...) = TruncF64asF32(...)
3812b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3813b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         then will the second truncation further alter the value?  The
3814b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         answer is no: flds (as generated here) followed by fsts
3815b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         (generated for the STbe) is the identity function on 32-bit
3816b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         floats, so we are safe.
3817b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3818b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         Another upshot of this is that if iselStmt can see the
3819b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         entirety of
3820b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3821b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            STbe(...) = TruncF64asF32(arg)
3822b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3823b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         then it can short circuit having to deal with TruncF64asF32
3824b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         individually; instead just compute arg into a 64-bit FP
3825b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         register and do 'fsts' (since that itself does the
3826b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         truncation).
3827b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3828b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         We generate pretty poor code here (should be ok both for
3829b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         32-bit and 64-bit mode); but it is expected that for the most
3830b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         part the latter optimisation will apply and hence this code
3831b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         will not often be used.
3832b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      */
38331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      HReg      fsrc    = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
3834b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      HReg      fdst    = newVRegF(env);
3835b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
3836b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
3837b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      sub_from_sp( env, 16 );
3838b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      // store as F32, hence truncating
3839b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      addInstr(env, PPCInstr_FpLdSt( False/*store*/, 4,
3840b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                                     fsrc, zero_r1 ));
3841b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      // and reload.  Good huh?! (sigh)
3842b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      addInstr(env, PPCInstr_FpLdSt( True/*load*/, 4,
3843b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                                     fdst, zero_r1 ));
3844b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      add_to_sp( env, 16 );
3845b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      return fdst;
3846b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   }
3847b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
38487d810d793616af057ce861746aa985df3304cb86sewardj   if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_I64UtoF32) {
38497d810d793616af057ce861746aa985df3304cb86sewardj      if (mode64) {
38507d810d793616af057ce861746aa985df3304cb86sewardj         HReg fdst = newVRegF(env);
38511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg isrc = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
38527d810d793616af057ce861746aa985df3304cb86sewardj         HReg r1   = StackFramePtr(env->mode64);
38537d810d793616af057ce861746aa985df3304cb86sewardj         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
38547d810d793616af057ce861746aa985df3304cb86sewardj
38557d810d793616af057ce861746aa985df3304cb86sewardj         /* Set host rounding mode */
38561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
38577d810d793616af057ce861746aa985df3304cb86sewardj
38587d810d793616af057ce861746aa985df3304cb86sewardj         sub_from_sp( env, 16 );
38597d810d793616af057ce861746aa985df3304cb86sewardj
38607d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_Store(8, zero_r1, isrc, True/*mode64*/));
38617d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
38627d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
38637d810d793616af057ce861746aa985df3304cb86sewardj                                       False, False,
38647d810d793616af057ce861746aa985df3304cb86sewardj                                       fdst, fdst));
38657d810d793616af057ce861746aa985df3304cb86sewardj
38667d810d793616af057ce861746aa985df3304cb86sewardj         add_to_sp( env, 16 );
38677d810d793616af057ce861746aa985df3304cb86sewardj
38687d810d793616af057ce861746aa985df3304cb86sewardj         ///* Restore default FPU rounding. */
38697d810d793616af057ce861746aa985df3304cb86sewardj         //set_FPU_rounding_default( env );
38707d810d793616af057ce861746aa985df3304cb86sewardj         return fdst;
38717d810d793616af057ce861746aa985df3304cb86sewardj      } else {
38727d810d793616af057ce861746aa985df3304cb86sewardj         /* 32-bit mode */
38737d810d793616af057ce861746aa985df3304cb86sewardj         HReg fdst = newVRegF(env);
38747d810d793616af057ce861746aa985df3304cb86sewardj         HReg isrcHi, isrcLo;
38757d810d793616af057ce861746aa985df3304cb86sewardj         HReg r1   = StackFramePtr(env->mode64);
38767d810d793616af057ce861746aa985df3304cb86sewardj         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
38777d810d793616af057ce861746aa985df3304cb86sewardj         PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
38787d810d793616af057ce861746aa985df3304cb86sewardj
38791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&isrcHi, &isrcLo, env, e->Iex.Binop.arg2, IEndianess);
38807d810d793616af057ce861746aa985df3304cb86sewardj
38817d810d793616af057ce861746aa985df3304cb86sewardj         /* Set host rounding mode */
38821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
38837d810d793616af057ce861746aa985df3304cb86sewardj
38847d810d793616af057ce861746aa985df3304cb86sewardj         sub_from_sp( env, 16 );
38857d810d793616af057ce861746aa985df3304cb86sewardj
38867d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_Store(4, zero_r1, isrcHi, False/*mode32*/));
38877d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_Store(4, four_r1, isrcLo, False/*mode32*/));
38887d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
38897d810d793616af057ce861746aa985df3304cb86sewardj         addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
38907d810d793616af057ce861746aa985df3304cb86sewardj                                       False, False,
38917d810d793616af057ce861746aa985df3304cb86sewardj                                       fdst, fdst));
38927d810d793616af057ce861746aa985df3304cb86sewardj
38937d810d793616af057ce861746aa985df3304cb86sewardj         add_to_sp( env, 16 );
38947d810d793616af057ce861746aa985df3304cb86sewardj
38957d810d793616af057ce861746aa985df3304cb86sewardj         ///* Restore default FPU rounding. */
38967d810d793616af057ce861746aa985df3304cb86sewardj         //set_FPU_rounding_default( env );
38977d810d793616af057ce861746aa985df3304cb86sewardj         return fdst;
38987d810d793616af057ce861746aa985df3304cb86sewardj      }
38997d810d793616af057ce861746aa985df3304cb86sewardj
39007d810d793616af057ce861746aa985df3304cb86sewardj   }
39017d810d793616af057ce861746aa985df3304cb86sewardj
39025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselFltExpr(ppc): No such tag(%u)\n", e->tag);
3903094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   ppIRExpr(e);
39045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselFltExpr_wrk(ppc)");
3905094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
3906094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3907094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3908094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3909094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*--- ISEL: Floating point expressions (64 bit)         ---*/
3910094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/*---------------------------------------------------------*/
3911094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3912094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* Compute a 64-bit floating point value into a register, the identity
3913094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   of which is returned.  As with iselIntExpr_R, the reg may be either
3914094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   real or virtual; in any case it must not be changed by subsequent
3915094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   code emitted by the caller.  */
3916094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3917094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* IEEE 754 formats.  From http://www.freesoft.org/CIE/RFC/1832/32.htm:
3918094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3919094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    Type                  S (1 bit)   E (11 bits)   F (52 bits)
3920094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    ----                  ---------   -----------   -----------
3921094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    signalling NaN        u           2047 (max)    .0uuuuu---u
3922094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion                                                    (with at least
3923094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion                                                     one 1 bit)
3924094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    quiet NaN             u           2047 (max)    .1uuuuu---u
3925094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3926094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    negative infinity     1           2047 (max)    .000000---0
3927094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3928094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    positive infinity     0           2047 (max)    .000000---0
3929094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3930094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    negative zero         1           0             .000000---0
3931094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3932094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion    positive zero         0           0             .000000---0
3933094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion*/
3934094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
39351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDblExpr ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3936094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
39371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselDblExpr_wrk( env, e, IEndianess );
3938094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  if 0
3939094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
3940094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion#  endif
3941094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregClass(r) == HRcFlt64);
3942094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(hregIsVirtual(r));
3943094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   return r;
3944094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
3945094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3946094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion/* DO NOT CALL THIS DIRECTLY */
39471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
3948094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion{
39494628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
3950094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   IRType ty = typeOfIRExpr(env->type_env,e);
3951094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(e);
3952094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   vassert(ty == Ity_F64);
3953094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3954dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
3955dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
3956094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3957094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3958094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   /* --------- LITERAL --------- */
3959094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Const) {
3960094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      union { UInt u32x2[2]; ULong u64; Double f64; } u;
3961094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u) == 8);
3962094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u.u64) == 8);
3963094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u.f64) == 8);
3964094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      vassert(sizeof(u.u32x2) == 8);
3965094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
3966094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (e->Iex.Const.con->tag == Ico_F64) {
3967094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         u.f64 = e->Iex.Const.con->Ico.F64;
3968094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
3969094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      else if (e->Iex.Const.con->tag == Ico_F64i) {
3970094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         u.u64 = e->Iex.Const.con->Ico.F64i;
3971094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
3972094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      else
39735b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         vpanic("iselDblExpr(ppc): const");
3974094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
397507b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      if (!mode64) {
3976f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_srcHi = newVRegI(env);
3977f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         HReg r_srcLo = newVRegI(env);
39787bbac2199faa35fa0f40be6bafe701407940c240sewardj         addInstr(env, PPCInstr_LI(r_srcHi, u.u32x2[0], mode64));
39797bbac2199faa35fa0f40be6bafe701407940c240sewardj         addInstr(env, PPCInstr_LI(r_srcLo, u.u32x2[1], mode64));
3980f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         return mk_LoadRR32toFPR( env, r_srcHi, r_srcLo );
398107b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      } else { // mode64
398207b07a966a2fdbcf621251a0c1a8ab84807fb120cerion         HReg r_src = newVRegI(env);
39835b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_LI(r_src, u.u64, mode64));
398407b07a966a2fdbcf621251a0c1a8ab84807fb120cerion         return mk_LoadR64toFPR( env, r_src );         // 1*I64 -> F64
3985f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      }
3986094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3987094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
398840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   /* --------- LOAD --------- */
39891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
3990094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
39915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr;
3992af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj      vassert(e->Iex.Load.ty == Ity_F64);
39931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_F64/*xfer*/,
39941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
39955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dst, am_addr));
3996094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
3997094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
3998094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
399940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   /* --------- GET --------- */
4000094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Get) {
4001094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      HReg r_dst = newVRegF(env);
40025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
40035b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                       GuestStatePtr(mode64) );
40045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      addInstr(env, PPCInstr_FpLdSt( True/*load*/, 8, r_dst, am_addr ));
4005094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      return r_dst;
4006094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4007cd304497d9d869f9b24a002299d3953ee072229bcerion
400840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   /* --------- OPS --------- */
400940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   if (e->tag == Iex_Qop) {
401040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      PPCFpOp fpop = Pfp_INVALID;
401196d7cc3e7d54ad5af2af2821223b21f9a8516a59florian      switch (e->Iex.Qop.details->op) {
401240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MAddF64:    fpop = Pfp_MADDD; break;
401340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MAddF64r32: fpop = Pfp_MADDS; break;
401440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MSubF64:    fpop = Pfp_MSUBD; break;
401540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         case Iop_MSubF64r32: fpop = Pfp_MSUBS; break;
401640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         default: break;
401740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      }
401840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      if (fpop != Pfp_INVALID) {
401940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         HReg r_dst  = newVRegF(env);
40201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcML  = iselDblExpr(env, e->Iex.Qop.details->arg2,
40211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess);
40221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcMR  = iselDblExpr(env, e->Iex.Qop.details->arg3,
40231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess);
40241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcAcc = iselDblExpr(env, e->Iex.Qop.details->arg4,
40251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                     IEndianess);
40261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Qop.details->arg1, IEndianess );
402740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         addInstr(env, PPCInstr_FpMulAcc(fpop, r_dst,
402840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj                                               r_srcML, r_srcMR, r_srcAcc));
402940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj         return r_dst;
403040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj      }
403140c802659108a96bb87cbc1a30b7b77e2abd0829sewardj   }
403240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj
4033b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (e->tag == Iex_Triop) {
4034420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      IRTriop *triop = e->Iex.Triop.details;
40355b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCFpOp fpop = Pfp_INVALID;
4036420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4037b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_AddF64:    fpop = Pfp_ADDD; break;
4038b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_SubF64:    fpop = Pfp_SUBD; break;
4039b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_MulF64:    fpop = Pfp_MULD; break;
4040b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_DivF64:    fpop = Pfp_DIVD; break;
4041b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_AddF64r32: fpop = Pfp_ADDS; break;
4042b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_SubF64r32: fpop = Pfp_SUBS; break;
4043b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_MulF64r32: fpop = Pfp_MULS; break;
4044b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         case Iop_DivF64r32: fpop = Pfp_DIVS; break;
4045b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         default: break;
4046094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4047094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (fpop != Pfp_INVALID) {
4048094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg r_dst  = newVRegF(env);
40491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselDblExpr(env, triop->arg2, IEndianess);
40501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDblExpr(env, triop->arg3, IEndianess);
40511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, triop->arg1, IEndianess );
40525b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpBinary(fpop, r_dst, r_srcL, r_srcR));
4053094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return r_dst;
4054094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4055b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   }
4056b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
4057b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj   if (e->tag == Iex_Binop) {
40581a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      PPCFpOp fpop = Pfp_INVALID;
40591a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      switch (e->Iex.Binop.op) {
4060cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_SqrtF64:   fpop = Pfp_SQRT;   break;
4061cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
40621a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      }
4063cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_SQRT) {
40641a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj         HReg fr_dst = newVRegF(env);
40651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
40661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
40671a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj         addInstr(env, PPCInstr_FpUnary(fpop, fr_dst, fr_src));
40681a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj         return fr_dst;
40691a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj      }
40701a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj   }
40711a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj
40721a3bfac0c5ad23699755c41baa2e1de53a84dc16sewardj   if (e->tag == Iex_Binop) {
4073b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
4074b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      if (e->Iex.Binop.op == Iop_RoundF64toF32) {
4075b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         HReg r_dst = newVRegF(env);
40761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
40771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4078b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         addInstr(env, PPCInstr_FpRSP(r_dst, r_src));
4079b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         //set_FPU_rounding_default( env );
4080b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj         return r_dst;
4081b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj      }
408207b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
408395d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj      if (e->Iex.Binop.op == Iop_I64StoF64 || e->Iex.Binop.op == Iop_I64UtoF64) {
40847fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         if (mode64) {
40857fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg fdst = newVRegF(env);
40861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg isrc = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
40877fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            HReg r1   = StackFramePtr(env->mode64);
40887fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
408907b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
40907fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            /* Set host rounding mode */
40911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
409207b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
40937fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            sub_from_sp( env, 16 );
409407b07a966a2fdbcf621251a0c1a8ab84807fb120cerion
40957fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_Store(8, zero_r1, isrc, True/*mode64*/));
40967fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
40977fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
409895d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          e->Iex.Binop.op == Iop_I64StoF64,
409995d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          True/*fdst is 64 bit*/,
41007fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj                                          fdst, fdst));
41017fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
41027fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            add_to_sp( env, 16 );
41037fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj
4104b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
4105b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
41067fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj            return fdst;
4107c74373da820d4004fbfab13e136b78bbf3618104sewardj         } else {
4108c74373da820d4004fbfab13e136b78bbf3618104sewardj            /* 32-bit mode */
4109c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg fdst = newVRegF(env);
4110c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg isrcHi, isrcLo;
4111c74373da820d4004fbfab13e136b78bbf3618104sewardj            HReg r1   = StackFramePtr(env->mode64);
4112c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
4113c74373da820d4004fbfab13e136b78bbf3618104sewardj            PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
4114c74373da820d4004fbfab13e136b78bbf3618104sewardj
41151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&isrcHi, &isrcLo, env, e->Iex.Binop.arg2,
41161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4117c74373da820d4004fbfab13e136b78bbf3618104sewardj
4118c74373da820d4004fbfab13e136b78bbf3618104sewardj            /* Set host rounding mode */
41191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            set_FPU_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4120c74373da820d4004fbfab13e136b78bbf3618104sewardj
4121c74373da820d4004fbfab13e136b78bbf3618104sewardj            sub_from_sp( env, 16 );
4122c74373da820d4004fbfab13e136b78bbf3618104sewardj
4123c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Store(4, zero_r1, isrcHi, False/*mode32*/));
4124c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_Store(4, four_r1, isrcLo, False/*mode32*/));
4125c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
4126c74373da820d4004fbfab13e136b78bbf3618104sewardj            addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
412795d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          e->Iex.Binop.op == Iop_I64StoF64,
412895d6f3a3957232f97e6c680dd49de38cdeb9a1ffsewardj                                          True/*fdst is 64 bit*/,
4129c74373da820d4004fbfab13e136b78bbf3618104sewardj                                          fdst, fdst));
4130c74373da820d4004fbfab13e136b78bbf3618104sewardj
4131c74373da820d4004fbfab13e136b78bbf3618104sewardj            add_to_sp( env, 16 );
4132c74373da820d4004fbfab13e136b78bbf3618104sewardj
4133b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            ///* Restore default FPU rounding. */
4134b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            //set_FPU_rounding_default( env );
4135c74373da820d4004fbfab13e136b78bbf3618104sewardj            return fdst;
41367fd5bb0dd6e9b745f8f8452f15cebb3c628d0a22sewardj         }
413707b07a966a2fdbcf621251a0c1a8ab84807fb120cerion      }
4138b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
4139094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4140094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4141094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Unop) {
41425b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      PPCFpOp fpop = Pfp_INVALID;
4143094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      switch (e->Iex.Unop.op) {
4144baf971ad7f6e005109f3301ec9d19c98066b3840sewardj         case Iop_NegF64:     fpop = Pfp_NEG; break;
4145baf971ad7f6e005109f3301ec9d19c98066b3840sewardj         case Iop_AbsF64:     fpop = Pfp_ABS; break;
41461ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj         case Iop_RSqrtEst5GoodF64:      fpop = Pfp_RSQRTE; break;
41470f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_NegINF:  fpop = Pfp_FRIM; break;
41480f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_PosINF:  fpop = Pfp_FRIP; break;
41490f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_NEAREST: fpop = Pfp_FRIN; break;
41500f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj         case Iop_RoundF64toF64_ZERO:    fpop = Pfp_FRIZ; break;
4151094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         default: break;
4152094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4153094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (fpop != Pfp_INVALID) {
4154094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg fr_dst = newVRegF(env);
41551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, e->Iex.Unop.arg, IEndianess);
41565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpUnary(fpop, fr_dst, fr_src));
4157094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return fr_dst;
4158094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4159094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4160094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4161094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   if (e->tag == Iex_Unop) {
4162094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      switch (e->Iex.Unop.op) {
41637c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_ReinterpI64asF64: {
41647c6dbff15934256b028a69e906cd3f80275c84absewardj            /* Given an I64, produce an IEEE754 double with the same
41657c6dbff15934256b028a69e906cd3f80275c84absewardj               bit pattern. */
41667c6dbff15934256b028a69e906cd3f80275c84absewardj            if (!mode64) {
41677c6dbff15934256b028a69e906cd3f80275c84absewardj               HReg r_srcHi, r_srcLo;
41681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               iselInt64Expr( &r_srcHi, &r_srcLo, env, e->Iex.Unop.arg,
41691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                               IEndianess);
41707c6dbff15934256b028a69e906cd3f80275c84absewardj               return mk_LoadRR32toFPR( env, r_srcHi, r_srcLo );
41717c6dbff15934256b028a69e906cd3f80275c84absewardj            } else {
41721f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
41737c6dbff15934256b028a69e906cd3f80275c84absewardj               return mk_LoadR64toFPR( env, r_src );
41747c6dbff15934256b028a69e906cd3f80275c84absewardj            }
4175094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         }
41764aa412af1d8166cc11f39a6e721df49431d23618sewardj
41777c6dbff15934256b028a69e906cd3f80275c84absewardj         case Iop_F32toF64: {
41784aa412af1d8166cc11f39a6e721df49431d23618sewardj            if (e->Iex.Unop.arg->tag == Iex_Unop &&
41794aa412af1d8166cc11f39a6e721df49431d23618sewardj                     e->Iex.Unop.arg->Iex.Unop.op == Iop_ReinterpI32asF32 ) {
41804aa412af1d8166cc11f39a6e721df49431d23618sewardj               e = e->Iex.Unop.arg;
41814aa412af1d8166cc11f39a6e721df49431d23618sewardj
41821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               HReg src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
41834aa412af1d8166cc11f39a6e721df49431d23618sewardj               HReg fr_dst = newVRegF(env);
41844aa412af1d8166cc11f39a6e721df49431d23618sewardj               PPCAMode *am_addr;
41854aa412af1d8166cc11f39a6e721df49431d23618sewardj
41864aa412af1d8166cc11f39a6e721df49431d23618sewardj               sub_from_sp( env, 16 );        // Move SP down 16 bytes
41874aa412af1d8166cc11f39a6e721df49431d23618sewardj               am_addr = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
41884aa412af1d8166cc11f39a6e721df49431d23618sewardj
41894aa412af1d8166cc11f39a6e721df49431d23618sewardj               // store src as Ity_I32's
41904aa412af1d8166cc11f39a6e721df49431d23618sewardj               addInstr(env, PPCInstr_Store( 4, am_addr, src, env->mode64 ));
41914aa412af1d8166cc11f39a6e721df49431d23618sewardj
41924aa412af1d8166cc11f39a6e721df49431d23618sewardj               // load single precision float, but the end results loads into a
41934aa412af1d8166cc11f39a6e721df49431d23618sewardj               // 64-bit FP register -- i.e., F64.
41944aa412af1d8166cc11f39a6e721df49431d23618sewardj               addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, fr_dst, am_addr));
41954aa412af1d8166cc11f39a6e721df49431d23618sewardj
41964aa412af1d8166cc11f39a6e721df49431d23618sewardj               add_to_sp( env, 16 );          // Reset SP
41974aa412af1d8166cc11f39a6e721df49431d23618sewardj               return fr_dst;
41984aa412af1d8166cc11f39a6e721df49431d23618sewardj            }
41994aa412af1d8166cc11f39a6e721df49431d23618sewardj
42004aa412af1d8166cc11f39a6e721df49431d23618sewardj
42017c6dbff15934256b028a69e906cd3f80275c84absewardj            /* this is a no-op */
42021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg res = iselFltExpr(env, e->Iex.Unop.arg, IEndianess);
42037c6dbff15934256b028a69e906cd3f80275c84absewardj            return res;
42047c6dbff15934256b028a69e906cd3f80275c84absewardj         }
42057c6dbff15934256b028a69e906cd3f80275c84absewardj         default:
42067c6dbff15934256b028a69e906cd3f80275c84absewardj            break;
4207094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4208094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4209094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
4210094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   /* --------- MULTIPLEX --------- */
421199dd03e04a6914d90d5fee727d61d76905334becflorian   if (e->tag == Iex_ITE) { // VFD
4212094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (ty == Ity_F64
421399dd03e04a6914d90d5fee727d61d76905334becflorian          && typeOfIRExpr(env->type_env,e->Iex.ITE.cond) == Ity_I1) {
42141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr1    = iselDblExpr(env, e->Iex.ITE.iftrue, IEndianess);
42151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr0    = iselDblExpr(env, e->Iex.ITE.iffalse, IEndianess);
4216094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg fr_dst = newVRegF(env);
4217009230b9758291b594e60d7c0243a73d53e81854sewardj         addInstr(env, PPCInstr_FpUnary( Pfp_MOV, fr_dst, fr0 ));
42181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cc = iselCondCode(env, e->Iex.ITE.cond, IEndianess);
421999dd03e04a6914d90d5fee727d61d76905334becflorian         addInstr(env, PPCInstr_FpCMov( cc, fr_dst, fr1 ));
4220094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return fr_dst;
4221094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
4222094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   }
4223094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion
42245b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselDblExpr(ppc): No such tag(%u)\n", e->tag);
4225094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion   ppIRExpr(e);
42265b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselDblExpr_wrk(ppc)");
4227094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion}
4228cd304497d9d869f9b24a002299d3953ee072229bcerion
42291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp32Expr(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4230f704eb2bab3d06d983c850b0bcf243e178060f75carll{
42311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselDfp32Expr_wrk( env, e, IEndianess );
4232f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert(hregClass(r) == HRcFlt64);
4233f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert( hregIsVirtual(r) );
4234f704eb2bab3d06d983c850b0bcf243e178060f75carll   return r;
4235f704eb2bab3d06d983c850b0bcf243e178060f75carll}
4236f704eb2bab3d06d983c850b0bcf243e178060f75carll
4237f704eb2bab3d06d983c850b0bcf243e178060f75carll/* DO NOT CALL THIS DIRECTLY */
42381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp32Expr_wrk(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4239f704eb2bab3d06d983c850b0bcf243e178060f75carll{
4240f704eb2bab3d06d983c850b0bcf243e178060f75carll   Bool mode64 = env->mode64;
4241f704eb2bab3d06d983c850b0bcf243e178060f75carll   IRType ty = typeOfIRExpr( env->type_env, e );
4242f704eb2bab3d06d983c850b0bcf243e178060f75carll
4243f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert( e );
4244f704eb2bab3d06d983c850b0bcf243e178060f75carll   vassert( ty == Ity_D32 );
4245f704eb2bab3d06d983c850b0bcf243e178060f75carll
4246f704eb2bab3d06d983c850b0bcf243e178060f75carll   /* --------- GET --------- */
4247f704eb2bab3d06d983c850b0bcf243e178060f75carll   if (e->tag == Iex_Get) {
4248f704eb2bab3d06d983c850b0bcf243e178060f75carll      HReg r_dst = newVRegF( env );
4249f704eb2bab3d06d983c850b0bcf243e178060f75carll      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
4250f704eb2bab3d06d983c850b0bcf243e178060f75carll                                       GuestStatePtr(mode64) );
4251f704eb2bab3d06d983c850b0bcf243e178060f75carll      addInstr( env, PPCInstr_FpLdSt( True/*load*/, 8, r_dst, am_addr ) );
4252f704eb2bab3d06d983c850b0bcf243e178060f75carll      return r_dst;
4253f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4254f704eb2bab3d06d983c850b0bcf243e178060f75carll
4255f704eb2bab3d06d983c850b0bcf243e178060f75carll   /* --------- LOAD --------- */
42561f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
4257f704eb2bab3d06d983c850b0bcf243e178060f75carll      PPCAMode* am_addr;
4258f704eb2bab3d06d983c850b0bcf243e178060f75carll      HReg r_dst = newVRegF(env);
4259f704eb2bab3d06d983c850b0bcf243e178060f75carll      vassert(e->Iex.Load.ty == Ity_D32);
42601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_D32/*xfer*/,
42611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
4262f704eb2bab3d06d983c850b0bcf243e178060f75carll      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, r_dst, am_addr));
4263f704eb2bab3d06d983c850b0bcf243e178060f75carll      return r_dst;
4264f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4265f704eb2bab3d06d983c850b0bcf243e178060f75carll
4266f704eb2bab3d06d983c850b0bcf243e178060f75carll   /* --------- OPS --------- */
4267f704eb2bab3d06d983c850b0bcf243e178060f75carll   if (e->tag == Iex_Binop) {
4268f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (e->Iex.Binop.op == Iop_D64toD32) {
4269f704eb2bab3d06d983c850b0bcf243e178060f75carll         HReg fr_dst = newVRegF(env);
42701f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
42711f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4272f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DRSP, fr_dst, fr_src));
4273f704eb2bab3d06d983c850b0bcf243e178060f75carll         return fr_dst;
4274f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
4275f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4276f704eb2bab3d06d983c850b0bcf243e178060f75carll
4277f704eb2bab3d06d983c850b0bcf243e178060f75carll   ppIRExpr( e );
4278f704eb2bab3d06d983c850b0bcf243e178060f75carll   vpanic( "iselDfp32Expr_wrk(ppc)" );
4279f704eb2bab3d06d983c850b0bcf243e178060f75carll}
4280f704eb2bab3d06d983c850b0bcf243e178060f75carll
42811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp64Expr(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4282c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
42831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselDfp64Expr_wrk( env, e, IEndianess );
4284c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert(hregClass(r) == HRcFlt64);
4285c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( hregIsVirtual(r) );
4286c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   return r;
4287c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4288c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4289c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* DO NOT CALL THIS DIRECTLY */
42901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselDfp64Expr_wrk(ISelEnv* env, IRExpr* e, IREndness IEndianess)
4291c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
4292c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   Bool mode64 = env->mode64;
4293c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   IRType ty = typeOfIRExpr( env->type_env, e );
4294c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   HReg r_dstHi, r_dstLo;
4295c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4296c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( e );
4297c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( ty == Ity_D64 );
4298c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4299c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_RdTmp) {
4300c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return lookupIRTemp( env, e->Iex.RdTmp.tmp );
4301c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4302c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4303c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* --------- GET --------- */
4304c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Get) {
4305c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_dst = newVRegF( env );
4306c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset,
4307c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                       GuestStatePtr(mode64) );
4308c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      addInstr( env, PPCInstr_FpLdSt( True/*load*/, 8, r_dst, am_addr ) );
4309c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return r_dst;
4310c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4311c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
43121f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
4313f704eb2bab3d06d983c850b0bcf243e178060f75carll      PPCAMode* am_addr;
4314f704eb2bab3d06d983c850b0bcf243e178060f75carll      HReg r_dst = newVRegF(env);
4315f704eb2bab3d06d983c850b0bcf243e178060f75carll      vassert(e->Iex.Load.ty == Ity_D64);
43161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, Ity_D64/*xfer*/,
43171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                   IEndianess);
4318f704eb2bab3d06d983c850b0bcf243e178060f75carll      addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dst, am_addr));
4319f704eb2bab3d06d983c850b0bcf243e178060f75carll      return r_dst;
4320f704eb2bab3d06d983c850b0bcf243e178060f75carll   }
4321f704eb2bab3d06d983c850b0bcf243e178060f75carll
4322c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* --------- OPS --------- */
4323c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Qop) {
4324c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_dst = newVRegF( env );
4325c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return r_dst;
4326c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4327c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4328c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Unop) {
4329cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      HReg fr_dst = newVRegF(env);
4330cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      switch (e->Iex.Unop.op) {
4331cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_ReinterpI64asD64: {
4332cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         /* Given an I64, produce an IEEE754 DFP with the same
4333cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj               bit pattern. */
4334cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         if (!mode64) {
4335cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            HReg r_srcHi, r_srcLo;
43361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr( &r_srcHi, &r_srcLo, env, e->Iex.Unop.arg,
43371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IEndianess);
4338cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            return mk_LoadRR32toFPR( env, r_srcHi, r_srcLo );
4339cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         } else {
43401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
4341cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            return mk_LoadR64toFPR( env, r_src );
4342cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         }
4343cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4344cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_D32toD64: {
43451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr(env, e->Iex.Unop.arg, IEndianess);
4346cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_Dfp64Unary(Pfp_DCTDP, fr_dst, fr_src));
4347cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4348cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4349c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_D128HItoD64:
43501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_dstHi, &r_dstLo, env, e->Iex.Unop.arg,
43511f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                         IEndianess );
4352c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return r_dstHi;
4353c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_D128LOtoD64:
43541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_dstHi, &r_dstLo, env, e->Iex.Unop.arg,
43551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                         IEndianess );
4356c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return r_dstLo;
4357cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_InsertExpD64: {
43581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_srcL = iselDblExpr(env, e->Iex.Binop.arg1, IEndianess);
43591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_srcR = iselDblExpr(env, e->Iex.Binop.arg2, IEndianess);
4360cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4361cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_Dfp64Binary(Pfp_DIEX, fr_dst, fr_srcL,
4362cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj					    fr_srcR));
4363cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4364cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj       }
4365c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4366c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         vex_printf( "ERROR: iselDfp64Expr_wrk, UNKNOWN unop case %d\n",
4367b173774421d015736c2316b5e6e998e7de545a5cflorian                     (Int)e->Iex.Unop.op );
4368c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4369c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4370c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
437126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   if (e->tag == Iex_Binop) {
4372cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      PPCFpOp fpop = Pfp_INVALID;
4373cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      HReg fr_dst = newVRegF(env);
437426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
437526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      switch (e->Iex.Binop.op) {
4376cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_D128toD64:     fpop = Pfp_DRDPQ;  break;
4377cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_D64toD32:      fpop = Pfp_DRSP;   break;
4378cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_I64StoD64:     fpop = Pfp_DCFFIX; break;
4379cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      case Iop_RoundD64toInt: fpop = Pfp_DRINTN; break;
4380cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      default: break;
438126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4382cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_DRDPQ) {
438326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg r_srcHi = newVRegF(env);
438426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg r_srcLo = newVRegF(env);
438526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
43861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
43871f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
43881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
438926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_DfpD128toD64(fpop, fr_dst, r_srcHi, r_srcLo));
439026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         return fr_dst;
4391cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4392cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DRINTN) {
4393cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg fr_src = newVRegF(env);
43941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* r_rmc = iselWordExpr_RI(env, e->Iex.Binop.arg1, IEndianess);
4395cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4396cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* NOTE, this IOP takes a DFP value and rounds to the
4397cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * neares floating point integer value, i.e. fractional part
4398cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * is zero.  The result is a decimal floating point number.
4399cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * the INT in the name is a bit misleading.
4400cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          */
44011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
4402cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpRound(fr_dst, fr_src, r_rmc));
4403cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
440426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4405cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DRSP) {
44061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
44071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
440826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_Dfp64Unary(fpop, fr_dst, fr_src));
440926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         return fr_dst;
4410cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4411cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DCFFIX) {
4412cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg fr_src = newVRegF(env);
4413cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4414cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
44151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
4416cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4417cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4418cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the I64 value into a floating point register
4419cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (mode64) {
44201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll           HReg tmp = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
4421cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4422cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll           addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4423cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4424cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi, tmpLo;
4425cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4426cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
44271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Binop.arg2,
44281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4429cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*mode32*/));
4430cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*mode32*/));
4431cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
4432cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4433cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8,  fr_src, zero_r1));
4434cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Unary(fpop, fr_dst, fr_src));
4435cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4436cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return fr_dst;
443726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4438cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4439cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      switch (e->Iex.Binop.op) {
4440e83db484fd409aa84e3d7307a6a770c28b8c0c16carll      /* shift instructions D64, I32 -> D64 */
4441cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_ShlD64: fpop = Pfp_DSCLI; break;
4442cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_ShrD64: fpop = Pfp_DSCRI; break;
4443cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
4444cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4445cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      if (fpop != Pfp_INVALID) {
44461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, e->Iex.Binop.arg1, IEndianess);
44471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* shift = iselWordExpr_RI(env, e->Iex.Binop.arg2, IEndianess);
4448cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4449e83db484fd409aa84e3d7307a6a770c28b8c0c16carll         /* shift value must be an immediate value */
4450e83db484fd409aa84e3d7307a6a770c28b8c0c16carll         vassert(shift->tag == Pri_Imm);
4451e83db484fd409aa84e3d7307a6a770c28b8c0c16carll
4452cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpShift(fpop, fr_dst, fr_src, shift));
4453cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4454cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4455cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4456cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      switch (e->Iex.Binop.op) {
4457cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_InsertExpD64:
4458cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         fpop = Pfp_DIEX;
4459cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         break;
4460cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: 	break;
4461cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4462cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      if (fpop != Pfp_INVALID) {
4463cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg fr_srcL = newVRegF(env);
44641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_srcR = iselDfp64Expr(env, e->Iex.Binop.arg2, IEndianess);
4465cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4466cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4467cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4468cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64) {
4469cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the I64 value into a floating point reg
44701f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg tmp = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
4471cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4472cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4473cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4474cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            // put the I64 register pair into a floating point reg
4475cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi;
4476cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpLo;
4477cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4478cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
44791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Binop.arg1,
44801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4481cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*!mode64*/));
4482cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*!mode64*/));
4483cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
4484cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fr_srcL, zero_r1));
4485cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp64Binary(fpop, fr_dst, fr_srcL,
4486cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                            fr_srcR));
4487cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4488cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return fr_dst;
4489cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
449026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   }
449126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4492c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Triop) {
4493420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      IRTriop *triop = e->Iex.Triop.details;
4494c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      PPCFpOp fpop = Pfp_INVALID;
4495c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4496420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4497c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_AddD64:
4498c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPADD;
4499c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4500c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_SubD64:
4501c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPSUB;
4502c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4503c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_MulD64:
4504c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPMUL;
4505c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4506c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_DivD64:
4507c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPDIV;
4508c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4509c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4510c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4511c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4512c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (fpop != Pfp_INVALID) {
4513c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_dst = newVRegF( env );
45141f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselDfp64Expr( env, triop->arg2, IEndianess );
45151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDfp64Expr( env, triop->arg3, IEndianess );
4516c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
45171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, triop->arg1, IEndianess );
4518c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Binary( fpop, r_dst, r_srcL, r_srcR ) );
4519c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return r_dst;
4520c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4521cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4522420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4523cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_QuantizeD64:          fpop = Pfp_DQUA;  break;
4524cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_SignificanceRoundD64: fpop = Pfp_RRDTR; break;
4525cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
4526cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4527cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_DQUA) {
4528cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dst = newVRegF(env);
45291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcL = iselDfp64Expr(env, triop->arg2, IEndianess);
45301f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDfp64Expr(env, triop->arg3, IEndianess);
45311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc  = iselWordExpr_RI(env, triop->arg1, IEndianess);
4532cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpQuantize(fpop, r_dst, r_srcL, r_srcR,
4533cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                            rmc));
4534cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return r_dst;
4535cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4536cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_RRDTR) {
4537cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_dst = newVRegF(env);
4538cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcL = newVRegF(env);
45391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_srcR = iselDfp64Expr(env, triop->arg3, IEndianess);
45401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc  = iselWordExpr_RI(env, triop->arg1, IEndianess);
4541cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
45421f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg i8_val = iselWordExpr_R(env, triop->arg2, IEndianess);
4543cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4544cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Move I8 to float register to issue instruction */
4545cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4546cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (mode64)
4547cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, i8_val, True/*mode64*/));
4548cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         else
4549cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, i8_val, False/*mode32*/));
4550cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4551cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_srcL, zero_r1));
4552cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4553cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4554cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // will set TE and RMC when issuing instruction
4555cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpQuantize(fpop, r_dst, r_srcL, r_srcR, rmc));
4556cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return r_dst;
4557cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4558c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4559c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4560c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   ppIRExpr( e );
4561c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vpanic( "iselDfp64Expr_wrk(ppc)" );
4562c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4563c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
45641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void iselDfp128Expr(HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e,
45651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                           IREndness IEndianess)
4566c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
45671f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselDfp128Expr_wrk( rHi, rLo, env, e, IEndianess );
4568c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( hregIsVirtual(*rHi) );
4569c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( hregIsVirtual(*rLo) );
4570c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4571c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4572c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/* DO NOT CALL THIS DIRECTLY */
45731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void iselDfp128Expr_wrk(HReg* rHi, HReg *rLo, ISelEnv* env, IRExpr* e,
45741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                               IREndness IEndianess)
4575c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
4576c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( e );
4577c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   vassert( typeOfIRExpr(env->type_env,e) == Ity_D128 );
4578c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4579c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* read 128-bit IRTemp */
4580c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_RdTmp) {
4581c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      lookupIRTempPair( rHi, rLo, env, e->Iex.RdTmp.tmp );
4582c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      return;
4583c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4584c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
458526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   if (e->tag == Iex_Unop) {
458626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      HReg r_dstHi = newVRegF(env);
458726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      HReg r_dstLo = newVRegF(env);
458826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
458926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      if (e->Iex.Unop.op == Iop_I64StoD128) {
4590cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg fr_src = newVRegF(env);
4591cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4592cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4593cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // put the I64 value into a floating point reg
4594cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64) {
45951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg tmp   = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
4596cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4597cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4598cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi, tmpLo;
4599cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4600cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
46011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Unop.arg,
46021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4603cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*mode32*/));
4604cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*mode32*/));
4605cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
460626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4607cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fr_src, zero_r1));
4608cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpI64StoD128(Pfp_DCFFIXQ, r_dstHi, r_dstLo,
4609cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                              fr_src));
461026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4611cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
461226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      if (e->Iex.Unop.op == Iop_D64toD128) {
46131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselDfp64Expr(env, e->Iex.Unop.arg, IEndianess);
461426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4615cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Source is 64bit, result is 128 bit.  High 64bit source arg,
461626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          * is ignored by the instruction.  Set high arg to r_src just
461726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          * to meet the vassert tests.
461826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          */
4619cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_Dfp128Unary(Pfp_DCTQPQ, r_dstHi, r_dstLo,
462026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                                            r_src, r_src));
462126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
462226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      *rHi = r_dstHi;
462326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      *rLo = r_dstLo;
462426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      return;
462526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   }
462626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
4627c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   /* --------- OPS --------- */
4628c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Binop) {
4629c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_srcHi;
4630c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      HReg r_srcLo;
4631c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4632c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      switch (e->Iex.Binop.op) {
4633c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_D64HLtoD128:
46341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         r_srcHi = iselDfp64Expr( env, e->Iex.Binop.arg1, IEndianess );
46351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         r_srcLo = iselDfp64Expr( env, e->Iex.Binop.arg2, IEndianess );
4636c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_srcHi;
4637c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_srcLo;
4638c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
4639c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
464026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      case Iop_D128toD64: {
464126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         PPCFpOp fpop = Pfp_DRDPQ;
464226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg fr_dst  = newVRegF(env);
464326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
46441f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, e->Iex.Binop.arg1, IEndianess );
46451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
46461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
464726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_DfpD128toD64(fpop, fr_dst, r_srcHi, r_srcLo));
464826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
464926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         /* Need to meet the interface spec but the result is
465026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          * just 64-bits so send the result back in both halfs.
465126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj          */
465226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rHi = fr_dst;
465326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rLo = fr_dst;
465426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         return;
465526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
465626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      case Iop_ShlD128:
465726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      case Iop_ShrD128: {
465826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg fr_dst_hi = newVRegF(env);
465926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         HReg fr_dst_lo = newVRegF(env);
46601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* shift = iselWordExpr_RI(env, e->Iex.Binop.arg2, IEndianess);
466126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         PPCFpOp fpop = Pfp_DSCLIQ;  /* fix later if necessary */
466226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
46631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg1,
46641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
466526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
466626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         if (e->Iex.Binop.op == Iop_ShrD128)
466726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj            fpop = Pfp_DSCRIQ;
466826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
466926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         addInstr(env, PPCInstr_DfpShift128(fpop, fr_dst_hi, fr_dst_lo,
467026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                                            r_srcHi, r_srcLo, shift));
467126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
467226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rHi = fr_dst_hi;
467326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj         *rLo = fr_dst_lo;
4674cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
4675cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4676cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_RoundD128toInt: {
4677cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstHi = newVRegF(env);
4678cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstLo = newVRegF(env);
46791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* r_rmc = iselWordExpr_RI(env, e->Iex.Binop.arg1, IEndianess);
4680cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4681cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         // will set R and RMC when issuing instruction
46821f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
46831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
4684cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4685cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpRound128(r_dstHi, r_dstLo,
4686cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                            r_srcHi, r_srcLo, r_rmc));
4687cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rHi = r_dstHi;
4688cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rLo = r_dstLo;
4689cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
4690cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4691cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_InsertExpD128: {
4692cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstHi = newVRegF(env);
4693cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_dstLo = newVRegF(env);
4694cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_srcL  = newVRegF(env);
4695cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4696cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         r_srcHi = newVRegF(env);
4697cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         r_srcLo = newVRegF(env);
4698cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
46991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Binop.arg2,
47001f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
4701cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4702cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Move I64 to float register to issue instruction */
4703cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64) {
47041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg tmp = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
4705cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(8, zero_r1, tmp, True/*mode64*/));
4706cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         } else {
4707cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            HReg tmpHi, tmpLo;
4708cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
4709cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
47101f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&tmpHi, &tmpLo, env, e->Iex.Unop.arg,
47111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                          IEndianess);
4712cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, zero_r1, tmpHi, False/*mode32*/));
4713cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, tmpLo, False/*mode32*/));
4714cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         }
4715cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4716cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_srcL, zero_r1));
4717cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_InsertExpD128(Pfp_DIEXQ,
4718cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                              r_dstHi, r_dstLo,
4719cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                              r_srcL, r_srcHi, r_srcLo));
4720cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rHi = r_dstHi;
4721cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rLo = r_dstLo;
4722cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
472326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj      }
4724c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4725cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         vex_printf( "ERROR: iselDfp128Expr_wrk, UNKNOWN binop case %d\n",
4726b173774421d015736c2316b5e6e998e7de545a5cflorian                     (Int)e->Iex.Binop.op );
4727c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4728c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4729c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
4730c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4731c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   if (e->tag == Iex_Triop) {
4732420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      IRTriop *triop = e->Iex.Triop.details;
4733c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      PPCFpOp fpop = Pfp_INVALID;
4734cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      HReg r_dstHi = newVRegF(env);
4735cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      HReg r_dstLo = newVRegF(env);
4736cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4737420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4738c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_AddD128:
4739c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPADDQ;
4740c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4741c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_SubD128:
4742c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPSUBQ;
4743c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4744c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_MulD128:
4745c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPMULQ;
4746c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4747c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Iop_DivD128:
4748c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         fpop = Pfp_DFPDIVQ;
4749c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4750c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      default:
4751c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         break;
4752c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4753c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4754c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (fpop != Pfp_INVALID) {
4755c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_srcRHi = newVRegV( env );
4756c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_srcRLo = newVRegV( env );
4757c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4758c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         /* dst will be used to pass in the left operand and get the result. */
47591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_dstHi, &r_dstLo, env, triop->arg2, IEndianess );
47601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &r_srcRHi, &r_srcRLo, env, triop->arg3, IEndianess );
47611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_DFP_rounding_mode( env, triop->arg1, IEndianess );
4762c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env,
4763c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                   PPCInstr_Dfp128Binary( fpop, r_dstHi, r_dstLo,
4764c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                          r_srcRHi, r_srcRLo ) );
4765c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rHi = r_dstHi;
4766c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         *rLo = r_dstLo;
4767c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
4768c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
4769420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian      switch (triop->op) {
4770cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_QuantizeD128:          fpop = Pfp_DQUAQ;  break;
4771cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      case Iop_SignificanceRoundD128: fpop = Pfp_DRRNDQ; break;
4772cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      default: break;
4773cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4774cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      if (fpop == Pfp_DQUAQ) {
4775cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_srcHi = newVRegF(env);
4776cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         HReg r_srcLo = newVRegF(env);
47771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc = iselWordExpr_RI(env, triop->arg1, IEndianess);
4778cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4779cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         /* dst will be used to pass in the left operand and get the result */
47801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_dstHi, &r_dstLo, env, triop->arg2, IEndianess);
47811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, triop->arg3, IEndianess);
4782cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
4783cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         // will set RMC when issuing instruction
4784cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         addInstr(env, PPCInstr_DfpQuantize128(fpop, r_dstHi, r_dstLo,
4785cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                               r_srcHi, r_srcLo, rmc));
4786cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        *rHi = r_dstHi;
4787cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        *rLo = r_dstLo;
4788cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         return;
4789cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4790cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll      } else if (fpop == Pfp_DRRNDQ) {
4791cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcHi = newVRegF(env);
4792cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_srcLo = newVRegF(env);
47931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* rmc = iselWordExpr_RI(env, triop->arg1, IEndianess);
4794cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* zero_r1 = PPCAMode_IR( 0, StackFramePtr(env->mode64) );
4795cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         PPCAMode* four_r1 = PPCAMode_IR( 4, StackFramePtr(env->mode64) );
47961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg i8_val = iselWordExpr_R(env, triop->arg2, IEndianess);
4797cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         HReg r_zero = newVRegI( env );
4798cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
47991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr(&r_srcHi, &r_srcLo, env, triop->arg3, IEndianess);
4800cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4801cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* dst will be used to pass in the left operand and get the result */
4802cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Move I8 to float register to issue instruction.  Note, the
4803cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * instruction only looks at the bottom 6 bits so we really don't
4804cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * have to clear the upper bits since the iselWordExpr_R sets the
4805cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * bottom 8-bits.
4806cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          */
4807cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         sub_from_sp( env, 16 );
4808cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4809cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         if (env->mode64)
4810cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, i8_val, True/*mode64*/));
4811cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         else
4812cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll            addInstr(env, PPCInstr_Store(4, four_r1, i8_val, False/*mode32*/));
4813cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4814cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         /* Have to write to the upper bits to ensure they have been
4815cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          * initialized. The instruction ignores all but the lower 6-bits.
4816cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll          */
4817cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr( env, PPCInstr_LI( r_zero, 0, env->mode64 ) );
4818cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dstHi, zero_r1));
4819cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, r_dstLo, zero_r1));
4820cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4821cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         add_to_sp( env, 16 );
4822cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
4823cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         // will set RMC when issuing instruction
4824cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll         addInstr(env, PPCInstr_DfpQuantize128(fpop, r_dstHi, r_dstLo,
4825cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll                                               r_srcHi, r_srcLo, rmc));
4826cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rHi = r_dstHi;
4827cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         *rLo = r_dstLo;
4828cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         return;
4829cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj      }
4830cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll }
4831c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4832c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   ppIRExpr( e );
483326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj   vpanic( "iselDfp128Expr(ppc64)" );
4834c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
4835c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
4836cd304497d9d869f9b24a002299d3953ee072229bcerion
4837e21595a704c11ce19b8cd73df03fdcbe483517eecerion/*---------------------------------------------------------*/
4838e21595a704c11ce19b8cd73df03fdcbe483517eecerion/*--- ISEL: SIMD (Vector) expressions, 128 bit.         ---*/
4839e21595a704c11ce19b8cd73df03fdcbe483517eecerion/*---------------------------------------------------------*/
4840e21595a704c11ce19b8cd73df03fdcbe483517eecerion
48411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselVecExpr ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
4842e21595a704c11ce19b8cd73df03fdcbe483517eecerion{
48431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   HReg r = iselVecExpr_wrk( env, e, IEndianess );
4844e21595a704c11ce19b8cd73df03fdcbe483517eecerion#  if 0
4845e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
4846e21595a704c11ce19b8cd73df03fdcbe483517eecerion#  endif
4847e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(hregClass(r) == HRcVec128);
4848e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(hregIsVirtual(r));
4849e21595a704c11ce19b8cd73df03fdcbe483517eecerion   return r;
4850e21595a704c11ce19b8cd73df03fdcbe483517eecerion}
4851e21595a704c11ce19b8cd73df03fdcbe483517eecerion
4852e21595a704c11ce19b8cd73df03fdcbe483517eecerion/* DO NOT CALL THIS DIRECTLY */
48531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
4854e21595a704c11ce19b8cd73df03fdcbe483517eecerion{
48554628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
48565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   PPCAvOp op = Pav_INVALID;
4857e522d4bbf9e59873859c2f0693450a176fb2b996sewardj   PPCAvFpOp fpop = Pavfp_INVALID;
48585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   IRType  ty = typeOfIRExpr(env->type_env,e);
4859e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(e);
4860e21595a704c11ce19b8cd73df03fdcbe483517eecerion   vassert(ty == Ity_V128);
4861e21595a704c11ce19b8cd73df03fdcbe483517eecerion
4862dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   if (e->tag == Iex_RdTmp) {
4863dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
4864e21595a704c11ce19b8cd73df03fdcbe483517eecerion   }
4865e21595a704c11ce19b8cd73df03fdcbe483517eecerion
4866e21595a704c11ce19b8cd73df03fdcbe483517eecerion   if (e->tag == Iex_Get) {
48675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion      /* Guest state vectors are 16byte aligned,
48685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         so don't need to worry here */
4869e21595a704c11ce19b8cd73df03fdcbe483517eecerion      HReg dst = newVRegV(env);
4870e21595a704c11ce19b8cd73df03fdcbe483517eecerion      addInstr(env,
48715b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion               PPCInstr_AvLdSt( True/*load*/, 16, dst,
48725b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                PPCAMode_IR( e->Iex.Get.offset,
48735b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                             GuestStatePtr(mode64) )));
4874e21595a704c11ce19b8cd73df03fdcbe483517eecerion      return dst;
4875e21595a704c11ce19b8cd73df03fdcbe483517eecerion   }
4876e21595a704c11ce19b8cd73df03fdcbe483517eecerion
48771f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
487885175a7453c4cc4a7d29a247766b627d5cb933decarll      /* Need to be able to do V128 unaligned loads. The BE unaligned load
487985175a7453c4cc4a7d29a247766b627d5cb933decarll       * can be accomplised using the following code sequece from the ISA.
488085175a7453c4cc4a7d29a247766b627d5cb933decarll       * It uses the lvx instruction that does two aligned loads and then
48819877fe5792c32f04fa31018a72928903031a12e8carll       * permute the data to store the required data as if it had been an
48829877fe5792c32f04fa31018a72928903031a12e8carll       * unaligned load.
48839877fe5792c32f04fa31018a72928903031a12e8carll       *
48849877fe5792c32f04fa31018a72928903031a12e8carll       *   lvx  Vhi,0,Rb        # load MSQ, using the unaligned address in Rb
48859877fe5792c32f04fa31018a72928903031a12e8carll       *   lvsl Vp, 0,Rb        # Set permute control vector
48869877fe5792c32f04fa31018a72928903031a12e8carll       *   addi Rb,Rb,15        # Address of LSQ
48879877fe5792c32f04fa31018a72928903031a12e8carll       *   lvx  Vlo,0,Rb        # load LSQ
48889877fe5792c32f04fa31018a72928903031a12e8carll       *   vperm Vt,Vhi,Vlo,Vp  # align the data as requested
48899877fe5792c32f04fa31018a72928903031a12e8carll       */
48909877fe5792c32f04fa31018a72928903031a12e8carll
48919877fe5792c32f04fa31018a72928903031a12e8carll      HReg Vhi   = newVRegV(env);
48929877fe5792c32f04fa31018a72928903031a12e8carll      HReg Vlo   = newVRegV(env);
48939877fe5792c32f04fa31018a72928903031a12e8carll      HReg Vp    = newVRegV(env);
4894a50fde5504e829e5154113d7e507f12707089f48cerion      HReg v_dst = newVRegV(env);
48959877fe5792c32f04fa31018a72928903031a12e8carll      HReg rB;
48969877fe5792c32f04fa31018a72928903031a12e8carll      HReg rB_plus_15 = newVRegI(env);
48979877fe5792c32f04fa31018a72928903031a12e8carll
4898a50fde5504e829e5154113d7e507f12707089f48cerion      vassert(e->Iex.Load.ty == Ity_V128);
48999877fe5792c32f04fa31018a72928903031a12e8carll      rB = iselWordExpr_R( env, e->Iex.Load.addr, IEndianess );
49009877fe5792c32f04fa31018a72928903031a12e8carll
49019877fe5792c32f04fa31018a72928903031a12e8carll      // lvx  Vhi, 0, Rb
49029877fe5792c32f04fa31018a72928903031a12e8carll      addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, Vhi,
49039877fe5792c32f04fa31018a72928903031a12e8carll                                     PPCAMode_IR(0, rB)) );
49049877fe5792c32f04fa31018a72928903031a12e8carll
490585175a7453c4cc4a7d29a247766b627d5cb933decarll      if (IEndianess == Iend_LE)
490685175a7453c4cc4a7d29a247766b627d5cb933decarll         // lvsr Vp, 0, Rb
490785175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvSh( False/*right shift*/, Vp,
490885175a7453c4cc4a7d29a247766b627d5cb933decarll                                      PPCAMode_IR(0, rB)) );
490985175a7453c4cc4a7d29a247766b627d5cb933decarll      else
491085175a7453c4cc4a7d29a247766b627d5cb933decarll         // lvsl Vp, 0, Rb
491185175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvSh( True/*left shift*/, Vp,
491285175a7453c4cc4a7d29a247766b627d5cb933decarll                                      PPCAMode_IR(0, rB)) );
49139877fe5792c32f04fa31018a72928903031a12e8carll
49149877fe5792c32f04fa31018a72928903031a12e8carll      // addi Rb_plus_15, Rb, 15
49159877fe5792c32f04fa31018a72928903031a12e8carll      addInstr(env, PPCInstr_Alu( Palu_ADD, rB_plus_15,
49169877fe5792c32f04fa31018a72928903031a12e8carll                                  rB, PPCRH_Imm(True, toUShort(15))) );
49179877fe5792c32f04fa31018a72928903031a12e8carll
49189877fe5792c32f04fa31018a72928903031a12e8carll      // lvx  Vlo, 0, Rb_plus_15
49199877fe5792c32f04fa31018a72928903031a12e8carll      addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, Vlo,
49209877fe5792c32f04fa31018a72928903031a12e8carll                                     PPCAMode_IR(0, rB_plus_15)) );
49219877fe5792c32f04fa31018a72928903031a12e8carll
492285175a7453c4cc4a7d29a247766b627d5cb933decarll      if (IEndianess == Iend_LE)
492385175a7453c4cc4a7d29a247766b627d5cb933decarll         // vperm Vt, Vhi, Vlo, Vp
492485175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvPerm( v_dst, Vlo, Vhi, Vp ));
492585175a7453c4cc4a7d29a247766b627d5cb933decarll      else
492685175a7453c4cc4a7d29a247766b627d5cb933decarll         // vperm Vt, Vhi, Vlo, Vp
492785175a7453c4cc4a7d29a247766b627d5cb933decarll         addInstr(env, PPCInstr_AvPerm( v_dst, Vhi, Vlo, Vp ));
492885175a7453c4cc4a7d29a247766b627d5cb933decarll
4929a50fde5504e829e5154113d7e507f12707089f48cerion      return v_dst;
4930a50fde5504e829e5154113d7e507f12707089f48cerion   }
4931a50fde5504e829e5154113d7e507f12707089f48cerion
4932f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   if (e->tag == Iex_Unop) {
4933f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      switch (e->Iex.Unop.op) {
4934f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
4935225a034683024109da729a4d2f080364b9485007cerion      case Iop_NotV128: {
49361f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
4937225a034683024109da729a4d2f080364b9485007cerion         HReg dst = newVRegV(env);
49385b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, arg));
4939225a034683024109da729a4d2f080364b9485007cerion         return dst;
4940225a034683024109da729a4d2f080364b9485007cerion      }
4941225a034683024109da729a4d2f080364b9485007cerion
4942dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj      case Iop_CmpNEZ8x16: {
49431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
4944dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         HReg zero = newVRegV(env);
4945dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         HReg dst  = newVRegV(env);
49465b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49475b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin8x16(Pav_CMPEQU, dst, arg, zero));
49485b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
4949dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj         return dst;
4950dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj      }
49511bee561912427ca8f8998c89b62d86ba2ee49732sewardj
49521bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_CmpNEZ16x8: {
49531f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49541bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg zero = newVRegV(env);
49551bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg dst  = newVRegV(env);
49565b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin16x8(Pav_CMPEQU, dst, arg, zero));
49585b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
49591bee561912427ca8f8998c89b62d86ba2ee49732sewardj         return dst;
49601bee561912427ca8f8998c89b62d86ba2ee49732sewardj      }
49611bee561912427ca8f8998c89b62d86ba2ee49732sewardj
49621bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_CmpNEZ32x4: {
49631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49641bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg zero = newVRegV(env);
49651bee561912427ca8f8998c89b62d86ba2ee49732sewardj         HReg dst  = newVRegV(env);
49665b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32x4(Pav_CMPEQU, dst, arg, zero));
49685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
49691bee561912427ca8f8998c89b62d86ba2ee49732sewardj         return dst;
49701bee561912427ca8f8998c89b62d86ba2ee49732sewardj      }
49711bee561912427ca8f8998c89b62d86ba2ee49732sewardj
49720c74bb5aa3240f693df0568d578baabf0c376dc4carll      case Iop_CmpNEZ64x2: {
49731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49740c74bb5aa3240f693df0568d578baabf0c376dc4carll         HReg zero = newVRegV(env);
49750c74bb5aa3240f693df0568d578baabf0c376dc4carll         HReg dst  = newVRegV(env);
49760c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero));
49770c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvBin64x2(Pav_CMPEQU, dst, arg, zero));
49780c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
49790c74bb5aa3240f693df0568d578baabf0c376dc4carll         return dst;
49800c74bb5aa3240f693df0568d578baabf0c376dc4carll      }
49810c74bb5aa3240f693df0568d578baabf0c376dc4carll
49821ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      case Iop_RecipEst32Fx4: fpop = Pavfp_RCPF;    goto do_32Fx4_unary;
49831ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj      case Iop_RSqrtEst32Fx4: fpop = Pavfp_RSQRTF;  goto do_32Fx4_unary;
4984e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_I32UtoFx4:     fpop = Pavfp_CVTU2F;  goto do_32Fx4_unary;
4985e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_I32StoFx4:     fpop = Pavfp_CVTS2F;  goto do_32Fx4_unary;
4986e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_QFtoI32Ux4_RZ: fpop = Pavfp_QCVTF2U; goto do_32Fx4_unary;
4987e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_QFtoI32Sx4_RZ: fpop = Pavfp_QCVTF2S; goto do_32Fx4_unary;
4988e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RM: fpop = Pavfp_ROUNDM;  goto do_32Fx4_unary;
4989e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RP: fpop = Pavfp_ROUNDP;  goto do_32Fx4_unary;
4990e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RN: fpop = Pavfp_ROUNDN;  goto do_32Fx4_unary;
4991e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_RoundF32x4_RZ: fpop = Pavfp_ROUNDZ;  goto do_32Fx4_unary;
49928ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      do_32Fx4_unary:
49938ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      {
49941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
49958ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg dst = newVRegV(env);
4996e522d4bbf9e59873859c2f0693450a176fb2b996sewardj         addInstr(env, PPCInstr_AvUn32Fx4(fpop, dst, arg));
49978ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         return dst;
49988ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      }
49998ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
5000225a034683024109da729a4d2f080364b9485007cerion      case Iop_32UtoV128: {
5001197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         HReg r_aligned16, r_zeros;
50021f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg, IEndianess);
5003225a034683024109da729a4d2f080364b9485007cerion         HReg   dst = newVRegV(env);
50045b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode *am_off0, *am_off4, *am_off8, *am_off12;
5005225a034683024109da729a4d2f080364b9485007cerion         sub_from_sp( env, 32 );     // Move SP down
5006225a034683024109da729a4d2f080364b9485007cerion
5007225a034683024109da729a4d2f080364b9485007cerion         /* Get a quadword aligned address within our stack space */
5008197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         r_aligned16 = get_sp_aligned16( env );
50095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off0  = PPCAMode_IR( 0,  r_aligned16 );
50105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off4  = PPCAMode_IR( 4,  r_aligned16 );
50115b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off8  = PPCAMode_IR( 8,  r_aligned16 );
50125b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         am_off12 = PPCAMode_IR( 12, r_aligned16 );
5013225a034683024109da729a4d2f080364b9485007cerion
5014197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         /* Store zeros */
5015197bd17d3ba8ac5204cd5c9ba5fab571249eb791sewardj         r_zeros = newVRegI(env);
50165b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_LI(r_zeros, 0x0, mode64));
50171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
50181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off0, r_src, mode64 ));
50191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
50201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off0, r_zeros, mode64 ));
50215b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_off4, r_zeros, mode64 ));
50225b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_off8, r_zeros, mode64 ));
5023225a034683024109da729a4d2f080364b9485007cerion
5024225a034683024109da729a4d2f080364b9485007cerion         /* Store r_src in low word of quadword-aligned mem */
50251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
50261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off12, r_zeros, mode64 ));
50271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
50281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_Store( 4, am_off12, r_src, mode64 ));
5029225a034683024109da729a4d2f080364b9485007cerion
5030225a034683024109da729a4d2f080364b9485007cerion         /* Load word into low word of quadword vector reg */
50311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         if (IEndianess == Iend_LE)
50321f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_AvLdSt( True/*ld*/, 4, dst, am_off0 ));
50331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         else
50341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            addInstr(env, PPCInstr_AvLdSt( True/*ld*/, 4, dst, am_off12 ));
5035225a034683024109da729a4d2f080364b9485007cerion
5036225a034683024109da729a4d2f080364b9485007cerion         add_to_sp( env, 32 );       // Reset SP
5037225a034683024109da729a4d2f080364b9485007cerion         return dst;
5038225a034683024109da729a4d2f080364b9485007cerion      }
5039225a034683024109da729a4d2f080364b9485007cerion
504092d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_Dup8x16:
504192d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_Dup16x8:
504292d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_Dup32x4:
50431f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         return mk_AvDuplicateRI(env, e->Iex.Unop.arg, IEndianess);
504427b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
50457deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_CipherSV128: op = Pav_CIPHERSUBV128; goto do_AvCipherV128Un;
50467deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvCipherV128Un: {
50471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
50487deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst = newVRegV(env);
50497deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvCipherV128Unary(op, dst, arg));
50507deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
50517deaf9552b546b847528cf39b38898fb7742b5f5carll      }
50527deaf9552b546b847528cf39b38898fb7742b5f5carll
5053a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz8x16: op = Pav_ZEROCNTBYTE;   goto do_zerocnt;
5054a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz16x8: op = Pav_ZEROCNTHALF;   goto do_zerocnt;
5055a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz32x4: op = Pav_ZEROCNTWORD;   goto do_zerocnt;
5056a8c7b0f2ac208ed08763d0873131962a65669d58sewardj      case Iop_Clz64x2: op = Pav_ZEROCNTDBL;    goto do_zerocnt;
5057c4fa725f59d51f73e08aa82b48bc63133ceb5579sewardj      case Iop_PwBitMtxXpose64x2: op = Pav_BITMTXXPOSE;  goto do_zerocnt;
50587deaf9552b546b847528cf39b38898fb7742b5f5carll      do_zerocnt:
50597deaf9552b546b847528cf39b38898fb7742b5f5carll      {
50601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll        HReg arg = iselVecExpr(env, e->Iex.Unop.arg, IEndianess);
50617deaf9552b546b847528cf39b38898fb7742b5f5carll        HReg dst = newVRegV(env);
5062c4fa725f59d51f73e08aa82b48bc63133ceb5579sewardj        addInstr(env, PPCInstr_AvUnary(op, dst, arg));
50637deaf9552b546b847528cf39b38898fb7742b5f5carll        return dst;
50647deaf9552b546b847528cf39b38898fb7742b5f5carll      }
50657deaf9552b546b847528cf39b38898fb7742b5f5carll
5066f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      default:
5067f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion         break;
5068f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      } /* switch (e->Iex.Unop.op) */
5069f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   } /* if (e->tag == Iex_Unop) */
5070f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
5071f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   if (e->tag == Iex_Binop) {
5072f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      switch (e->Iex.Binop.op) {
5073f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
5074f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      case Iop_64HLtoV128: {
5075f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         if (!mode64) {
507688a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     r3, r2, r1, r0, r_aligned16;
50775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            PPCAMode *am_off0, *am_off4, *am_off8, *am_off12;
507888a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     dst = newVRegV(env);
5079f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* do this via the stack (easy, convenient, etc) */
5080f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            sub_from_sp( env, 32 );        // Move SP down
5081f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5082f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            // get a quadword aligned address within our stack space
5083f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            r_aligned16 = get_sp_aligned16( env );
50845b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off0  = PPCAMode_IR( 0,  r_aligned16 );
50855b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off4  = PPCAMode_IR( 4,  r_aligned16 );
50865b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off8  = PPCAMode_IR( 8,  r_aligned16 );
50875b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            am_off12 = PPCAMode_IR( 12, r_aligned16 );
5088f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5089f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* Do the less significant 64 bits */
50901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&r1, &r0, env, e->Iex.Binop.arg2, IEndianess);
50915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off12, r0, mode64 ));
50925b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off8,  r1, mode64 ));
5093f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* Do the more significant 64 bits */
50941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            iselInt64Expr(&r3, &r2, env, e->Iex.Binop.arg1, IEndianess);
50955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off4, r2, mode64 ));
50965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_Store( 4, am_off0, r3, mode64 ));
5097f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5098f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            /* Fetch result back from stack. */
50995b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            addInstr(env, PPCInstr_AvLdSt(True/*ld*/, 16, dst, am_off0));
5100f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
5101f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            add_to_sp( env, 32 );          // Reset SP
5102f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion            return dst;
5103f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         } else {
51041f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     rHi = iselWordExpr_R(env, e->Iex.Binop.arg1, IEndianess);
51051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg     rLo = iselWordExpr_R(env, e->Iex.Binop.arg2, IEndianess);
510688a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     dst = newVRegV(env);
510788a9908b9b2a58daee177e33f90e59f4f9627259cerion            HReg     r_aligned16;
510888a9908b9b2a58daee177e33f90e59f4f9627259cerion            PPCAMode *am_off0, *am_off8;
510988a9908b9b2a58daee177e33f90e59f4f9627259cerion            /* do this via the stack (easy, convenient, etc) */
511088a9908b9b2a58daee177e33f90e59f4f9627259cerion            sub_from_sp( env, 32 );        // Move SP down
511188a9908b9b2a58daee177e33f90e59f4f9627259cerion
511288a9908b9b2a58daee177e33f90e59f4f9627259cerion            // get a quadword aligned address within our stack space
511388a9908b9b2a58daee177e33f90e59f4f9627259cerion            r_aligned16 = get_sp_aligned16( env );
511488a9908b9b2a58daee177e33f90e59f4f9627259cerion            am_off0  = PPCAMode_IR( 0,  r_aligned16 );
511588a9908b9b2a58daee177e33f90e59f4f9627259cerion            am_off8  = PPCAMode_IR( 8,  r_aligned16 );
511688a9908b9b2a58daee177e33f90e59f4f9627259cerion
511788a9908b9b2a58daee177e33f90e59f4f9627259cerion            /* Store 2*I64 to stack */
51181f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            if (IEndianess == Iend_LE) {
51191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off0, rLo, mode64 ));
51201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off8, rHi, mode64 ));
51211f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            } else {
51221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off0, rHi, mode64 ));
51231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll               addInstr(env, PPCInstr_Store( 8, am_off8, rLo, mode64 ));
51241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            }
512588a9908b9b2a58daee177e33f90e59f4f9627259cerion            /* Fetch result back from stack. */
512688a9908b9b2a58daee177e33f90e59f4f9627259cerion            addInstr(env, PPCInstr_AvLdSt(True/*ld*/, 16, dst, am_off0));
512788a9908b9b2a58daee177e33f90e59f4f9627259cerion
512888a9908b9b2a58daee177e33f90e59f4f9627259cerion            add_to_sp( env, 32 );          // Reset SP
512988a9908b9b2a58daee177e33f90e59f4f9627259cerion            return dst;
5130f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
5131f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      }
5132f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
5133e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_Max32Fx4:   fpop = Pavfp_MAXF;   goto do_32Fx4;
5134e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_Min32Fx4:   fpop = Pavfp_MINF;   goto do_32Fx4;
5135e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_CmpEQ32Fx4: fpop = Pavfp_CMPEQF; goto do_32Fx4;
5136e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_CmpGT32Fx4: fpop = Pavfp_CMPGTF; goto do_32Fx4;
5137e522d4bbf9e59873859c2f0693450a176fb2b996sewardj      case Iop_CmpGE32Fx4: fpop = Pavfp_CMPGEF; goto do_32Fx4;
51388ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      do_32Fx4:
51398ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      {
51401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argL = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
51411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argR = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
51428ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg dst = newVRegV(env);
5143e522d4bbf9e59873859c2f0693450a176fb2b996sewardj         addInstr(env, PPCInstr_AvBin32Fx4(fpop, dst, argL, argR));
51448ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         return dst;
51458ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      }
51468ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
51478ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      case Iop_CmpLE32Fx4: {
51481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argL = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
51491f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argR = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
51508ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg dst = newVRegV(env);
51518ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
51528ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         /* stay consistent with native ppc compares:
51538ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion            if a left/right lane holds a nan, return zeros for that lane
51548ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion            so: le == NOT(gt OR isNan)
51558ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion          */
51568ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         HReg isNanLR = newVRegV(env);
51571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg isNanL = isNan(env, argL, IEndianess);
51581f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg isNanR = isNan(env, argR, IEndianess);
51595b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_OR, isNanLR,
51605b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                         isNanL, isNanR));
51618ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion
51625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32Fx4(Pavfp_CMPGTF, dst,
51635b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           argL, argR));
51645b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(Pav_OR, dst, dst, isNanLR));
51655b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst));
51668ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion         return dst;
51678ea0d3ebfb8b1e4d8b6f851b0079c47a9886c686cerion      }
516836991efdccc3af11ee9691dfa5297872dfb88312cerion
5169225a034683024109da729a4d2f080364b9485007cerion      case Iop_AndV128:    op = Pav_AND;      goto do_AvBin;
5170225a034683024109da729a4d2f080364b9485007cerion      case Iop_OrV128:     op = Pav_OR;       goto do_AvBin;
5171225a034683024109da729a4d2f080364b9485007cerion      case Iop_XorV128:    op = Pav_XOR;      goto do_AvBin;
517236991efdccc3af11ee9691dfa5297872dfb88312cerion      do_AvBin: {
51731f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
51741f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
517536991efdccc3af11ee9691dfa5297872dfb88312cerion         HReg dst  = newVRegV(env);
51765b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(op, dst, arg1, arg2));
517736991efdccc3af11ee9691dfa5297872dfb88312cerion         return dst;
517836991efdccc3af11ee9691dfa5297872dfb88312cerion      }
517936991efdccc3af11ee9691dfa5297872dfb88312cerion
51800a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shl8x16:    op = Pav_SHL;    goto do_AvBin8x16;
51810a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shr8x16:    op = Pav_SHR;    goto do_AvBin8x16;
51820a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Sar8x16:    op = Pav_SAR;    goto do_AvBin8x16;
51831bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_Rol8x16:    op = Pav_ROTL;   goto do_AvBin8x16;
518492d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_InterleaveHI8x16: op = Pav_MRGHI;  goto do_AvBin8x16;
518592d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_InterleaveLO8x16: op = Pav_MRGLO;  goto do_AvBin8x16;
5186f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Add8x16:    op = Pav_ADDU;   goto do_AvBin8x16;
5187f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd8Ux16:  op = Pav_QADDU;  goto do_AvBin8x16;
5188f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd8Sx16:  op = Pav_QADDS;  goto do_AvBin8x16;
5189f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Sub8x16:    op = Pav_SUBU;   goto do_AvBin8x16;
5190f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub8Ux16:  op = Pav_QSUBU;  goto do_AvBin8x16;
5191f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub8Sx16:  op = Pav_QSUBS;  goto do_AvBin8x16;
519236991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg8Ux16:   op = Pav_AVGU;   goto do_AvBin8x16;
519336991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg8Sx16:   op = Pav_AVGS;   goto do_AvBin8x16;
519436991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max8Ux16:   op = Pav_MAXU;   goto do_AvBin8x16;
519536991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max8Sx16:   op = Pav_MAXS;   goto do_AvBin8x16;
519636991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min8Ux16:   op = Pav_MINU;   goto do_AvBin8x16;
519736991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min8Sx16:   op = Pav_MINS;   goto do_AvBin8x16;
519824d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven8Ux16: op = Pav_OMULU;  goto do_AvBin8x16;
519924d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven8Sx16: op = Pav_OMULS;  goto do_AvBin8x16;
52000c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpEQ8x16:  op = Pav_CMPEQU; goto do_AvBin8x16;
52010c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT8Ux16: op = Pav_CMPGTU; goto do_AvBin8x16;
52020c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT8Sx16: op = Pav_CMPGTS; goto do_AvBin8x16;
52037deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd8x16: op = Pav_POLYMULADD; goto do_AvBin8x16;
520436991efdccc3af11ee9691dfa5297872dfb88312cerion      do_AvBin8x16: {
52051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
52061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
520727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         HReg dst  = newVRegV(env);
52085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin8x16(op, dst, arg1, arg2));
520936991efdccc3af11ee9691dfa5297872dfb88312cerion         return dst;
521036991efdccc3af11ee9691dfa5297872dfb88312cerion      }
521136991efdccc3af11ee9691dfa5297872dfb88312cerion
52120a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shl16x8:    op = Pav_SHL;    goto do_AvBin16x8;
52130a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shr16x8:    op = Pav_SHR;    goto do_AvBin16x8;
52140a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Sar16x8:    op = Pav_SAR;    goto do_AvBin16x8;
52151bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_Rol16x8:    op = Pav_ROTL;   goto do_AvBin16x8;
52165f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_NarrowBin16to8x16:    op = Pav_PACKUU;  goto do_AvBin16x8;
52175f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin16Uto8Ux16: op = Pav_QPACKUU; goto do_AvBin16x8;
52185f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin16Sto8Sx16: op = Pav_QPACKSS; goto do_AvBin16x8;
5219c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveHI16x8:  op = Pav_MRGHI;  goto do_AvBin16x8;
5220c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveLO16x8:  op = Pav_MRGLO;  goto do_AvBin16x8;
5221f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Add16x8:    op = Pav_ADDU;   goto do_AvBin16x8;
5222f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd16Ux8:  op = Pav_QADDU;  goto do_AvBin16x8;
5223f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd16Sx8:  op = Pav_QADDS;  goto do_AvBin16x8;
5224f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Sub16x8:    op = Pav_SUBU;   goto do_AvBin16x8;
5225f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub16Ux8:  op = Pav_QSUBU;  goto do_AvBin16x8;
5226f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub16Sx8:  op = Pav_QSUBS;  goto do_AvBin16x8;
522736991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg16Ux8:   op = Pav_AVGU;   goto do_AvBin16x8;
522836991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg16Sx8:   op = Pav_AVGS;   goto do_AvBin16x8;
522936991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max16Ux8:   op = Pav_MAXU;   goto do_AvBin16x8;
523036991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max16Sx8:   op = Pav_MAXS;   goto do_AvBin16x8;
523136991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min16Ux8:   op = Pav_MINU;   goto do_AvBin16x8;
523236991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min16Sx8:   op = Pav_MINS;   goto do_AvBin16x8;
523324d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven16Ux8: op = Pav_OMULU;  goto do_AvBin16x8;
523424d06f124e3325e8edcc1c495d15736d5adcda96cerion      case Iop_MullEven16Sx8: op = Pav_OMULS;  goto do_AvBin16x8;
52350c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpEQ16x8:  op = Pav_CMPEQU; goto do_AvBin16x8;
52360c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT16Ux8: op = Pav_CMPGTU; goto do_AvBin16x8;
52370c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT16Sx8: op = Pav_CMPGTS; goto do_AvBin16x8;
52387deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd16x8: op = Pav_POLYMULADD; goto do_AvBin16x8;
523936991efdccc3af11ee9691dfa5297872dfb88312cerion      do_AvBin16x8: {
52401f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
52411f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
524236991efdccc3af11ee9691dfa5297872dfb88312cerion         HReg dst  = newVRegV(env);
52435b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin16x8(op, dst, arg1, arg2));
5244225a034683024109da729a4d2f080364b9485007cerion         return dst;
5245225a034683024109da729a4d2f080364b9485007cerion      }
5246d3e52410a03147c36dbf977a37e77a4de246f7c9cerion
52470a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shl32x4:    op = Pav_SHL;    goto do_AvBin32x4;
52480a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Shr32x4:    op = Pav_SHR;    goto do_AvBin32x4;
52490a7b4f40d11db65d00af3b0f51c23807dd83817fcerion      case Iop_Sar32x4:    op = Pav_SAR;    goto do_AvBin32x4;
52501bee561912427ca8f8998c89b62d86ba2ee49732sewardj      case Iop_Rol32x4:    op = Pav_ROTL;   goto do_AvBin32x4;
52515f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_NarrowBin32to16x8:    op = Pav_PACKUU;  goto do_AvBin32x4;
52525f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin32Uto16Ux8: op = Pav_QPACKUU; goto do_AvBin32x4;
52535f438dd73072211989c6d496845bdc9b777ecbecsewardj      case Iop_QNarrowBin32Sto16Sx8: op = Pav_QPACKSS; goto do_AvBin32x4;
5254c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveHI32x4:  op = Pav_MRGHI;  goto do_AvBin32x4;
5255c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj      case Iop_InterleaveLO32x4:  op = Pav_MRGLO;  goto do_AvBin32x4;
5256f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Add32x4:    op = Pav_ADDU;   goto do_AvBin32x4;
5257f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd32Ux4:  op = Pav_QADDU;  goto do_AvBin32x4;
5258f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QAdd32Sx4:  op = Pav_QADDS;  goto do_AvBin32x4;
5259f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_Sub32x4:    op = Pav_SUBU;   goto do_AvBin32x4;
5260f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub32Ux4:  op = Pav_QSUBU;  goto do_AvBin32x4;
5261f34ccc4ae06b8de99583c836fc15a571567b363acerion      case Iop_QSub32Sx4:  op = Pav_QSUBS;  goto do_AvBin32x4;
526236991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg32Ux4:   op = Pav_AVGU;   goto do_AvBin32x4;
526336991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Avg32Sx4:   op = Pav_AVGS;   goto do_AvBin32x4;
526436991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max32Ux4:   op = Pav_MAXU;   goto do_AvBin32x4;
526536991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Max32Sx4:   op = Pav_MAXS;   goto do_AvBin32x4;
526636991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min32Ux4:   op = Pav_MINU;   goto do_AvBin32x4;
526736991efdccc3af11ee9691dfa5297872dfb88312cerion      case Iop_Min32Sx4:   op = Pav_MINS;   goto do_AvBin32x4;
526848ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Mul32x4:    op = Pav_MULU;   goto do_AvBin32x4;
526948ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_MullEven32Ux4: op = Pav_OMULU;  goto do_AvBin32x4;
527048ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_MullEven32Sx4: op = Pav_OMULS;  goto do_AvBin32x4;
52710c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpEQ32x4:  op = Pav_CMPEQU; goto do_AvBin32x4;
52720c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT32Ux4: op = Pav_CMPGTU; goto do_AvBin32x4;
52730c43922a06643631fb78de1f6d5a00837c189e9bcerion      case Iop_CmpGT32Sx4: op = Pav_CMPGTS; goto do_AvBin32x4;
527448ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CatOddLanes32x4:  op = Pav_CATODD;  goto do_AvBin32x4;
527548ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CatEvenLanes32x4: op = Pav_CATEVEN; goto do_AvBin32x4;
52767deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd32x4: op = Pav_POLYMULADD; goto do_AvBin32x4;
5277d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      do_AvBin32x4: {
52781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
52791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
5280d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         HReg dst  = newVRegV(env);
52815b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32x4(op, dst, arg1, arg2));
5282d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         return dst;
5283d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      }
5284d3e52410a03147c36dbf977a37e77a4de246f7c9cerion
528548ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Shl64x2:    op = Pav_SHL;    goto do_AvBin64x2;
528648ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Shr64x2:    op = Pav_SHR;    goto do_AvBin64x2;
528748ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Sar64x2:    op = Pav_SAR;    goto do_AvBin64x2;
528848ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Rol64x2:    op = Pav_ROTL;   goto do_AvBin64x2;
52890c74bb5aa3240f693df0568d578baabf0c376dc4carll      case Iop_NarrowBin64to32x4:    op = Pav_PACKUU;  goto do_AvBin64x2;
529048ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_QNarrowBin64Sto32Sx4: op = Pav_QPACKSS; goto do_AvBin64x2;
529148ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_QNarrowBin64Uto32Ux4: op = Pav_QPACKUU; goto do_AvBin64x2;
529248ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_InterleaveHI64x2:  op = Pav_MRGHI;  goto do_AvBin64x2;
529348ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_InterleaveLO64x2:  op = Pav_MRGLO;  goto do_AvBin64x2;
52940c74bb5aa3240f693df0568d578baabf0c376dc4carll      case Iop_Add64x2:    op = Pav_ADDU;   goto do_AvBin64x2;
529548ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Sub64x2:    op = Pav_SUBU;   goto do_AvBin64x2;
529648ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Max64Ux2:   op = Pav_MAXU;   goto do_AvBin64x2;
529748ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Max64Sx2:   op = Pav_MAXS;   goto do_AvBin64x2;
529848ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Min64Ux2:   op = Pav_MINU;   goto do_AvBin64x2;
529948ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_Min64Sx2:   op = Pav_MINS;   goto do_AvBin64x2;
530048ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CmpEQ64x2:  op = Pav_CMPEQU; goto do_AvBin64x2;
530148ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CmpGT64Ux2: op = Pav_CMPGTU; goto do_AvBin64x2;
530248ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_CmpGT64Sx2: op = Pav_CMPGTS; goto do_AvBin64x2;
53037deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_PolynomialMulAdd64x2: op = Pav_POLYMULADD; goto do_AvBin64x2;
53040c74bb5aa3240f693df0568d578baabf0c376dc4carll      do_AvBin64x2: {
53051f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
53070c74bb5aa3240f693df0568d578baabf0c376dc4carll         HReg dst  = newVRegV(env);
53080c74bb5aa3240f693df0568d578baabf0c376dc4carll         addInstr(env, PPCInstr_AvBin64x2(op, dst, arg1, arg2));
53090c74bb5aa3240f693df0568d578baabf0c376dc4carll         return dst;
53100c74bb5aa3240f693df0568d578baabf0c376dc4carll      }
53110c74bb5aa3240f693df0568d578baabf0c376dc4carll
531292d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_ShlN8x16: op = Pav_SHL; goto do_AvShift8x16;
531392d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_SarN8x16: op = Pav_SAR; goto do_AvShift8x16;
531492d9d876af80d14fa2f319f7109964f2d6231f15cerion      do_AvShift8x16: {
53151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
531692d9d876af80d14fa2f319f7109964f2d6231f15cerion         HReg dst    = newVRegV(env);
53171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
53185b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin8x16(op, dst, r_src, v_shft));
531992d9d876af80d14fa2f319f7109964f2d6231f15cerion         return dst;
532092d9d876af80d14fa2f319f7109964f2d6231f15cerion      }
532192d9d876af80d14fa2f319f7109964f2d6231f15cerion
53223c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_ShlN16x8: op = Pav_SHL; goto do_AvShift16x8;
53233c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_ShrN16x8: op = Pav_SHR; goto do_AvShift16x8;
53243c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_SarN16x8: op = Pav_SAR; goto do_AvShift16x8;
53253c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      do_AvShift16x8: {
53261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53273c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion         HReg dst    = newVRegV(env);
53281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
53295b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin16x8(op, dst, r_src, v_shft));
53303c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion         return dst;
53313c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      }
53323c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion
53333c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_ShlN32x4: op = Pav_SHL; goto do_AvShift32x4;
5334d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      case Iop_ShrN32x4: op = Pav_SHR; goto do_AvShift32x4;
53353c052793dacedf702ca4b6ccbfb46a7efa7bc714cerion      case Iop_SarN32x4: op = Pav_SAR; goto do_AvShift32x4;
5336d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      do_AvShift32x4: {
53371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
5338d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         HReg dst    = newVRegV(env);
53391f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
53405b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBin32x4(op, dst, r_src, v_shft));
5341d3e52410a03147c36dbf977a37e77a4de246f7c9cerion         return dst;
5342d3e52410a03147c36dbf977a37e77a4de246f7c9cerion      }
5343d3e52410a03147c36dbf977a37e77a4de246f7c9cerion
534448ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_ShlN64x2: op = Pav_SHL; goto do_AvShift64x2;
534548ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_ShrN64x2: op = Pav_SHR; goto do_AvShift64x2;
534648ae46b56cef87c90638b25d6b2462c475033da8carll      case Iop_SarN64x2: op = Pav_SAR; goto do_AvShift64x2;
534748ae46b56cef87c90638b25d6b2462c475033da8carll      do_AvShift64x2: {
53481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
534948ae46b56cef87c90638b25d6b2462c475033da8carll         HReg dst    = newVRegV(env);
53501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
535148ae46b56cef87c90638b25d6b2462c475033da8carll         addInstr(env, PPCInstr_AvBin64x2(op, dst, r_src, v_shft));
535248ae46b56cef87c90638b25d6b2462c475033da8carll         return dst;
535348ae46b56cef87c90638b25d6b2462c475033da8carll      }
535448ae46b56cef87c90638b25d6b2462c475033da8carll
535527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      case Iop_ShrV128: op = Pav_SHR; goto do_AvShiftV128;
535692d9d876af80d14fa2f319f7109964f2d6231f15cerion      case Iop_ShlV128: op = Pav_SHL; goto do_AvShiftV128;
535727b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      do_AvShiftV128: {
535827b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         HReg dst    = newVRegV(env);
53591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src  = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2, IEndianess);
536192d9d876af80d14fa2f319f7109964f2d6231f15cerion         /* Note: shift value gets masked by 127 */
53625b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvBinary(op, dst, r_src, v_shft));
536327b3d7ec17c3a0814d4980db87defbb4f07339bfcerion         return dst;
536427b3d7ec17c3a0814d4980db87defbb4f07339bfcerion      }
536527b3d7ec17c3a0814d4980db87defbb4f07339bfcerion
5366dc1f91317b466ccabbe21bf0feda19658d5b614bsewardj      case Iop_Perm8x16: {
536792d9d876af80d14fa2f319f7109964f2d6231f15cerion         HReg dst   = newVRegV(env);
53681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_ctl = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
53705b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvPerm(dst, v_src, v_src, v_ctl));
537192d9d876af80d14fa2f319f7109964f2d6231f15cerion         return dst;
537292d9d876af80d14fa2f319f7109964f2d6231f15cerion      }
537392d9d876af80d14fa2f319f7109964f2d6231f15cerion
53747deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_CipherV128:  op = Pav_CIPHERV128;   goto do_AvCipherV128;
53757deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_CipherLV128: op = Pav_CIPHERLV128;  goto do_AvCipherV128;
53767deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_NCipherV128: op = Pav_NCIPHERV128;  goto do_AvCipherV128;
53777deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_NCipherLV128:op = Pav_NCIPHERLV128; goto do_AvCipherV128;
53787deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvCipherV128: {
53791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
53817deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst  = newVRegV(env);
53827deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvCipherV128Binary(op, dst, arg1, arg2));
53837deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
53847deaf9552b546b847528cf39b38898fb7742b5f5carll      }
53857deaf9552b546b847528cf39b38898fb7742b5f5carll
53867deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_SHA256:op = Pav_SHA256; goto do_AvHashV128;
53877deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_SHA512:op = Pav_SHA512; goto do_AvHashV128;
53887deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvHashV128: {
53891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
53907deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst  = newVRegV(env);
53911f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* s_field = iselWordExpr_RI(env, e->Iex.Binop.arg2, IEndianess);
53927deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvHashV128Binary(op, dst, arg1, s_field));
53937deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
53947deaf9552b546b847528cf39b38898fb7742b5f5carll      }
5395f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      default:
5396f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion         break;
5397f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion      } /* switch (e->Iex.Binop.op) */
5398f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion   } /* if (e->tag == Iex_Binop) */
5399f5936dc5ae19b923b5f0a6b9b8df9ec8d395555ccerion
54007deaf9552b546b847528cf39b38898fb7742b5f5carll   if (e->tag == Iex_Triop) {
54017deaf9552b546b847528cf39b38898fb7742b5f5carll      IRTriop *triop = e->Iex.Triop.details;
54027deaf9552b546b847528cf39b38898fb7742b5f5carll      switch (triop->op) {
54037deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_BCDAdd:op = Pav_BCDAdd; goto do_AvBCDV128;
54047deaf9552b546b847528cf39b38898fb7742b5f5carll      case Iop_BCDSub:op = Pav_BCDSub; goto do_AvBCDV128;
54057deaf9552b546b847528cf39b38898fb7742b5f5carll      do_AvBCDV128: {
54061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg1 = iselVecExpr(env, triop->arg1, IEndianess);
54071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg arg2 = iselVecExpr(env, triop->arg2, IEndianess);
54087deaf9552b546b847528cf39b38898fb7742b5f5carll         HReg dst  = newVRegV(env);
54091f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCRI* ps = iselWordExpr_RI(env, triop->arg3, IEndianess);
54107deaf9552b546b847528cf39b38898fb7742b5f5carll         addInstr(env, PPCInstr_AvBCDV128Trinary(op, dst, arg1, arg2, ps));
54117deaf9552b546b847528cf39b38898fb7742b5f5carll         return dst;
54127deaf9552b546b847528cf39b38898fb7742b5f5carll      }
54137deaf9552b546b847528cf39b38898fb7742b5f5carll
541420a760ec66a13a93147a40d3c3530be21d7fe411sewardj      case Iop_Add32Fx4: fpop = Pavfp_ADDF; goto do_32Fx4_with_rm;
541520a760ec66a13a93147a40d3c3530be21d7fe411sewardj      case Iop_Sub32Fx4: fpop = Pavfp_SUBF; goto do_32Fx4_with_rm;
541620a760ec66a13a93147a40d3c3530be21d7fe411sewardj      case Iop_Mul32Fx4: fpop = Pavfp_MULF; goto do_32Fx4_with_rm;
541720a760ec66a13a93147a40d3c3530be21d7fe411sewardj      do_32Fx4_with_rm:
541820a760ec66a13a93147a40d3c3530be21d7fe411sewardj      {
54191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argL = iselVecExpr(env, triop->arg2, IEndianess);
54201f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg argR = iselVecExpr(env, triop->arg3, IEndianess);
542120a760ec66a13a93147a40d3c3530be21d7fe411sewardj         HReg dst  = newVRegV(env);
542220a760ec66a13a93147a40d3c3530be21d7fe411sewardj         /* FIXME: this is bogus, in the sense that Altivec ignores
542320a760ec66a13a93147a40d3c3530be21d7fe411sewardj            FPSCR.RM, at least for some FP operations.  So setting the
542420a760ec66a13a93147a40d3c3530be21d7fe411sewardj            RM is pointless.  This is only really correct in the case
542520a760ec66a13a93147a40d3c3530be21d7fe411sewardj            where the RM is known, at JIT time, to be Irrm_NEAREST,
542620a760ec66a13a93147a40d3c3530be21d7fe411sewardj            since -- at least for Altivec FP add/sub/mul -- the
542720a760ec66a13a93147a40d3c3530be21d7fe411sewardj            emitted insn is hardwired to round to nearest. */
54281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         set_FPU_rounding_mode(env, triop->arg1, IEndianess);
542920a760ec66a13a93147a40d3c3530be21d7fe411sewardj         addInstr(env, PPCInstr_AvBin32Fx4(fpop, dst, argL, argR));
543020a760ec66a13a93147a40d3c3530be21d7fe411sewardj         return dst;
543120a760ec66a13a93147a40d3c3530be21d7fe411sewardj      }
543220a760ec66a13a93147a40d3c3530be21d7fe411sewardj
54337deaf9552b546b847528cf39b38898fb7742b5f5carll      default:
54347deaf9552b546b847528cf39b38898fb7742b5f5carll         break;
54357deaf9552b546b847528cf39b38898fb7742b5f5carll      } /* switch (e->Iex.Triop.op) */
54367deaf9552b546b847528cf39b38898fb7742b5f5carll   } /* if (e->tag == Iex_Trinop) */
54377deaf9552b546b847528cf39b38898fb7742b5f5carll
54387deaf9552b546b847528cf39b38898fb7742b5f5carll
5439cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   if (e->tag == Iex_Const ) {
5440cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion      vassert(e->Iex.Const.con->tag == Ico_V128);
5441cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion      if (e->Iex.Const.con->Ico.V128 == 0x0000) {
5442cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion         return generate_zeroes_V128(env);
5443d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj      }
5444d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj      else if (e->Iex.Const.con->Ico.V128 == 0xffff) {
5445d2b1816d5a45eab742a6a7716a38133d2d47d66esewardj         return generate_ones_V128(env);
5446cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion      }
5447cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion   }
5448cd90bfe9a039fb52f46065da04ba5e892541a5d5cerion
54495b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vex_printf("iselVecExpr(ppc) (subarch = %s): can't reduce\n",
54505117ce116f47141cb23d1b49cc826e19323add97sewardj              LibVEX_ppVexHwCaps(mode64 ? VexArchPPC64 : VexArchPPC32,
54515117ce116f47141cb23d1b49cc826e19323add97sewardj                                 env->hwcaps));
5452e21595a704c11ce19b8cd73df03fdcbe483517eecerion   ppIRExpr(e);
54535b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselVecExpr_wrk(ppc)");
5454e21595a704c11ce19b8cd73df03fdcbe483517eecerion}
5455bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
5456bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
5457bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
5458bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- ISEL: Statements                                  ---*/
5459bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
5460bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
54611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarllstatic void iselStmt ( ISelEnv* env, IRStmt* stmt, IREndness IEndianess )
5462bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion{
54634628ccd1bafb946378f91849b92ffcfea0267b2ecerion   Bool mode64 = env->mode64;
5464bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   if (vex_traceflags & VEX_TRACE_VCODE) {
54652c49e036c365df707cd8e6622d66382f380557b2cerion      vex_printf("\n -- ");
5466bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      ppIRStmt(stmt);
5467bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      vex_printf("\n");
5468bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
5469a50fde5504e829e5154113d7e507f12707089f48cerion
5470bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   switch (stmt->tag) {
5471bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
54722c49e036c365df707cd8e6622d66382f380557b2cerion   /* --------- STORE --------- */
5473af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj   case Ist_Store: {
5474e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRType    tya   = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
5475e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IRType    tyd   = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
5476e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      IREndness end   = stmt->Ist.Store.end;
5477af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj
54781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      if (end != IEndianess)
5479e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         goto stmt_fail;
5480e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      if (!mode64 && (tya != Ity_I32))
5481e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj         goto stmt_fail;
5482e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj      if (mode64 && (tya != Ity_I64))
5483af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj         goto stmt_fail;
5484ed623dbefb52ca3211490d656abc999a129df060cerion
5485f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (tyd == Ity_I8 || tyd == Ity_I16 || tyd == Ity_I32 ||
5486f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          (mode64 && (tyd == Ity_I64))) {
5487e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
54881f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
54891f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
54901f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, stmt->Ist.Store.data, IEndianess);
54915b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( toUChar(sizeofIRType(tyd)),
5492e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       am_addr, r_src, mode64 ));
54932c49e036c365df707cd8e6622d66382f380557b2cerion         return;
54942c49e036c365df707cd8e6622d66382f380557b2cerion      }
5495094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (tyd == Ity_F64) {
5496e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
54971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
54981f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
54991f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, stmt->Ist.Store.data, IEndianess);
55005b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55015b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_FpLdSt(False/*store*/, 8, fr_src, am_addr));
5502094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5503094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
5504094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (tyd == Ity_F32) {
5505e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
55061f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55081f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselFltExpr(env, stmt->Ist.Store.data, IEndianess);
55095b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55105b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_FpLdSt(False/*store*/, 4, fr_src, am_addr));
5511094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5512094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
5513f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (tyd == Ity_D64) {
5514f704eb2bab3d06d983c850b0bcf243e178060f75carll         PPCAMode* am_addr
55151f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55161f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55171f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr(env, stmt->Ist.Store.data, IEndianess);
5518f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env,
5519f704eb2bab3d06d983c850b0bcf243e178060f75carll                  PPCInstr_FpLdSt(False/*store*/, 8, fr_src, am_addr));
5520f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5521f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
5522f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (tyd == Ity_D32) {
5523f704eb2bab3d06d983c850b0bcf243e178060f75carll         PPCAMode* am_addr
55241f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55261f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr(env, stmt->Ist.Store.data, IEndianess);
5527f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env,
5528f704eb2bab3d06d983c850b0bcf243e178060f75carll                  PPCInstr_FpLdSt(False/*store*/, 4, fr_src, am_addr));
5529f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5530f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
5531e21595a704c11ce19b8cd73df03fdcbe483517eecerion      if (tyd == Ity_V128) {
5532e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         PPCAMode* am_addr
55331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/,
55341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                 IEndianess);
55351f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, stmt->Ist.Store.data, IEndianess);
55365b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55375b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt(False/*store*/, 16, v_src, am_addr));
5538e21595a704c11ce19b8cd73df03fdcbe483517eecerion         return;
5539e21595a704c11ce19b8cd73df03fdcbe483517eecerion      }
5540e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      if (tyd == Ity_I64 && !mode64) {
5541e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         /* Just calculate the address in the register.  Life is too
5542e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj            short to arse around trying and possibly failing to adjust
5543e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj            the offset in a 'reg+offset' style amode. */
5544e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         HReg rHi32, rLo32;
55451f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_addr = iselWordExpr_R(env, stmt->Ist.Store.addr, IEndianess);
55461f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr( &rHi32, &rLo32, env, stmt->Ist.Store.data,
55471f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess );
5548e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         addInstr(env, PPCInstr_Store( 4/*byte-store*/,
5549e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       PPCAMode_IR( 0, r_addr ),
5550e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       rHi32,
5551e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       False/*32-bit insn please*/) );
5552e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         addInstr(env, PPCInstr_Store( 4/*byte-store*/,
5553e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       PPCAMode_IR( 4, r_addr ),
5554e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       rLo32,
5555e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj                                       False/*32-bit insn please*/) );
5556e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj         return;
5557e2957d6819b03cba323f4dd1fa805860b5d238fdsewardj      }
55582c49e036c365df707cd8e6622d66382f380557b2cerion      break;
55592c49e036c365df707cd8e6622d66382f380557b2cerion   }
5560cd304497d9d869f9b24a002299d3953ee072229bcerion
5561cd304497d9d869f9b24a002299d3953ee072229bcerion   /* --------- PUT --------- */
5562cd304497d9d869f9b24a002299d3953ee072229bcerion   case Ist_Put: {
5563cd304497d9d869f9b24a002299d3953ee072229bcerion      IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);
5564f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (ty == Ity_I8  || ty == Ity_I16 ||
5565f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          ty == Ity_I32 || ((ty == Ity_I64) && mode64)) {
55661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, stmt->Ist.Put.data, IEndianess);
55675b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
55685b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                          GuestStatePtr(mode64) );
55695b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( toUChar(sizeofIRType(ty)),
55705b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                       am_addr, r_src, mode64 ));
5571cd304497d9d869f9b24a002299d3953ee072229bcerion         return;
5572cd304497d9d869f9b24a002299d3953ee072229bcerion      }
5573f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (!mode64 && ty == Ity_I64) {
557402d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion         HReg rHi, rLo;
55755b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr  = PPCAMode_IR( stmt->Ist.Put.offset,
55765b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           GuestStatePtr(mode64) );
55775b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr4 = advance4(env, am_addr);
55781f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&rHi,&rLo, env, stmt->Ist.Put.data, IEndianess);
55795b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_addr,  rHi, mode64 ));
55805b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Store( 4, am_addr4, rLo, mode64 ));
558102d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion         return;
558202d0cb3ea12b04c79adc349a36c9ebb2efce77bacerion     }
5583a50fde5504e829e5154113d7e507f12707089f48cerion     if (ty == Ity_V128) {
55845b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         /* Guest state vectors are 16byte aligned,
55855b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion            so don't need to worry here */
55861f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, stmt->Ist.Put.data, IEndianess);
55875b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr  = PPCAMode_IR( stmt->Ist.Put.offset,
55885b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                           GuestStatePtr(mode64) );
55895b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env,
55905b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                  PPCInstr_AvLdSt(False/*store*/, 16, v_src, am_addr));
5591a50fde5504e829e5154113d7e507f12707089f48cerion         return;
5592a50fde5504e829e5154113d7e507f12707089f48cerion      }
5593094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (ty == Ity_F64) {
55941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, stmt->Ist.Put.data, IEndianess);
55955b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
55965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                          GuestStatePtr(mode64) );
55975b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
55985b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion                                        fr_src, am_addr ));
5599094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5600094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
5601f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (ty == Ity_D32) {
5602f704eb2bab3d06d983c850b0bcf243e178060f75carll         /* The 32-bit value is stored in a 64-bit register */
56031f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr( env, stmt->Ist.Put.data, IEndianess );
5604f704eb2bab3d06d983c850b0bcf243e178060f75carll         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
5605f704eb2bab3d06d983c850b0bcf243e178060f75carll                                          GuestStatePtr(mode64) );
5606f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr( env, PPCInstr_FpLdSt( False/*store*/, 8,
5607f704eb2bab3d06d983c850b0bcf243e178060f75carll                                         fr_src, am_addr ) );
5608f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5609f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
5610c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (ty == Ity_D64) {
56111f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr( env, stmt->Ist.Put.data, IEndianess );
5612c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
5613c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                          GuestStatePtr(mode64) );
5614c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_FpLdSt( False/*store*/, 8, fr_src, am_addr ) );
5615c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5616c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
5617cd304497d9d869f9b24a002299d3953ee072229bcerion      break;
5618cd304497d9d869f9b24a002299d3953ee072229bcerion   }
5619ab9132df645da753ae6b0421d551ea5c024aa6e6cerion
56206e53088a92d40be75cc362986956ac149b3fa94bsewardj   /* --------- Indexed PUT --------- */
5621aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   case Ist_PutI: {
5622d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRPutI *puti = stmt->Ist.PutI.details;
5623d6f38b3f822f7d57adfc0da3410995d85d6a4597florian
5624aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      PPCAMode* dst_am
5625aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         = genGuestArrayOffset(
5626d6f38b3f822f7d57adfc0da3410995d85d6a4597florian              env, puti->descr,
56271f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll              puti->ix, puti->bias,
56281f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll              IEndianess );
5629d6f38b3f822f7d57adfc0da3410995d85d6a4597florian      IRType ty = typeOfIRExpr(env->type_env, puti->data);
5630aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      if (mode64 && ty == Ity_I64) {
56311f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, puti->data, IEndianess);
5632aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         addInstr(env, PPCInstr_Store( toUChar(8),
5633aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                       dst_am, r_src, mode64 ));
5634aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         return;
5635aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      }
5636aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj      if ((!mode64) && ty == Ity_I32) {
56371f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, puti->data, IEndianess);
5638aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         addInstr(env, PPCInstr_Store( toUChar(4),
5639aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj                                       dst_am, r_src, mode64 ));
5640aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj         return;
56416e53088a92d40be75cc362986956ac149b3fa94bsewardj      }
56426e53088a92d40be75cc362986956ac149b3fa94bsewardj      break;
5643aca070a5b3418a6a9b01e3c57a7eb0fbb5050908sewardj   }
5644cd304497d9d869f9b24a002299d3953ee072229bcerion
5645cd304497d9d869f9b24a002299d3953ee072229bcerion   /* --------- TMP --------- */
5646dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   case Ist_WrTmp: {
5647dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      IRTemp tmp = stmt->Ist.WrTmp.tmp;
5648cd304497d9d869f9b24a002299d3953ee072229bcerion      IRType ty = typeOfIRTemp(env->type_env, tmp);
5649f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (ty == Ity_I8  || ty == Ity_I16 ||
5650f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion          ty == Ity_I32 || ((ty == Ity_I64) && mode64)) {
5651a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = lookupIRTemp(env, tmp);
56521f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_src = iselWordExpr_R(env, stmt->Ist.WrTmp.data, IEndianess);
5653a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         addInstr(env, mk_iMOVds_RR( r_dst, r_src ));
5654cd304497d9d869f9b24a002299d3953ee072229bcerion         return;
5655cd304497d9d869f9b24a002299d3953ee072229bcerion      }
5656f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      if (!mode64 && ty == Ity_I64) {
565784ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         HReg r_srcHi, r_srcLo, r_dstHi, r_dstLo;
5658c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
56591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt64Expr(&r_srcHi,&r_srcLo, env, stmt->Ist.WrTmp.data,
56601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                       IEndianess);
56612bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         lookupIRTempPair( &r_dstHi, &r_dstLo, env, tmp);
566284ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         addInstr(env, mk_iMOVds_RR(r_dstHi, r_srcHi) );
566384ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         addInstr(env, mk_iMOVds_RR(r_dstLo, r_srcLo) );
566484ad616686a2c29be1c2b1f65f72ae79820a84c4cerion         return;
566584ad616686a2c29be1c2b1f65f72ae79820a84c4cerion      }
5666bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      if (mode64 && ty == Ity_I128) {
5667bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         HReg r_srcHi, r_srcLo, r_dstHi, r_dstLo;
56681f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselInt128Expr(&r_srcHi,&r_srcLo, env, stmt->Ist.WrTmp.data,
56691f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                        IEndianess);
56702bb062db199d9799e1259ab608e8a1aea3bb29a3sewardj         lookupIRTempPair( &r_dstHi, &r_dstLo, env, tmp);
5671bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         addInstr(env, mk_iMOVds_RR(r_dstHi, r_srcHi) );
5672bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         addInstr(env, mk_iMOVds_RR(r_dstLo, r_srcLo) );
5673bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         return;
5674bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      }
5675c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (!mode64 && ty == Ity_I128) {
5676c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_srcHi, r_srcMedHi, r_srcMedLo, r_srcLo;
5677c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg r_dstHi, r_dstMedHi, r_dstMedLo, r_dstLo;
5678c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
5679c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         iselInt128Expr_to_32x4(&r_srcHi, &r_srcMedHi,
5680c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                &r_srcMedLo, &r_srcLo,
56811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                env, stmt->Ist.WrTmp.data, IEndianess);
5682c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
5683c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         lookupIRTempQuad( &r_dstHi, &r_dstMedHi, &r_dstMedLo,
5684c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                           &r_dstLo, env, tmp);
5685c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
5686c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstHi,    r_srcHi) );
5687c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstMedHi, r_srcMedHi) );
5688c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstMedLo, r_srcMedLo) );
5689c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr(env, mk_iMOVds_RR(r_dstLo,    r_srcLo) );
5690c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5691c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
56929abfcbca0696407c4b781b9395298c5edffa33a0cerion      if (ty == Ity_I1) {
56931f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         PPCCondCode cond = iselCondCode(env, stmt->Ist.WrTmp.data,
56941f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                         IEndianess);
5695a2f75883f769b3cf13c32d5321cc9a6b7fcea9a6cerion         HReg r_dst = lookupIRTemp(env, tmp);
56965b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_Set(cond, r_dst));
56979abfcbca0696407c4b781b9395298c5edffa33a0cerion         return;
56989abfcbca0696407c4b781b9395298c5edffa33a0cerion      }
5699094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      if (ty == Ity_F64) {
5700094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         HReg fr_dst = lookupIRTemp(env, tmp);
57011f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDblExpr(env, stmt->Ist.WrTmp.data, IEndianess);
57025b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpUnary(Pfp_MOV, fr_dst, fr_src));
5703094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion         return;
5704094d1397b3f69b1a538e80ab509ea8cd75f4be3bcerion      }
57056587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      if (ty == Ity_F32) {
57066587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         HReg fr_dst = lookupIRTemp(env, tmp);
57071f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselFltExpr(env, stmt->Ist.WrTmp.data, IEndianess);
57085b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_FpUnary(Pfp_MOV, fr_dst, fr_src));
57096587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         return;
57106587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      }
5711f704eb2bab3d06d983c850b0bcf243e178060f75carll      if (ty == Ity_D32) {
5712f704eb2bab3d06d983c850b0bcf243e178060f75carll         HReg fr_dst = lookupIRTemp(env, tmp);
57131f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp32Expr(env, stmt->Ist.WrTmp.data, IEndianess);
5714f704eb2bab3d06d983c850b0bcf243e178060f75carll         addInstr(env, PPCInstr_Dfp64Unary(Pfp_MOV, fr_dst, fr_src));
5715f704eb2bab3d06d983c850b0bcf243e178060f75carll         return;
5716f704eb2bab3d06d983c850b0bcf243e178060f75carll      }
57176587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      if (ty == Ity_V128) {
57186587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         HReg v_dst = lookupIRTemp(env, tmp);
57191f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg v_src = iselVecExpr(env, stmt->Ist.WrTmp.data, IEndianess);
57205b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         addInstr(env, PPCInstr_AvUnary(Pav_MOV, v_dst, v_src));
57216587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion         return;
57226587f2fb1f591415e65c5f347b8c6b5cabbdfed8cerion      }
5723c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (ty == Ity_D64) {
5724c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg fr_dst = lookupIRTemp( env, tmp );
57251f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg fr_src = iselDfp64Expr( env, stmt->Ist.WrTmp.data, IEndianess );
5726c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Unary( Pfp_MOV, fr_dst, fr_src ) );
5727c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5728c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
5729c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (ty == Ity_D128) {
5730c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         HReg fr_srcHi, fr_srcLo, fr_dstHi, fr_dstLo;
5731c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj	 //         lookupDfp128IRTempPair( &fr_dstHi, &fr_dstLo, env, tmp );
5732c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         lookupIRTempPair( &fr_dstHi, &fr_dstLo, env, tmp );
57331f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         iselDfp128Expr( &fr_srcHi, &fr_srcLo, env, stmt->Ist.WrTmp.data,
57341f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                         IEndianess );
5735c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Unary( Pfp_MOV, fr_dstHi, fr_srcHi ) );
5736c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         addInstr( env, PPCInstr_Dfp64Unary( Pfp_MOV, fr_dstLo, fr_srcLo ) );
5737c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         return;
5738c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
5739cd304497d9d869f9b24a002299d3953ee072229bcerion      break;
5740cd304497d9d869f9b24a002299d3953ee072229bcerion   }
5741cd304497d9d869f9b24a002299d3953ee072229bcerion
5742e768e92e054cde495849a5c842a477d287677f78sewardj   /* --------- Load Linked or Store Conditional --------- */
5743e768e92e054cde495849a5c842a477d287677f78sewardj   case Ist_LLSC: {
5744e768e92e054cde495849a5c842a477d287677f78sewardj      IRTemp res    = stmt->Ist.LLSC.result;
5745e768e92e054cde495849a5c842a477d287677f78sewardj      IRType tyRes  = typeOfIRTemp(env->type_env, res);
5746e768e92e054cde495849a5c842a477d287677f78sewardj      IRType tyAddr = typeOfIRExpr(env->type_env, stmt->Ist.LLSC.addr);
5747e768e92e054cde495849a5c842a477d287677f78sewardj
57481f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      if (stmt->Ist.LLSC.end != IEndianess)
5749e768e92e054cde495849a5c842a477d287677f78sewardj         goto stmt_fail;
5750e768e92e054cde495849a5c842a477d287677f78sewardj      if (!mode64 && (tyAddr != Ity_I32))
5751e768e92e054cde495849a5c842a477d287677f78sewardj         goto stmt_fail;
5752e768e92e054cde495849a5c842a477d287677f78sewardj      if (mode64 && (tyAddr != Ity_I64))
5753e768e92e054cde495849a5c842a477d287677f78sewardj         goto stmt_fail;
5754e768e92e054cde495849a5c842a477d287677f78sewardj
5755e768e92e054cde495849a5c842a477d287677f78sewardj      if (stmt->Ist.LLSC.storedata == NULL) {
5756e768e92e054cde495849a5c842a477d287677f78sewardj         /* LL */
57571f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg r_addr = iselWordExpr_R( env, stmt->Ist.LLSC.addr, IEndianess );
5758e768e92e054cde495849a5c842a477d287677f78sewardj         HReg r_dst  = lookupIRTemp(env, res);
5759d826889bd512ded2fbbc4781c595ecf0513f46f6carll         if (tyRes == Ity_I8) {
5760d826889bd512ded2fbbc4781c595ecf0513f46f6carll            addInstr(env, PPCInstr_LoadL( 1, r_dst, r_addr, mode64 ));
5761d826889bd512ded2fbbc4781c595ecf0513f46f6carll            return;
5762d826889bd512ded2fbbc4781c595ecf0513f46f6carll         }
5763d826889bd512ded2fbbc4781c595ecf0513f46f6carll         if (tyRes == Ity_I16) {
5764d826889bd512ded2fbbc4781c595ecf0513f46f6carll            addInstr(env, PPCInstr_LoadL( 2, r_dst, r_addr, mode64 ));
5765d826889bd512ded2fbbc4781c595ecf0513f46f6carll            return;
5766d826889bd512ded2fbbc4781c595ecf0513f46f6carll         }
5767e768e92e054cde495849a5c842a477d287677f78sewardj         if (tyRes == Ity_I32) {
5768e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_LoadL( 4, r_dst, r_addr, mode64 ));
5769e768e92e054cde495849a5c842a477d287677f78sewardj            return;
5770e768e92e054cde495849a5c842a477d287677f78sewardj         }
5771e768e92e054cde495849a5c842a477d287677f78sewardj         if (tyRes == Ity_I64 && mode64) {
5772e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_LoadL( 8, r_dst, r_addr, mode64 ));
5773e768e92e054cde495849a5c842a477d287677f78sewardj            return;
5774e768e92e054cde495849a5c842a477d287677f78sewardj         }
5775e768e92e054cde495849a5c842a477d287677f78sewardj         /* fallthru */;
5776e768e92e054cde495849a5c842a477d287677f78sewardj      } else {
5777e768e92e054cde495849a5c842a477d287677f78sewardj         /* SC */
5778e768e92e054cde495849a5c842a477d287677f78sewardj         HReg   r_res  = lookupIRTemp(env, res); /* :: Ity_I1 */
57791f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_a    = iselWordExpr_R(env, stmt->Ist.LLSC.addr, IEndianess);
57801f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg   r_src  = iselWordExpr_R(env, stmt->Ist.LLSC.storedata,
57811f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                        IEndianess);
5782e768e92e054cde495849a5c842a477d287677f78sewardj         HReg   r_tmp  = newVRegI(env);
5783e768e92e054cde495849a5c842a477d287677f78sewardj         IRType tyData = typeOfIRExpr(env->type_env,
5784e768e92e054cde495849a5c842a477d287677f78sewardj                                      stmt->Ist.LLSC.storedata);
5785e768e92e054cde495849a5c842a477d287677f78sewardj         vassert(tyRes == Ity_I1);
5786d826889bd512ded2fbbc4781c595ecf0513f46f6carll         if (tyData == Ity_I8 || tyData == Ity_I16 || tyData == Ity_I32 ||
5787d826889bd512ded2fbbc4781c595ecf0513f46f6carll            (tyData == Ity_I64 && mode64)) {
5788d826889bd512ded2fbbc4781c595ecf0513f46f6carll            int size = 0;
5789d826889bd512ded2fbbc4781c595ecf0513f46f6carll
5790d826889bd512ded2fbbc4781c595ecf0513f46f6carll            if (tyData == Ity_I64)
5791d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 8;
5792d826889bd512ded2fbbc4781c595ecf0513f46f6carll            else if (tyData == Ity_I32)
5793d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 4;
5794d826889bd512ded2fbbc4781c595ecf0513f46f6carll            else if (tyData == Ity_I16)
5795d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 2;
5796d826889bd512ded2fbbc4781c595ecf0513f46f6carll            else if (tyData == Ity_I8)
5797d826889bd512ded2fbbc4781c595ecf0513f46f6carll               size = 1;
5798d826889bd512ded2fbbc4781c595ecf0513f46f6carll
5799d826889bd512ded2fbbc4781c595ecf0513f46f6carll            addInstr(env, PPCInstr_StoreC( size,
5800e768e92e054cde495849a5c842a477d287677f78sewardj                                           r_a, r_src, mode64 ));
5801e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_MfCR( r_tmp ));
5802e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_Shft(
5803e768e92e054cde495849a5c842a477d287677f78sewardj                             Pshft_SHR,
5804e768e92e054cde495849a5c842a477d287677f78sewardj                             env->mode64 ? False : True
5805e768e92e054cde495849a5c842a477d287677f78sewardj                                /*F:64-bit, T:32-bit shift*/,
5806e768e92e054cde495849a5c842a477d287677f78sewardj                             r_tmp, r_tmp,
5807e768e92e054cde495849a5c842a477d287677f78sewardj                             PPCRH_Imm(False/*unsigned*/, 29)));
5808e768e92e054cde495849a5c842a477d287677f78sewardj            /* Probably unnecessary, since the IR dest type is Ity_I1,
5809e768e92e054cde495849a5c842a477d287677f78sewardj               and so we are entitled to leave whatever junk we like
5810e768e92e054cde495849a5c842a477d287677f78sewardj               drifting round in the upper 31 or 63 bits of r_res.
5811e768e92e054cde495849a5c842a477d287677f78sewardj               However, for the sake of conservativeness .. */
5812e768e92e054cde495849a5c842a477d287677f78sewardj            addInstr(env, PPCInstr_Alu(
5813e768e92e054cde495849a5c842a477d287677f78sewardj                             Palu_AND,
5814e768e92e054cde495849a5c842a477d287677f78sewardj                             r_res, r_tmp,
5815e768e92e054cde495849a5c842a477d287677f78sewardj                             PPCRH_Imm(False/*signed*/, 1)));
5816e768e92e054cde495849a5c842a477d287677f78sewardj            return;
5817e768e92e054cde495849a5c842a477d287677f78sewardj         }
5818e768e92e054cde495849a5c842a477d287677f78sewardj         /* fallthru */
5819e768e92e054cde495849a5c842a477d287677f78sewardj      }
5820e768e92e054cde495849a5c842a477d287677f78sewardj      goto stmt_fail;
5821e768e92e054cde495849a5c842a477d287677f78sewardj      /*NOTREACHED*/
5822e768e92e054cde495849a5c842a477d287677f78sewardj   }
5823e768e92e054cde495849a5c842a477d287677f78sewardj
5824ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- Call to DIRTY helper --------- */
5825ed623dbefb52ca3211490d656abc999a129df060cerion   case Ist_Dirty: {
5826ed623dbefb52ca3211490d656abc999a129df060cerion      IRDirty* d = stmt->Ist.Dirty.details;
5827ed623dbefb52ca3211490d656abc999a129df060cerion
5828cfe046e178666280b87da998b1b52ecda03ecd89sewardj      /* Figure out the return type, if any. */
5829cfe046e178666280b87da998b1b52ecda03ecd89sewardj      IRType retty = Ity_INVALID;
5830cfe046e178666280b87da998b1b52ecda03ecd89sewardj      if (d->tmp != IRTemp_INVALID)
5831cfe046e178666280b87da998b1b52ecda03ecd89sewardj         retty = typeOfIRTemp(env->type_env, d->tmp);
5832cfe046e178666280b87da998b1b52ecda03ecd89sewardj
58337842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj      /* Throw out any return types we don't know about.  The set of
58347842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         acceptable return types is the same in both 32- and 64-bit
58357842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         mode, so we don't need to inspect mode64 to make a
58367842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         decision. */
583774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      Bool retty_ok = False;
58387842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj      switch (retty) {
58397842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         case Ity_INVALID: /* function doesn't return anything */
58407842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         case Ity_V128:
58417842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         case Ity_I64: case Ity_I32: case Ity_I16: case Ity_I8:
58427842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj            retty_ok = True; break;
58437842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj         default:
58447842cafd3abae5b7ceeaf783f1d4986fe6a7234csewardj            break;
5845cfe046e178666280b87da998b1b52ecda03ecd89sewardj      }
584674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      if (!retty_ok)
5847cfe046e178666280b87da998b1b52ecda03ecd89sewardj         break; /* will go to stmt_fail: */
5848cfe046e178666280b87da998b1b52ecda03ecd89sewardj
584974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      /* Marshal args, do the call, clear stack, set the return value
585074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         to 0x555..555 if this is a conditional call that returns a
585174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         value and the call is skipped. */
585274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      UInt   addToSp = 0;
585374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      RetLoc rloc    = mk_RetLoc_INVALID();
58541f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      doHelperCall( &addToSp, &rloc, env, d->guard, d->cee, retty, d->args,
58551f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                    IEndianess );
585674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      vassert(is_sane_RetLoc(rloc));
5857ed623dbefb52ca3211490d656abc999a129df060cerion
5858ed623dbefb52ca3211490d656abc999a129df060cerion      /* Now figure out what to do with the returned value, if any. */
585974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj      switch (retty) {
586074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_INVALID: {
586174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* No return value.  Nothing to do. */
586274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(d->tmp == IRTemp_INVALID);
586374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(rloc.pri == RLPri_None);
586474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(addToSp == 0);
586574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
586674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
586774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_I32: case Ity_I16: case Ity_I8: {
586874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* The returned value is in %r3.  Park it in the register
586974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               associated with tmp. */
587074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            HReg r_dst = lookupIRTemp(env, d->tmp);
587174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
587274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(rloc.pri == RLPri_Int);
587374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(addToSp == 0);
587474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
587574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
587674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_I64:
587774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            if (mode64) {
587874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               /* The returned value is in %r3.  Park it in the register
587974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  associated with tmp. */
588074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               HReg r_dst = lookupIRTemp(env, d->tmp);
588174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
588274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(rloc.pri == RLPri_Int);
588374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(addToSp == 0);
588474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            } else {
588574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               /* The returned value is in %r3:%r4.  Park it in the
588674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj                  register-pair associated with tmp. */
588774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               HReg r_dstHi = INVALID_HREG;
588874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               HReg r_dstLo = INVALID_HREG;
588974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               lookupIRTempPair( &r_dstHi, &r_dstLo, env, d->tmp);
589074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR(r_dstHi, hregPPC_GPR3(mode64)));
589174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               addInstr(env, mk_iMOVds_RR(r_dstLo, hregPPC_GPR4(mode64)));
589274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(rloc.pri == RLPri_2Int);
589374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               vassert(addToSp == 0);
589474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            }
589574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
589674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         case Ity_V128: {
589774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /* The returned value is on the stack, and *retloc tells
589874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               us where.  Fish it off the stack and then move the
589974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               stack pointer upwards to clear it, as directed by
590074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj               doHelperCall. */
590174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(rloc.pri == RLPri_V128SpRel);
590274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(addToSp >= 16);
590374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            HReg      dst = lookupIRTemp(env, d->tmp);
590474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            PPCAMode* am  = PPCAMode_IR(rloc.spOff, StackFramePtr(mode64));
590574142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, dst, am ));
590674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            add_to_sp(env, addToSp);
590774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            return;
590874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         }
590974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         default:
591074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            /*NOTREACHED*/
591174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj            vassert(0);
5912ed623dbefb52ca3211490d656abc999a129df060cerion      }
5913ed623dbefb52ca3211490d656abc999a129df060cerion   }
5914cd304497d9d869f9b24a002299d3953ee072229bcerion
591592f5dc7ca4f50145028c4baebc783d196dfb67a2cerion   /* --------- MEM FENCE --------- */
5916c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj   case Ist_MBE:
5917c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      switch (stmt->Ist.MBE.event) {
5918c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj         case Imbe_Fence:
5919c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            addInstr(env, PPCInstr_MFence());
5920c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            return;
5921c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj         default:
5922c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj            break;
5923c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      }
5924c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj      break;
5925cd304497d9d869f9b24a002299d3953ee072229bcerion
5926ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- INSTR MARK --------- */
5927ed623dbefb52ca3211490d656abc999a129df060cerion   /* Doesn't generate any executable code ... */
5928ed623dbefb52ca3211490d656abc999a129df060cerion   case Ist_IMark:
5929ed623dbefb52ca3211490d656abc999a129df060cerion       return;
5930ed623dbefb52ca3211490d656abc999a129df060cerion
5931cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj   /* --------- ABI HINT --------- */
5932cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj   /* These have no meaning (denotation in the IR) and so we ignore
5933cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj      them ... if any actually made it this far. */
5934cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj   case Ist_AbiHint:
5935cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj       return;
5936cf8986c47a4c8c810566bb5b7b3da7a16a17dfe2sewardj
5937ed623dbefb52ca3211490d656abc999a129df060cerion   /* --------- NO-OP --------- */
5938ed623dbefb52ca3211490d656abc999a129df060cerion   /* Fairly self-explanatory, wouldn't you say? */
5939ed623dbefb52ca3211490d656abc999a129df060cerion   case Ist_NoOp:
5940ed623dbefb52ca3211490d656abc999a129df060cerion       return;
5941ed623dbefb52ca3211490d656abc999a129df060cerion
5942b536af93912b69421440c27aa0533ad77d678f85cerion   /* --------- EXIT --------- */
5943b536af93912b69421440c27aa0533ad77d678f85cerion   case Ist_Exit: {
59443dee849ec7c38746749065e67dc53b75daa7617dsewardj      IRConst* dst = stmt->Ist.Exit.dst;
59453dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (!mode64 && dst->tag != Ico_U32)
59465b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         vpanic("iselStmt(ppc): Ist_Exit: dst is not a 32-bit value");
59473dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (mode64 && dst->tag != Ico_U64)
5948f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         vpanic("iselStmt(ppc64): Ist_Exit: dst is not a 64-bit value");
59493dee849ec7c38746749065e67dc53b75daa7617dsewardj
59501f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      PPCCondCode cc    = iselCondCode(env, stmt->Ist.Exit.guard, IEndianess);
59513dee849ec7c38746749065e67dc53b75daa7617dsewardj      PPCAMode*   amCIA = PPCAMode_IR(stmt->Ist.Exit.offsIP,
59523dee849ec7c38746749065e67dc53b75daa7617dsewardj                                      hregPPC_GPR31(mode64));
59533dee849ec7c38746749065e67dc53b75daa7617dsewardj
59543dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Case: boring transfer to known address */
59553dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (stmt->Ist.Exit.jk == Ijk_Boring
59563dee849ec7c38746749065e67dc53b75daa7617dsewardj          || stmt->Ist.Exit.jk == Ijk_Call
59573dee849ec7c38746749065e67dc53b75daa7617dsewardj          /* || stmt->Ist.Exit.jk == Ijk_Ret */) {
59583dee849ec7c38746749065e67dc53b75daa7617dsewardj         if (env->chainingAllowed) {
59593dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. almost always true .. */
59603dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* Skip the event check at the dst if this is a forwards
59613dee849ec7c38746749065e67dc53b75daa7617dsewardj               edge. */
59623dee849ec7c38746749065e67dc53b75daa7617dsewardj            Bool toFastEP
59633dee849ec7c38746749065e67dc53b75daa7617dsewardj               = mode64
59643dee849ec7c38746749065e67dc53b75daa7617dsewardj               ? (((Addr64)stmt->Ist.Exit.dst->Ico.U64) > (Addr64)env->max_ga)
59653dee849ec7c38746749065e67dc53b75daa7617dsewardj               : (((Addr32)stmt->Ist.Exit.dst->Ico.U32) > (Addr32)env->max_ga);
59663dee849ec7c38746749065e67dc53b75daa7617dsewardj            if (0) vex_printf("%s", toFastEP ? "Y" : ",");
59673dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XDirect(
59683dee849ec7c38746749065e67dc53b75daa7617dsewardj                             mode64 ? (Addr64)stmt->Ist.Exit.dst->Ico.U64
59693dee849ec7c38746749065e67dc53b75daa7617dsewardj                                    : (Addr64)stmt->Ist.Exit.dst->Ico.U32,
59703dee849ec7c38746749065e67dc53b75daa7617dsewardj                             amCIA, cc, toFastEP));
59713dee849ec7c38746749065e67dc53b75daa7617dsewardj         } else {
59723dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. very occasionally .. */
59733dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* We can't use chaining, so ask for an assisted transfer,
59743dee849ec7c38746749065e67dc53b75daa7617dsewardj               as that's the only alternative that is allowable. */
59751f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r = iselWordExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst),
59761f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IEndianess);
59773dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, cc, Ijk_Boring));
59783dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
59793dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
59803dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
59813dee849ec7c38746749065e67dc53b75daa7617dsewardj
59823dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Case: assisted transfer to arbitrary address */
59833dee849ec7c38746749065e67dc53b75daa7617dsewardj      switch (stmt->Ist.Exit.jk) {
59842f6902b260141dc063d131b3ec79af6f292a4a31sewardj         /* Keep this list in sync with that in iselNext below */
59852f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_ClientReq:
5986f252de5ec83a5cc72f96fe4decf662cfbb28df8bsewardj         case Ijk_EmFail:
59872f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_EmWarn:
59882f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_NoDecode:
59892f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_NoRedir:
59902f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_SigBUS:
59912f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_SigTRAP:
59922f6902b260141dc063d131b3ec79af6f292a4a31sewardj         case Ijk_Sys_syscall:
599305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         case Ijk_InvalICache:
59943dee849ec7c38746749065e67dc53b75daa7617dsewardj         {
59951f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r = iselWordExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst),
59961f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                                    IEndianess);
59973dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, cc,
59983dee849ec7c38746749065e67dc53b75daa7617dsewardj                                             stmt->Ist.Exit.jk));
59993dee849ec7c38746749065e67dc53b75daa7617dsewardj            return;
60003dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
60013dee849ec7c38746749065e67dc53b75daa7617dsewardj         default:
60023dee849ec7c38746749065e67dc53b75daa7617dsewardj            break;
60033dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
60043dee849ec7c38746749065e67dc53b75daa7617dsewardj
60053dee849ec7c38746749065e67dc53b75daa7617dsewardj      /* Do we ever expect to see any other kind? */
60063dee849ec7c38746749065e67dc53b75daa7617dsewardj      goto stmt_fail;
6007b536af93912b69421440c27aa0533ad77d678f85cerion   }
6008bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6009bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   default: break;
6010bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
6011af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj  stmt_fail:
6012bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   ppIRStmt(stmt);
60135b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion   vpanic("iselStmt(ppc)");
6014bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
6015bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6016bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6017bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6018bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- ISEL: Basic block terminators (Nexts)             ---*/
6019bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6020bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
60213dee849ec7c38746749065e67dc53b75daa7617dsewardjstatic void iselNext ( ISelEnv* env,
60221f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                       IRExpr* next, IRJumpKind jk, Int offsIP,
60231f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll                       IREndness IEndianess)
60242c49e036c365df707cd8e6622d66382f380557b2cerion{
60252c49e036c365df707cd8e6622d66382f380557b2cerion   if (vex_traceflags & VEX_TRACE_VCODE) {
60263dee849ec7c38746749065e67dc53b75daa7617dsewardj      vex_printf( "\n-- PUT(%d) = ", offsIP);
60273dee849ec7c38746749065e67dc53b75daa7617dsewardj      ppIRExpr( next );
60283dee849ec7c38746749065e67dc53b75daa7617dsewardj      vex_printf( "; exit-");
60292c49e036c365df707cd8e6622d66382f380557b2cerion      ppIRJumpKind(jk);
60303dee849ec7c38746749065e67dc53b75daa7617dsewardj      vex_printf( "\n");
60313dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
60323dee849ec7c38746749065e67dc53b75daa7617dsewardj
60333dee849ec7c38746749065e67dc53b75daa7617dsewardj   PPCCondCode always = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
60343dee849ec7c38746749065e67dc53b75daa7617dsewardj
60353dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* Case: boring transfer to known address */
60363dee849ec7c38746749065e67dc53b75daa7617dsewardj   if (next->tag == Iex_Const) {
60373dee849ec7c38746749065e67dc53b75daa7617dsewardj      IRConst* cdst = next->Iex.Const.con;
60383dee849ec7c38746749065e67dc53b75daa7617dsewardj      vassert(cdst->tag == (env->mode64 ? Ico_U64 :Ico_U32));
60393dee849ec7c38746749065e67dc53b75daa7617dsewardj      if (jk == Ijk_Boring || jk == Ijk_Call) {
60403dee849ec7c38746749065e67dc53b75daa7617dsewardj         /* Boring transfer to known address */
60413dee849ec7c38746749065e67dc53b75daa7617dsewardj         PPCAMode* amCIA = PPCAMode_IR(offsIP, hregPPC_GPR31(env->mode64));
60423dee849ec7c38746749065e67dc53b75daa7617dsewardj         if (env->chainingAllowed) {
60433dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. almost always true .. */
60443dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* Skip the event check at the dst if this is a forwards
60453dee849ec7c38746749065e67dc53b75daa7617dsewardj               edge. */
60463dee849ec7c38746749065e67dc53b75daa7617dsewardj            Bool toFastEP
60473dee849ec7c38746749065e67dc53b75daa7617dsewardj               = env->mode64
60483dee849ec7c38746749065e67dc53b75daa7617dsewardj               ? (((Addr64)cdst->Ico.U64) > (Addr64)env->max_ga)
60493dee849ec7c38746749065e67dc53b75daa7617dsewardj               : (((Addr32)cdst->Ico.U32) > (Addr32)env->max_ga);
60503dee849ec7c38746749065e67dc53b75daa7617dsewardj            if (0) vex_printf("%s", toFastEP ? "X" : ".");
60513dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XDirect(
60523dee849ec7c38746749065e67dc53b75daa7617dsewardj                             env->mode64 ? (Addr64)cdst->Ico.U64
60533dee849ec7c38746749065e67dc53b75daa7617dsewardj                                         : (Addr64)cdst->Ico.U32,
60543dee849ec7c38746749065e67dc53b75daa7617dsewardj                             amCIA, always, toFastEP));
60553dee849ec7c38746749065e67dc53b75daa7617dsewardj         } else {
60563dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* .. very occasionally .. */
60573dee849ec7c38746749065e67dc53b75daa7617dsewardj            /* We can't use chaining, so ask for an assisted transfer,
60583dee849ec7c38746749065e67dc53b75daa7617dsewardj               as that's the only alternative that is allowable. */
60591f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll            HReg r = iselWordExpr_R(env, next, IEndianess);
60603dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, always,
60613dee849ec7c38746749065e67dc53b75daa7617dsewardj                                             Ijk_Boring));
60623dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
60633dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
60643dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
60652c49e036c365df707cd8e6622d66382f380557b2cerion   }
60663dee849ec7c38746749065e67dc53b75daa7617dsewardj
60673dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* Case: call/return (==boring) transfer to any address */
60683dee849ec7c38746749065e67dc53b75daa7617dsewardj   switch (jk) {
60693dee849ec7c38746749065e67dc53b75daa7617dsewardj      case Ijk_Boring: case Ijk_Ret: case Ijk_Call: {
60701f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg       r     = iselWordExpr_R(env, next, IEndianess);
60713dee849ec7c38746749065e67dc53b75daa7617dsewardj         PPCAMode*  amCIA = PPCAMode_IR(offsIP, hregPPC_GPR31(env->mode64));
60723dee849ec7c38746749065e67dc53b75daa7617dsewardj         if (env->chainingAllowed) {
60733dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XIndir(r, amCIA, always));
60743dee849ec7c38746749065e67dc53b75daa7617dsewardj         } else {
60753dee849ec7c38746749065e67dc53b75daa7617dsewardj            addInstr(env, PPCInstr_XAssisted(r, amCIA, always,
60763dee849ec7c38746749065e67dc53b75daa7617dsewardj                                             Ijk_Boring));
60773dee849ec7c38746749065e67dc53b75daa7617dsewardj         }
60783dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
60793dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
60803dee849ec7c38746749065e67dc53b75daa7617dsewardj      default:
60813dee849ec7c38746749065e67dc53b75daa7617dsewardj         break;
60823dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
60833dee849ec7c38746749065e67dc53b75daa7617dsewardj
60842f6902b260141dc063d131b3ec79af6f292a4a31sewardj   /* Case: assisted transfer to arbitrary address */
60853dee849ec7c38746749065e67dc53b75daa7617dsewardj   switch (jk) {
60862f6902b260141dc063d131b3ec79af6f292a4a31sewardj      /* Keep this list in sync with that for Ist_Exit above */
60872f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_ClientReq:
60882f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_EmFail:
60892f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_EmWarn:
60902f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_NoDecode:
60913dee849ec7c38746749065e67dc53b75daa7617dsewardj      case Ijk_NoRedir:
60922f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_SigBUS:
60932f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_SigTRAP:
60942f6902b260141dc063d131b3ec79af6f292a4a31sewardj      case Ijk_Sys_syscall:
609505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj      case Ijk_InvalICache:
60963dee849ec7c38746749065e67dc53b75daa7617dsewardj      {
60971f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll         HReg      r     = iselWordExpr_R(env, next, IEndianess);
60983dee849ec7c38746749065e67dc53b75daa7617dsewardj         PPCAMode* amCIA = PPCAMode_IR(offsIP, hregPPC_GPR31(env->mode64));
60993dee849ec7c38746749065e67dc53b75daa7617dsewardj         addInstr(env, PPCInstr_XAssisted(r, amCIA, always, jk));
61003dee849ec7c38746749065e67dc53b75daa7617dsewardj         return;
61013dee849ec7c38746749065e67dc53b75daa7617dsewardj      }
61023dee849ec7c38746749065e67dc53b75daa7617dsewardj      default:
61033dee849ec7c38746749065e67dc53b75daa7617dsewardj         break;
61043dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
61053dee849ec7c38746749065e67dc53b75daa7617dsewardj
61063dee849ec7c38746749065e67dc53b75daa7617dsewardj   vex_printf( "\n-- PUT(%d) = ", offsIP);
61073dee849ec7c38746749065e67dc53b75daa7617dsewardj   ppIRExpr( next );
61083dee849ec7c38746749065e67dc53b75daa7617dsewardj   vex_printf( "; exit-");
61093dee849ec7c38746749065e67dc53b75daa7617dsewardj   ppIRJumpKind(jk);
61103dee849ec7c38746749065e67dc53b75daa7617dsewardj   vex_printf( "\n");
61113dee849ec7c38746749065e67dc53b75daa7617dsewardj   vassert(0); // are we expecting any other kind?
6112bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
6113bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6114bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6115bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6116bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*--- Insn selector top-level                           ---*/
6117bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------*/
6118bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61193dee849ec7c38746749065e67dc53b75daa7617dsewardj/* Translate an entire SB to ppc code. */
6120cacba8e675988fbf21b08feea1f317a9c896c053florianHInstrArray* iselSB_PPC ( const IRSB* bb,
61219e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          VexArch      arch_host,
6122d8c64e082224b2e688abdef9219cc76fd82b373bflorian                          const VexArchInfo* archinfo_host,
6123d8c64e082224b2e688abdef9219cc76fd82b373bflorian                          const VexAbiInfo*  vbi,
61249e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Int offs_Host_EvC_Counter,
61259e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Int offs_Host_EvC_FailAddr,
61269e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Bool chainingAllowed,
61279e1cf1522d17dd5ca8a0599168a4d38ead0b71eesewardj                          Bool addProfInc,
6128dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian                          Addr max_ga)
61291f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
6130bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion{
61313dee849ec7c38746749065e67dc53b75daa7617dsewardj   Int       i, j;
61323dee849ec7c38746749065e67dc53b75daa7617dsewardj   HReg      hregLo, hregMedLo, hregMedHi, hregHi;
61333dee849ec7c38746749065e67dc53b75daa7617dsewardj   ISelEnv*  env;
61343dee849ec7c38746749065e67dc53b75daa7617dsewardj   UInt      hwcaps_host = archinfo_host->hwcaps;
61353dee849ec7c38746749065e67dc53b75daa7617dsewardj   Bool      mode64 = False;
61363dee849ec7c38746749065e67dc53b75daa7617dsewardj   UInt      mask32, mask64;
61373dee849ec7c38746749065e67dc53b75daa7617dsewardj   PPCAMode *amCounter, *amFailAddr;
61381f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   IREndness IEndianess;
6139bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61408f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   vassert(arch_host == VexArchPPC32 || arch_host == VexArchPPC64);
61418f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   mode64 = arch_host == VexArchPPC64;
61428f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj
61438f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   /* do some sanity checks */
61445117ce116f47141cb23d1b49cc826e19323add97sewardj   mask32 = VEX_HWCAPS_PPC32_F | VEX_HWCAPS_PPC32_V
6145c66d6fa5d9397f167b162483cf3419051cc01a80sewardj            | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX
61460c74bb5aa3240f693df0568d578baabf0c376dc4carll            | VEX_HWCAPS_PPC32_DFP | VEX_HWCAPS_PPC32_ISA2_07;
61470c74bb5aa3240f693df0568d578baabf0c376dc4carll
61485117ce116f47141cb23d1b49cc826e19323add97sewardj
614966d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj   mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX
61500c74bb5aa3240f693df0568d578baabf0c376dc4carll            | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP
61510c74bb5aa3240f693df0568d578baabf0c376dc4carll            | VEX_HWCAPS_PPC64_ISA2_07;
61525117ce116f47141cb23d1b49cc826e19323add97sewardj
61538f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   if (mode64) {
61548f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj      vassert((hwcaps_host & mask32) == 0);
61558f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   } else {
61568f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj      vassert((hwcaps_host & mask64) == 0);
61578f073592de3c74d8bcdb4da353bb0132c4e6308dsewardj   }
6158bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61599b76916dcc1628e133d57db001563429c6e3a590sewardj   /* Check that the host's endianness is as expected. */
61601f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   vassert((archinfo_host->endness == VexEndnessBE) ||
61611f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll	   (archinfo_host->endness == VexEndnessLE));
61621f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll
61631f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   if (archinfo_host->endness == VexEndnessBE)
61641f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll     IEndianess = Iend_BE;
61651f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   else
61661f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll     IEndianess = Iend_LE;
61679b76916dcc1628e133d57db001563429c6e3a590sewardj
6168bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Make up an initial environment to use. */
6169d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   env = LibVEX_Alloc_inline(sizeof(ISelEnv));
6170bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->vreg_ctr = 0;
6171bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
61724628ccd1bafb946378f91849b92ffcfea0267b2ecerion   /* Are we being ppc32 or ppc64? */
61734628ccd1bafb946378f91849b92ffcfea0267b2ecerion   env->mode64 = mode64;
61744628ccd1bafb946378f91849b92ffcfea0267b2ecerion
6175bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Set up output code array. */
6176bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->code = newHInstrArray();
6177bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6178bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Copy BB's type env. */
6179bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->type_env = bb->tyenv;
6180bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6181bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Make up an IRTemp -> virtual HReg mapping.  This doesn't
6182c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    * change as we go along.
6183c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    *
6184c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    * vregmap2 and vregmap3 are only used in 32 bit mode
6185c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    * for supporting I128 in 32-bit mode
6186c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    */
6187bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->n_vregmap = bb->tyenv->types_used;
6188d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   env->vregmapLo    = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
6189d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   env->vregmapMedLo = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
61903dee849ec7c38746749065e67dc53b75daa7617dsewardj   if (mode64) {
61913dee849ec7c38746749065e67dc53b75daa7617dsewardj      env->vregmapMedHi = NULL;
61923dee849ec7c38746749065e67dc53b75daa7617dsewardj      env->vregmapHi    = NULL;
61933dee849ec7c38746749065e67dc53b75daa7617dsewardj   } else {
6194d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian      env->vregmapMedHi = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
6195d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian      env->vregmapHi    = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
6196c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj   }
6197bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6198bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* and finally ... */
61993dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->chainingAllowed = chainingAllowed;
62003dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->max_ga          = max_ga;
62013dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->hwcaps          = hwcaps_host;
62023dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->previous_rm     = NULL;
62033dee849ec7c38746749065e67dc53b75daa7617dsewardj   env->vbi             = vbi;
6204bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6205bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* For each IR temporary, allocate a suitably-kinded virtual
6206bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      register. */
6207bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   j = 0;
6208bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   for (i = 0; i < env->n_vregmap; i++) {
6209c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      hregLo = hregMedLo = hregMedHi = hregHi = INVALID_HREG;
6210bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      switch (bb->tyenv->types[i]) {
6211ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_I1:
6212ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_I8:
6213ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_I16:
6214bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion      case Ity_I32:
6215a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         if (mode64) {
6216a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo = mkHReg(True, HRcInt64, 0, j++);
6217a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         } else {
6218a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo = mkHReg(True, HRcInt32, 0, j++);
6219bb01b7cbfd84c27dd213f67a144ea5a99af36961cerion         }
6220a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6221f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion      case Ity_I64:
6222a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         if (mode64) {
6223a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt64, 0, j++);
6224a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         } else {
6225a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt32, 0, j++);
6226a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedLo = mkHReg(True, HRcInt32, 0, j++);
6227c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         }
6228a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6229c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      case Ity_I128:
6230a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         if (mode64) {
6231a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt64, 0, j++);
6232a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedLo = mkHReg(True, HRcInt64, 0, j++);
6233a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         } else {
6234a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregLo    = mkHReg(True, HRcInt32, 0, j++);
6235a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedLo = mkHReg(True, HRcInt32, 0, j++);
6236a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregMedHi = mkHReg(True, HRcInt32, 0, j++);
6237a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            hregHi    = mkHReg(True, HRcInt32, 0, j++);
6238f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion         }
6239a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6240ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      case Ity_F32:
6241a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_F64:
6242a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo = mkHReg(True, HRcFlt64, 0, j++);
6243a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6244a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_V128:
6245a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo = mkHReg(True, HRcVec128, 0, j++);
6246a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6247f704eb2bab3d06d983c850b0bcf243e178060f75carll      case Ity_D32:
6248a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_D64:
6249a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo = mkHReg(True, HRcFlt64, 0, j++);
6250a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6251a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      case Ity_D128:
6252a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregLo    = mkHReg(True, HRcFlt64, 0, j++);
6253a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         hregMedLo = mkHReg(True, HRcFlt64, 0, j++);
6254a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         break;
6255ab9132df645da753ae6b0421d551ea5c024aa6e6cerion      default:
6256ab9132df645da753ae6b0421d551ea5c024aa6e6cerion         ppIRType(bb->tyenv->types[i]);
62575b2325f209f6d3c7ab9c4e819d15060f8d1f09efcerion         vpanic("iselBB(ppc): IRTemp type");
6258bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion      }
6259c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      env->vregmapLo[i]    = hregLo;
6260c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      env->vregmapMedLo[i] = hregMedLo;
6261c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      if (!mode64) {
6262c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         env->vregmapMedHi[i] = hregMedHi;
6263c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj         env->vregmapHi[i]    = hregHi;
6264c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj      }
6265bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   }
6266bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->vreg_ctr = j;
6267bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
62683dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* The very first instruction must be an event check. */
62693dee849ec7c38746749065e67dc53b75daa7617dsewardj   amCounter  = PPCAMode_IR(offs_Host_EvC_Counter, hregPPC_GPR31(mode64));
62703dee849ec7c38746749065e67dc53b75daa7617dsewardj   amFailAddr = PPCAMode_IR(offs_Host_EvC_FailAddr, hregPPC_GPR31(mode64));
62713dee849ec7c38746749065e67dc53b75daa7617dsewardj   addInstr(env, PPCInstr_EvCheck(amCounter, amFailAddr));
62723dee849ec7c38746749065e67dc53b75daa7617dsewardj
62733dee849ec7c38746749065e67dc53b75daa7617dsewardj   /* Possibly a block counter increment (for profiling).  At this
62743dee849ec7c38746749065e67dc53b75daa7617dsewardj      point we don't know the address of the counter, so just pretend
62753dee849ec7c38746749065e67dc53b75daa7617dsewardj      it is zero.  It will have to be patched later, but before this
62763dee849ec7c38746749065e67dc53b75daa7617dsewardj      translation is used, by a call to LibVEX_patchProfCtr. */
62773dee849ec7c38746749065e67dc53b75daa7617dsewardj   if (addProfInc) {
62783dee849ec7c38746749065e67dc53b75daa7617dsewardj      addInstr(env, PPCInstr_ProfInc());
62793dee849ec7c38746749065e67dc53b75daa7617dsewardj   }
62807f000af9c21e3b5059e0b2d26bcb9ca378ae0e54cerion
6281bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* Ok, finally we can iterate over the statements. */
6282bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   for (i = 0; i < bb->stmts_used; i++)
62831f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll      iselStmt(env, bb->stmts[i], IEndianess);
6284bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
62851f5fe1fc3a37ca729925e8eec25aa1025b4a6cdbcarll   iselNext(env, bb->next, bb->jumpkind, bb->offsIP, IEndianess);
6286bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6287bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   /* record the number of vregs we used. */
6288bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   env->code->n_vregs = env->vreg_ctr;
6289bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion   return env->code;
6290bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion}
6291bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6292bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion
6293bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------------*/
6294cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                     host_ppc_isel.c ---*/
6295bcf8c3ed0466b8876535f68f9ca5c31f5fd8a26fcerion/*---------------------------------------------------------------*/
6296