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