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