11adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman//===-- X86FastISel.cpp - X86 FastISel implementation ---------------------===// 21adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// 31adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// The LLVM Compiler Infrastructure 41adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// 51adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// This file is distributed under the University of Illinois Open Source 61adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// License. See LICENSE.TXT for details. 71adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// 81adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman//===----------------------------------------------------------------------===// 91adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// 101adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// This file defines the X86-specific support for the FastISel class. Much 111adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// of the target-specific code is generated by tablegen in the file 121adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// X86GenFastISel.inc, which is #included here. 131adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman// 141adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman//===----------------------------------------------------------------------===// 151adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman 161adf1b03af9b1e2ee5a527caa5b14c9d55a32173Dan Gohman#include "X86.h" 17ef41ff618f2537539b538e6c7bf471c753391f92Evan Cheng#include "X86ISelLowering.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "X86InstrBuilder.h" 1988e3041ca61eeaebbbd6c68a1b37209983b4c765Evan Cheng#include "X86RegisterInfo.h" 2088e3041ca61eeaebbbd6c68a1b37209983b4c765Evan Cheng#include "X86Subtarget.h" 2122bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman#include "X86TargetMachine.h" 2284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman#include "llvm/CodeGen/Analysis.h" 23c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng#include "llvm/CodeGen/FastISel.h" 24a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman#include "llvm/CodeGen/FunctionLoweringInfo.h" 2595267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson#include "llvm/CodeGen/MachineConstantPool.h" 26f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng#include "llvm/CodeGen/MachineFrameInfo.h" 27667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson#include "llvm/CodeGen/MachineRegisterInfo.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalAlias.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Operator.h" 35f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng#include "llvm/Support/CallSite.h" 36c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 373589308f37177f28257dd1a39dc6d6395a435acbDan Gohman#include "llvm/Support/GetElementPtrTypeIterator.h" 38381993f1f2f947fcdaec814181a735091b22fcbaEvan Cheng#include "llvm/Target/TargetOptions.h" 39c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Chengusing namespace llvm; 40c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng 41087fcf3e89c2728b5fc850c587da4876319877caChris Lattnernamespace { 42bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 43c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Chengclass X86FastISel : public FastISel { 44c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng /// Subtarget - Keep a pointer to the X86Subtarget around so that we can 45c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng /// make the right decision when generating code for different targets. 46c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng const X86Subtarget *Subtarget; 47f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 48f0e06e8d4445a45b18d18efcdb7c6fef22e90047Michael Liao /// RegInfo - X86 register info. 49f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng /// 50f0e06e8d4445a45b18d18efcdb7c6fef22e90047Michael Liao const X86RegisterInfo *RegInfo; 51f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 52bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck /// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87 53f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng /// floating point ops. 54f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng /// When SSE is available, use it for f32 operations. 55f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng /// When SSE2 is available, use it for f64 operations. 56f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng bool X86ScalarSSEf64; 57f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng bool X86ScalarSSEf32; 58f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 598b19e56051c45c3e48523238a5a0f33bbac0115dEvan Chengpublic: 60d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson explicit X86FastISel(FunctionLoweringInfo &funcInfo, 61d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson const TargetLibraryInfo *libInfo) 62d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson : FastISel(funcInfo, libInfo) { 6388e3041ca61eeaebbbd6c68a1b37209983b4c765Evan Cheng Subtarget = &TM.getSubtarget<X86Subtarget>(); 641accb7ed98d823c291a4d5df172d0538451aba9eCraig Topper X86ScalarSSEf64 = Subtarget->hasSSE2(); 651accb7ed98d823c291a4d5df172d0538451aba9eCraig Topper X86ScalarSSEf32 = Subtarget->hasSSE1(); 66f0e06e8d4445a45b18d18efcdb7c6fef22e90047Michael Liao RegInfo = static_cast<const X86RegisterInfo*>(TM.getRegisterInfo()); 6788e3041ca61eeaebbbd6c68a1b37209983b4c765Evan Cheng } 68c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng 6946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman virtual bool TargetSelectInstruction(const Instruction *I); 7099b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman 71beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner /// TryToFoldLoad - The specified machine instr operand is a vreg, and that 72beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner /// vreg is being provided by the specified load instruction. If possible, 73beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner /// try to fold the load as an operand to the instruction, returning true if 74beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner /// possible. 75beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner virtual bool TryToFoldLoad(MachineInstr *MI, unsigned OpNo, 76beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner const LoadInst *LI); 77bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 78fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier virtual bool FastLowerArguments(); 79fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 80c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng#include "X86GenFastISel.inc" 818b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng 828b19e56051c45c3e48523238a5a0f33bbac0115dEvan Chengprivate: 8346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86FastEmitCompare(const Value *LHS, const Value *RHS, EVT VT); 84bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 85e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson bool X86FastEmitLoad(EVT VT, const X86AddressMode &AM, unsigned &RR); 860de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng 87b44101c1401c23fb86fe649309f52e823206147dChris Lattner bool X86FastEmitStore(EVT VT, const Value *Val, const X86AddressMode &AM); 88b44101c1401c23fb86fe649309f52e823206147dChris Lattner bool X86FastEmitStore(EVT VT, unsigned Val, const X86AddressMode &AM); 8924e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng 90e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson bool X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT, unsigned Src, EVT SrcVT, 9124e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng unsigned &ResultReg); 92bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectAddress(const Value *V, X86AddressMode &AM); 9446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectCallAddress(const Value *V, X86AddressMode &AM); 950586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman 9646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectLoad(const Instruction *I); 97bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectStore(const Instruction *I); 996e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman 10084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman bool X86SelectRet(const Instruction *I); 10184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 10246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectCmp(const Instruction *I); 103d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman 10446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectZExt(const Instruction *I); 105d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman 10646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectBranch(const Instruction *I); 107c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 10846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectShift(const Instruction *I); 109c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 11046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectSelect(const Instruction *I); 1110de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng 11246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectTrunc(const Instruction *I); 113bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 11446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectFPExt(const Instruction *I); 11546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectFPTrunc(const Instruction *I); 11678efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman 11746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86VisitIntrinsicCall(const IntrinsicInst &I); 11846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman bool X86SelectCall(const Instruction *I); 119f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 12025255cbe0000abd64194e9e34098243cd689fd47Eli Friedman bool DoSelectCall(const Instruction *I, const char *MemIntName); 12125255cbe0000abd64194e9e34098243cd689fd47Eli Friedman 1222cc3aa44591313307e2d596daca784419ab7286dDan Gohman const X86InstrInfo *getInstrInfo() const { 12397135e1ee51357245561a5108f90a8a1161431a1Dan Gohman return getTargetMachine()->getInstrInfo(); 12497135e1ee51357245561a5108f90a8a1161431a1Dan Gohman } 12597135e1ee51357245561a5108f90a8a1161431a1Dan Gohman const X86TargetMachine *getTargetMachine() const { 12697135e1ee51357245561a5108f90a8a1161431a1Dan Gohman return static_cast<const X86TargetMachine *>(&TM); 1272cc3aa44591313307e2d596daca784419ab7286dDan Gohman } 1282cc3aa44591313307e2d596daca784419ab7286dDan Gohman 12946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman unsigned TargetMaterializeConstant(const Constant *C); 1300586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman 13146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman unsigned TargetMaterializeAlloca(const AllocaInst *C); 132f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1332790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman unsigned TargetMaterializeFloatZero(const ConstantFP *CF); 1342790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman 135f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng /// isScalarFPTypeInSSEReg - Return true if the specified scalar FP type is 136f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng /// computed in an SSE register, not on the X87 floating point stack. 137e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson bool isScalarFPTypeInSSEReg(EVT VT) const { 138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return (VT == MVT::f64 && X86ScalarSSEf64) || // f64 is when SSE2 139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (VT == MVT::f32 && X86ScalarSSEf32); // f32 is when SSE1 140f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } 141f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 142db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner bool isTypeLegal(Type *Ty, MVT &VT, bool AllowI1 = false); 143d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 144c088345f1377a36c35c037be63830d0e6892f904Eli Friedman bool IsMemcpySmall(uint64_t Len); 145c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 146d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman bool TryEmitSmallMemcpy(X86AddressMode DestAM, 147d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman X86AddressMode SrcAM, uint64_t Len); 148c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng}; 149bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 150087fcf3e89c2728b5fc850c587da4876319877caChris Lattner} // end anonymous namespace. 15199b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman 152db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool X86FastISel::isTypeLegal(Type *Ty, MVT &VT, bool AllowI1) { 1531440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands EVT evt = TLI.getValueType(Ty, /*HandleUnknown=*/true); 1541440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands if (evt == MVT::Other || !evt.isSimple()) 155f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Unhandled type. Halt "fast" selection and bail. 156f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return false; 1571440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands 1581440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands VT = evt.getSimpleVT(); 1599b66d73bb1a0279d86e9ba77807146146a07724fDan Gohman // For now, require SSE/SSE2 for performing floating-point operations, 1609b66d73bb1a0279d86e9ba77807146146a07724fDan Gohman // since x87 requires additional work. 161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::f64 && !X86ScalarSSEf64) 162f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper return false; 163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::f32 && !X86ScalarSSEf32) 164f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper return false; 1659b66d73bb1a0279d86e9ba77807146146a07724fDan Gohman // Similarly, no f80 support yet. 166825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::f80) 1679b66d73bb1a0279d86e9ba77807146146a07724fDan Gohman return false; 168f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // We only handle legal types. For example, on x86-32 the instruction 169f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // selector contains all of the 64-bit instructions from x86-64, 170f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // under the assumption that i64 won't be used if the target doesn't 171f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // support it. 172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT); 173f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng} 174f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 175f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng#include "X86GenCallingConv.inc" 176f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1770de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng/// X86FastEmitLoad - Emit a machine instruction to load a value of type VT. 178f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng/// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV. 1790de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng/// Return true and the result register by reference if it is possible. 180e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersonbool X86FastISel::X86FastEmitLoad(EVT VT, const X86AddressMode &AM, 1810de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng unsigned &ResultReg) { 1820de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng // Get opcode and regclass of the output for the given load instruction. 1830de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng unsigned Opc = 0; 1840de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng const TargetRegisterClass *RC = NULL; 185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 1860de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng default: return false; 1877e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman case MVT::i1: 188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: 1890de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng Opc = X86::MOV8rm; 190c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR8RegClass; 1910de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng break; 192825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 1930de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng Opc = X86::MOV16rm; 194c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR16RegClass; 1950de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng break; 196825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 1970de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng Opc = X86::MOV32rm; 198c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR32RegClass; 1990de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng break; 200825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: 2010de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng // Must be in x86-64 mode. 2020de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng Opc = X86::MOV64rm; 203c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR64RegClass; 2040de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng break; 205825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f32: 206645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes if (X86ScalarSSEf32) { 207645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes Opc = Subtarget->hasAVX() ? X86::VMOVSSrm : X86::MOVSSrm; 208c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::FR32RegClass; 2098b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng } else { 2100de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng Opc = X86::LD_Fp32m; 211c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::RFP32RegClass; 2128b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng } 2130de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng break; 214825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f64: 215645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes if (X86ScalarSSEf64) { 216645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes Opc = Subtarget->hasAVX() ? X86::VMOVSDrm : X86::MOVSDrm; 217c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::FR64RegClass; 2180de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng } else { 2190de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng Opc = X86::LD_Fp64m; 220c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::RFP64RegClass; 2210de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng } 2220de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng break; 223825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f80: 2245af29c2e5709b56de701fa4adb4705b9f84973c8Dan Gohman // No f80 support yet. 2255af29c2e5709b56de701fa4adb4705b9f84973c8Dan Gohman return false; 2268b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng } 2270de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng 2280de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng ResultReg = createResultReg(RC); 22984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 23084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman DL, TII.get(Opc), ResultReg), AM); 2318b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng return true; 2328b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng} 2338b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng 234f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng/// X86FastEmitStore - Emit a machine instruction to store a value Val of 235f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng/// type VT. The address is either pre-computed, consisted of a base ptr, Ptr 236f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng/// and a displacement offset, or a GlobalAddress, 2370de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng/// i.e. V. Return true if it is possible. 2380de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Chengbool 239b44101c1401c23fb86fe649309f52e823206147dChris LattnerX86FastISel::X86FastEmitStore(EVT VT, unsigned Val, const X86AddressMode &AM) { 240863890e2fa7339da613532b065627e941aa2eaf6Dan Gohman // Get opcode and regclass of the output for the given store instruction. 241a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson unsigned Opc = 0; 242825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 243825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f80: // No f80 support yet. 244a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson default: return false; 2457e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman case MVT::i1: { 2467e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman // Mask out all but lowest bit. 247c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper unsigned AndResult = createResultReg(&X86::GR8RegClass); 24884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2497e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman TII.get(X86::AND8ri), AndResult).addReg(Val).addImm(1); 2507e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman Val = AndResult; 2517e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman } 2527e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman // FALLTHROUGH, handling i1 as i8. 253825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: Opc = X86::MOV8mr; break; 254825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: Opc = X86::MOV16mr; break; 255825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: Opc = X86::MOV32mr; break; 256825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: Opc = X86::MOV64mr; break; // Must be in x86-64 mode. 257825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f32: 258645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes Opc = X86ScalarSSEf32 ? 259645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes (Subtarget->hasAVX() ? X86::VMOVSSmr : X86::MOVSSmr) : X86::ST_Fp32m; 260a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson break; 261825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f64: 262645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes Opc = X86ScalarSSEf64 ? 263645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes (Subtarget->hasAVX() ? X86::VMOVSDmr : X86::MOVSDmr) : X86::ST_Fp64m; 264a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson break; 265e4824714026a528fe4cb08ad73e048066980eda6Lang Hames case MVT::v4f32: 266e4824714026a528fe4cb08ad73e048066980eda6Lang Hames Opc = X86::MOVAPSmr; 267e4824714026a528fe4cb08ad73e048066980eda6Lang Hames break; 268e4824714026a528fe4cb08ad73e048066980eda6Lang Hames case MVT::v2f64: 269e4824714026a528fe4cb08ad73e048066980eda6Lang Hames Opc = X86::MOVAPDmr; 270e4824714026a528fe4cb08ad73e048066980eda6Lang Hames break; 271e4824714026a528fe4cb08ad73e048066980eda6Lang Hames case MVT::v4i32: 272e4824714026a528fe4cb08ad73e048066980eda6Lang Hames case MVT::v2i64: 273e4824714026a528fe4cb08ad73e048066980eda6Lang Hames case MVT::v8i16: 274e4824714026a528fe4cb08ad73e048066980eda6Lang Hames case MVT::v16i8: 275e4824714026a528fe4cb08ad73e048066980eda6Lang Hames Opc = X86::MOVDQAmr; 276e4824714026a528fe4cb08ad73e048066980eda6Lang Hames break; 277a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson } 278bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 27984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 28084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman DL, TII.get(Opc)), AM).addReg(Val); 281a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson return true; 282a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson} 283a3971dfbfeff803f5de53cf62d794c9d60aa3b7aOwen Anderson 28446510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86FastEmitStore(EVT VT, const Value *Val, 285438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner const X86AddressMode &AM) { 286438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner // Handle 'null' like i32/i64 0. 287ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth if (isa<ConstantPointerNull>(Val)) 288ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth Val = Constant::getNullValue(TD.getIntPtrType(Val->getContext())); 289bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 290438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner // If this is a store of a simple constant, fold the constant into the store. 29146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val)) { 292438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner unsigned Opc = 0; 2937e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman bool Signed = true; 294825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 295438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner default: break; 2967e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman case MVT::i1: Signed = false; // FALLTHROUGH to handle as i8. 297825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: Opc = X86::MOV8mi; break; 298825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: Opc = X86::MOV16mi; break; 299825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: Opc = X86::MOV32mi; break; 300825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: 301438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner // Must be a 32-bit sign extended value. 302eaf77254d4d6dd8dfc461c3e6078f44da881291cJakub Staszak if (isInt<32>(CI->getSExtValue())) 303438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner Opc = X86::MOV64mi32; 304438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner break; 305438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner } 306bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 307438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner if (Opc) { 30884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 30984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman DL, TII.get(Opc)), AM) 310795ee9dd1e43d9e3ba87c052f721b6f7a2161827John McCall .addImm(Signed ? (uint64_t) CI->getSExtValue() : 3117e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman CI->getZExtValue()); 312438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner return true; 313438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner } 314438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner } 315bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 316438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner unsigned ValReg = getRegForValue(Val); 317438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner if (ValReg == 0) 318bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return false; 319bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 320438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner return X86FastEmitStore(VT, ValReg, AM); 321438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner} 322438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner 32324e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng/// X86FastEmitExtend - Emit a machine instruction to extend a value Src of 32424e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng/// type SrcVT to type DstVT using the specified extension opcode Opc (e.g. 32524e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng/// ISD::SIGN_EXTEND). 326e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersonbool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT, 327e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson unsigned Src, EVT SrcVT, 32824e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng unsigned &ResultReg) { 329a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman unsigned RR = FastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Opc, 330a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman Src, /*TODO: Kill=*/false); 331fe9b5a4f74c5686ab479dd42bd87e654834a8ba4Jakub Staszak if (RR == 0) 332ac34a00fe0784cd6efc466f03f93ab1017fa9726Owen Anderson return false; 333fe9b5a4f74c5686ab479dd42bd87e654834a8ba4Jakub Staszak 334fe9b5a4f74c5686ab479dd42bd87e654834a8ba4Jakub Staszak ResultReg = RR; 335fe9b5a4f74c5686ab479dd42bd87e654834a8ba4Jakub Staszak return true; 33624e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng} 33724e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng 3380586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman/// X86SelectAddress - Attempt to fill in an address from the given value. 3390586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman/// 34046510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) { 34146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const User *U = NULL; 3423589308f37177f28257dd1a39dc6d6395a435acbDan Gohman unsigned Opcode = Instruction::UserOp1; 34346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const Instruction *I = dyn_cast<Instruction>(V)) { 344ea9f151cbc1ce153c7605a02acc31f76cbb3c5a2Dan Gohman // Don't walk into other basic blocks; it's possible we haven't 345ea9f151cbc1ce153c7605a02acc31f76cbb3c5a2Dan Gohman // visited them yet, so the instructions may not yet be assigned 346ea9f151cbc1ce153c7605a02acc31f76cbb3c5a2Dan Gohman // virtual registers. 347742bf87efa5c2e8c10c6b12b35b65fec439cea53Dan Gohman if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(V)) || 348742bf87efa5c2e8c10c6b12b35b65fec439cea53Dan Gohman FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) { 349742bf87efa5c2e8c10c6b12b35b65fec439cea53Dan Gohman Opcode = I->getOpcode(); 350742bf87efa5c2e8c10c6b12b35b65fec439cea53Dan Gohman U = I; 351742bf87efa5c2e8c10c6b12b35b65fec439cea53Dan Gohman } 35246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(V)) { 3533589308f37177f28257dd1a39dc6d6395a435acbDan Gohman Opcode = C->getOpcode(); 3543589308f37177f28257dd1a39dc6d6395a435acbDan Gohman U = C; 3553589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 3560586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman 357db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner if (PointerType *Ty = dyn_cast<PointerType>(V->getType())) 358868ee9460c6e3055162f7ed9b05747606096945aChris Lattner if (Ty->getAddressSpace() > 255) 3591415a602ade564390bd86476feaeb66cb3612951Dan Gohman // Fast instruction selection doesn't support the special 3601415a602ade564390bd86476feaeb66cb3612951Dan Gohman // address spaces. 361868ee9460c6e3055162f7ed9b05747606096945aChris Lattner return false; 362868ee9460c6e3055162f7ed9b05747606096945aChris Lattner 3633589308f37177f28257dd1a39dc6d6395a435acbDan Gohman switch (Opcode) { 3643589308f37177f28257dd1a39dc6d6395a435acbDan Gohman default: break; 3653589308f37177f28257dd1a39dc6d6395a435acbDan Gohman case Instruction::BitCast: 3663589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Look past bitcasts. 3670aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectAddress(U->getOperand(0), AM); 3683589308f37177f28257dd1a39dc6d6395a435acbDan Gohman 3693589308f37177f28257dd1a39dc6d6395a435acbDan Gohman case Instruction::IntToPtr: 3703589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Look past no-op inttoptrs. 3713589308f37177f28257dd1a39dc6d6395a435acbDan Gohman if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy()) 3720aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectAddress(U->getOperand(0), AM); 37355fdaec36a0a2fac68d2f085c11fce22d2742db7Dan Gohman break; 3743589308f37177f28257dd1a39dc6d6395a435acbDan Gohman 3753589308f37177f28257dd1a39dc6d6395a435acbDan Gohman case Instruction::PtrToInt: 3763589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Look past no-op ptrtoints. 3773589308f37177f28257dd1a39dc6d6395a435acbDan Gohman if (TLI.getValueType(U->getType()) == TLI.getPointerTy()) 3780aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectAddress(U->getOperand(0), AM); 37955fdaec36a0a2fac68d2f085c11fce22d2742db7Dan Gohman break; 3803589308f37177f28257dd1a39dc6d6395a435acbDan Gohman 3813589308f37177f28257dd1a39dc6d6395a435acbDan Gohman case Instruction::Alloca: { 3823589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Do static allocas. 3833589308f37177f28257dd1a39dc6d6395a435acbDan Gohman const AllocaInst *A = cast<AllocaInst>(V); 384a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman DenseMap<const AllocaInst*, int>::iterator SI = 385a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman FuncInfo.StaticAllocaMap.find(A); 386a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman if (SI != FuncInfo.StaticAllocaMap.end()) { 38797135e1ee51357245561a5108f90a8a1161431a1Dan Gohman AM.BaseType = X86AddressMode::FrameIndexBase; 38897135e1ee51357245561a5108f90a8a1161431a1Dan Gohman AM.Base.FrameIndex = SI->second; 38997135e1ee51357245561a5108f90a8a1161431a1Dan Gohman return true; 39097135e1ee51357245561a5108f90a8a1161431a1Dan Gohman } 39197135e1ee51357245561a5108f90a8a1161431a1Dan Gohman break; 3923589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 3933589308f37177f28257dd1a39dc6d6395a435acbDan Gohman 3943589308f37177f28257dd1a39dc6d6395a435acbDan Gohman case Instruction::Add: { 3953589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Adds of constants are common and easy enough. 39646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const ConstantInt *CI = dyn_cast<ConstantInt>(U->getOperand(1))) { 39709aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman uint64_t Disp = (int32_t)AM.Disp + (uint64_t)CI->getSExtValue(); 39809aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman // They have to fit in the 32-bit signed displacement field though. 39934247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer if (isInt<32>(Disp)) { 40009aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman AM.Disp = (uint32_t)Disp; 4010aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectAddress(U->getOperand(0), AM); 40209aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman } 4033589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 4043589308f37177f28257dd1a39dc6d6395a435acbDan Gohman break; 4053589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 4063589308f37177f28257dd1a39dc6d6395a435acbDan Gohman 4073589308f37177f28257dd1a39dc6d6395a435acbDan Gohman case Instruction::GetElementPtr: { 408bfcc8e0a6636651fa1f13949ec2faf99068042f1Chris Lattner X86AddressMode SavedAM = AM; 409bfcc8e0a6636651fa1f13949ec2faf99068042f1Chris Lattner 4103589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Pattern-match simple GEPs. 41109aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman uint64_t Disp = (int32_t)AM.Disp; 4123589308f37177f28257dd1a39dc6d6395a435acbDan Gohman unsigned IndexReg = AM.IndexReg; 4133589308f37177f28257dd1a39dc6d6395a435acbDan Gohman unsigned Scale = AM.Scale; 4143589308f37177f28257dd1a39dc6d6395a435acbDan Gohman gep_type_iterator GTI = gep_type_begin(U); 415c8a1a3c426209e9c7b35e279e1578a89edc40af6Dan Gohman // Iterate through the indices, folding what we can. Constants can be 416c8a1a3c426209e9c7b35e279e1578a89edc40af6Dan Gohman // folded, and one dynamic index can be handled, if the scale is supported. 41746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); 4183589308f37177f28257dd1a39dc6d6395a435acbDan Gohman i != e; ++i, ++GTI) { 41946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Value *Op = *i; 420db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner if (StructType *STy = dyn_cast<StructType>(*GTI)) { 4213589308f37177f28257dd1a39dc6d6395a435acbDan Gohman const StructLayout *SL = TD.getStructLayout(STy); 422dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner Disp += SL->getElementOffset(cast<ConstantInt>(Op)->getZExtValue()); 423dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner continue; 424dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner } 425471e4224809f51652c71f319532697a879a75a0dEric Christopher 426dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // A array/variable index is always of the form i*S where S is the 427dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // constant scale size. See if we can push the scale into immediates. 428dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType()); 429dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner for (;;) { 430dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { 431dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // Constant-offset addressing. 432dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner Disp += CI->getSExtValue() * S; 433dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner break; 434dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner } 435dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner if (isa<AddOperator>(Op) && 436dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner (!isa<Instruction>(Op) || 437dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner FuncInfo.MBBMap[cast<Instruction>(Op)->getParent()] 438dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner == FuncInfo.MBB) && 439dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) { 440dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // An add (in the same block) with a constant operand. Fold the 441dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // constant. 442dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner ConstantInt *CI = 443dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1)); 444dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner Disp += CI->getSExtValue() * S; 445dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // Iterate on the other operand. 446dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner Op = cast<AddOperator>(Op)->getOperand(0); 447dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner continue; 448dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner } 449dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner if (IndexReg == 0 && 450dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner (!AM.GV || !Subtarget->isPICStyleRIPRel()) && 451dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner (S == 1 || S == 2 || S == 4 || S == 8)) { 452dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // Scaled-index addressing. 453dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner Scale = S; 454dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner IndexReg = getRegForGEPIndex(Op).first; 455dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner if (IndexReg == 0) 456dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner return false; 457dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner break; 458b55d6b6a7ea64f1cd168181f619aaa2f7080855aDan Gohman } 459dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // Unsupported. 460dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner goto unsupported_gep; 4613589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 4620586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman } 46309aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman // Check for displacement overflow. 46434247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer if (!isInt<32>(Disp)) 46509aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman break; 4663589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Ok, the GEP indices were covered by constant-offset and scaled-index 4673589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // addressing. Update the address state and move on to examining the base. 4683589308f37177f28257dd1a39dc6d6395a435acbDan Gohman AM.IndexReg = IndexReg; 4693589308f37177f28257dd1a39dc6d6395a435acbDan Gohman AM.Scale = Scale; 47009aae469cee47c0572cbfcf3a3baa332aa3b5258Dan Gohman AM.Disp = (uint32_t)Disp; 471225d4ca8ab7c7d0e7fa0c7d43d95308b16edc554Chris Lattner if (X86SelectAddress(U->getOperand(0), AM)) 472225d4ca8ab7c7d0e7fa0c7d43d95308b16edc554Chris Lattner return true; 473bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 474dceb52a01b21425e3b4611957ec4988b991ec5a8Chris Lattner // If we couldn't merge the gep value into this addr mode, revert back to 475225d4ca8ab7c7d0e7fa0c7d43d95308b16edc554Chris Lattner // our address and just match the value instead of completely failing. 476225d4ca8ab7c7d0e7fa0c7d43d95308b16edc554Chris Lattner AM = SavedAM; 477225d4ca8ab7c7d0e7fa0c7d43d95308b16edc554Chris Lattner break; 4783589308f37177f28257dd1a39dc6d6395a435acbDan Gohman unsupported_gep: 4793589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Ok, the GEP indices weren't all covered. 4803589308f37177f28257dd1a39dc6d6395a435acbDan Gohman break; 4813589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 4823589308f37177f28257dd1a39dc6d6395a435acbDan Gohman } 4833589308f37177f28257dd1a39dc6d6395a435acbDan Gohman 4843589308f37177f28257dd1a39dc6d6395a435acbDan Gohman // Handle constant address. 48546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) { 486a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman // Can't handle alternate code models yet. 487f1d6bd5cbe6ae4a9327b159dcbc0810f0affd0fbChris Lattner if (TM.getCodeModel() != CodeModel::Small) 4882cc3aa44591313307e2d596daca784419ab7286dDan Gohman return false; 4892cc3aa44591313307e2d596daca784419ab7286dDan Gohman 490a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman // Can't handle TLS yet. 49146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 492e9865945ad8286a007d8b8465703c5b242f94caaDan Gohman if (GVar->isThreadLocal()) 493e9865945ad8286a007d8b8465703c5b242f94caaDan Gohman return false; 494471e4224809f51652c71f319532697a879a75a0dEric Christopher 495a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman // Can't handle TLS yet, part 2 (this is slightly crazy, but this is how 496a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman // it works...). 497a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) 498a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman if (const GlobalVariable *GVar = 499a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false))) 500a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman if (GVar->isThreadLocal()) 501a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman return false; 502a6176adc8aad5d37268f40e49ae58c0eae2323c2Eli Friedman 5030a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // RIP-relative addresses can't have additional register operands, so if 5040a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // we've already folded stuff into the addressing mode, just force the 5050a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // global value into its own register, which we can use as the basereg. 5060a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (!Subtarget->isPICStyleRIPRel() || 5070a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner (AM.Base.Reg == 0 && AM.IndexReg == 0)) { 5080a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Okay, we've committed to selecting this global. Set up the address. 5090a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner AM.GV = GV; 5100a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner 5110a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Allow the subtarget to classify the global. 5120a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner unsigned char GVFlags = Subtarget->ClassifyGlobalReference(GV, TM); 5130a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner 5140a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // If this reference is relative to the pic base, set it now. 5150a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (isGlobalRelativeToPICBase(GVFlags)) { 5160a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // FIXME: How do we know Base.Reg is free?? 5170a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner AM.Base.Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF); 5180a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner } 519e9865945ad8286a007d8b8465703c5b242f94caaDan Gohman 5200a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Unless the ABI requires an extra load, return a direct reference to 5210a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // the global. 5220a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (!isGlobalStubReference(GVFlags)) { 5230a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (Subtarget->isPICStyleRIPRel()) { 5240a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Use rip-relative addressing if we can. Above we verified that the 5250a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // base and index registers are unused. 5260a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner assert(AM.Base.Reg == 0 && AM.IndexReg == 0); 5270a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner AM.Base.Reg = X86::RIP; 5280a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner } 5290a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner AM.GVOpFlags = GVFlags; 5300a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner return true; 5310aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 532bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 5330a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Ok, we need to do a load from a stub. If we've already loaded from 5340a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // this stub, reuse the loaded pointer, otherwise emit the load now. 5350a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner DenseMap<const Value*, unsigned>::iterator I = LocalValueMap.find(V); 5360a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner unsigned LoadReg; 5370a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (I != LocalValueMap.end() && I->second != 0) { 5380a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner LoadReg = I->second; 5390aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } else { 5400a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Issue load from stub. 5410a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner unsigned Opc = 0; 5420a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner const TargetRegisterClass *RC = NULL; 5430a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner X86AddressMode StubAM; 5440a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner StubAM.Base.Reg = AM.Base.Reg; 5450a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner StubAM.GV = GV; 5460a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner StubAM.GVOpFlags = GVFlags; 5470a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner 5480a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Prepare for inserting code in the local-value area. 54976ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher SavePoint SaveInsertPt = enterLocalValueArea(); 5500a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner 5510a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (TLI.getPointerTy() == MVT::i64) { 5520a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner Opc = X86::MOV64rm; 553c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR64RegClass; 5540a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner 5550a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner if (Subtarget->isPICStyleRIPRel()) 5560a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner StubAM.Base.Reg = X86::RIP; 5570a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner } else { 5580a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner Opc = X86::MOV32rm; 559c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR32RegClass; 5600a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner } 561bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 5620a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner LoadReg = createResultReg(RC); 5630a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner MachineInstrBuilder LoadMI = 5640a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), LoadReg); 5650a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner addFullAddress(LoadMI, StubAM); 56684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 5670a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Ok, back to normal mode. 56876ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher leaveLocalValueArea(SaveInsertPt); 56984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 5700a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Prevent loading GV stub multiple times in same MBB. 5710a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner LocalValueMap[V] = LoadReg; 5720a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner } 573bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 5740a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // Now construct the final address. Note that the Disp, Scale, 5750a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner // and Index values may already be set here. 5760a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner AM.Base.Reg = LoadReg; 5770a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner AM.GV = 0; 5780a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner return true; 5790a1c997c27706e315efb61b8b3e110d42cbaae64Chris Lattner } 5800aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 5810aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 5820aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // If all else fails, try to materialize the value in a register. 5830aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (!AM.GV || !Subtarget->isPICStyleRIPRel()) { 5840aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (AM.Base.Reg == 0) { 5850aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner AM.Base.Reg = getRegForValue(V); 5860aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return AM.Base.Reg != 0; 5870aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 5880aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (AM.IndexReg == 0) { 5890aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner assert(AM.Scale == 1 && "Scale with no index!"); 5900aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner AM.IndexReg = getRegForValue(V); 5910aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return AM.IndexReg != 0; 5920aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 5930aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 5940aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 5950aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return false; 5960aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner} 5970aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 5980aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner/// X86SelectCallAddress - Attempt to fill in an address from the given value. 5990aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner/// 60046510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectCallAddress(const Value *V, X86AddressMode &AM) { 60146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const User *U = NULL; 6020aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner unsigned Opcode = Instruction::UserOp1; 60346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const Instruction *I = dyn_cast<Instruction>(V)) { 6040aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner Opcode = I->getOpcode(); 6050aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner U = I; 60646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(V)) { 6070aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner Opcode = C->getOpcode(); 6080aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner U = C; 6090aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 6100aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6110aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner switch (Opcode) { 6120aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner default: break; 6130aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner case Instruction::BitCast: 6140aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // Look past bitcasts. 6150aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectCallAddress(U->getOperand(0), AM); 6160aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6170aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner case Instruction::IntToPtr: 6180aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // Look past no-op inttoptrs. 6190aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy()) 6200aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectCallAddress(U->getOperand(0), AM); 6210aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner break; 6220aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6230aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner case Instruction::PtrToInt: 6240aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // Look past no-op ptrtoints. 6250aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (TLI.getValueType(U->getType()) == TLI.getPointerTy()) 6260aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return X86SelectCallAddress(U->getOperand(0), AM); 6270aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner break; 6280aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner } 6290aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6300aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // Handle constant address. 63146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) { 6320aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // Can't handle alternate code models yet. 633f1d6bd5cbe6ae4a9327b159dcbc0810f0affd0fbChris Lattner if (TM.getCodeModel() != CodeModel::Small) 6340aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return false; 6350aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6360aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // RIP-relative addresses can't have additional register operands. 6370aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (Subtarget->isPICStyleRIPRel() && 6380aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner (AM.Base.Reg != 0 || AM.IndexReg != 0)) 6390aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return false; 6400aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 641d64cfe1506daf95483549e7347098fbf1a978097NAKAMURA Takumi // Can't handle DLLImport. 642d64cfe1506daf95483549e7347098fbf1a978097NAKAMURA Takumi if (GV->hasDLLImportLinkage()) 643d64cfe1506daf95483549e7347098fbf1a978097NAKAMURA Takumi return false; 644d64cfe1506daf95483549e7347098fbf1a978097NAKAMURA Takumi 645d64cfe1506daf95483549e7347098fbf1a978097NAKAMURA Takumi // Can't handle TLS. 64646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 647d64cfe1506daf95483549e7347098fbf1a978097NAKAMURA Takumi if (GVar->isThreadLocal()) 6480aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner return false; 6490aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6500aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner // Okay, we've committed to selecting this global. Set up the basic address. 6510aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner AM.GV = GV; 652bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 653e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner // No ABI requires an extra load for anything other than DLLImport, which 654e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner // we rejected above. Return a direct reference to the global. 655e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner if (Subtarget->isPICStyleRIPRel()) { 656e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner // Use rip-relative addressing if we can. Above we verified that the 657e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner // base and index registers are unused. 658e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner assert(AM.Base.Reg == 0 && AM.IndexReg == 0); 659e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner AM.Base.Reg = X86::RIP; 660e2c920845a407957b8ae2600feae1f4c85a0d4d0Chris Lattner } else if (Subtarget->isPICStyleStubPIC()) { 661e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner AM.GVOpFlags = X86II::MO_PIC_BASE_OFFSET; 662e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner } else if (Subtarget->isPICStyleGOT()) { 663e6c07b52e76b19d83338901b2e103bd8cbabd42fChris Lattner AM.GVOpFlags = X86II::MO_GOTOFF; 664ff7727f4f71ffba1d1e6dcf9b6a91202b6238016Chris Lattner } 665bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 6662ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman return true; 6670586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman } 6680586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman 66997135e1ee51357245561a5108f90a8a1161431a1Dan Gohman // If all else fails, try to materialize the value in a register. 6704c1b606ecd9cb02c0ae1e468ad57d76d6d96bc26Chris Lattner if (!AM.GV || !Subtarget->isPICStyleRIPRel()) { 67197135e1ee51357245561a5108f90a8a1161431a1Dan Gohman if (AM.Base.Reg == 0) { 67297135e1ee51357245561a5108f90a8a1161431a1Dan Gohman AM.Base.Reg = getRegForValue(V); 67397135e1ee51357245561a5108f90a8a1161431a1Dan Gohman return AM.Base.Reg != 0; 67497135e1ee51357245561a5108f90a8a1161431a1Dan Gohman } 67597135e1ee51357245561a5108f90a8a1161431a1Dan Gohman if (AM.IndexReg == 0) { 67697135e1ee51357245561a5108f90a8a1161431a1Dan Gohman assert(AM.Scale == 1 && "Scale with no index!"); 67797135e1ee51357245561a5108f90a8a1161431a1Dan Gohman AM.IndexReg = getRegForValue(V); 67897135e1ee51357245561a5108f90a8a1161431a1Dan Gohman return AM.IndexReg != 0; 67997135e1ee51357245561a5108f90a8a1161431a1Dan Gohman } 68097135e1ee51357245561a5108f90a8a1161431a1Dan Gohman } 68197135e1ee51357245561a5108f90a8a1161431a1Dan Gohman 68297135e1ee51357245561a5108f90a8a1161431a1Dan Gohman return false; 6830586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman} 6840586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman 6850aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner 6860de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng/// X86SelectStore - Select and emit code to implement store instructions. 68746510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectStore(const Instruction *I) { 6884136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman // Atomic stores need special handling. 689e4824714026a528fe4cb08ad73e048066980eda6Lang Hames const StoreInst *S = cast<StoreInst>(I); 690e4824714026a528fe4cb08ad73e048066980eda6Lang Hames 691e4824714026a528fe4cb08ad73e048066980eda6Lang Hames if (S->isAtomic()) 692e4824714026a528fe4cb08ad73e048066980eda6Lang Hames return false; 693e4824714026a528fe4cb08ad73e048066980eda6Lang Hames 694e4824714026a528fe4cb08ad73e048066980eda6Lang Hames unsigned SABIAlignment = 695e4824714026a528fe4cb08ad73e048066980eda6Lang Hames TD.getABITypeAlignment(S->getValueOperand()->getType()); 696e4824714026a528fe4cb08ad73e048066980eda6Lang Hames if (S->getAlignment() != 0 && S->getAlignment() < SABIAlignment) 6974136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman return false; 6984136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman 6991440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 7007e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman if (!isTypeLegal(I->getOperand(0)->getType(), VT, /*AllowI1=*/true)) 7010de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng return false; 7020de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng 7030586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman X86AddressMode AM; 7040aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (!X86SelectAddress(I->getOperand(1), AM)) 7050586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman return false; 7060de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng 707438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner return X86FastEmitStore(VT, I->getOperand(0), AM); 7080de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng} 7090de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng 71084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman/// X86SelectRet - Select and emit code to implement ret instructions. 71184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohmanbool X86FastISel::X86SelectRet(const Instruction *I) { 71284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman const ReturnInst *Ret = cast<ReturnInst>(I); 71384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman const Function &F = *I->getParent()->getParent(); 714b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky const X86MachineFunctionInfo *X86MFInfo = 715b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky FuncInfo.MF->getInfo<X86MachineFunctionInfo>(); 71684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 71784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (!FuncInfo.CanLowerReturn) 71884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 71984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 72084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman CallingConv::ID CC = F.getCallingConv(); 72184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (CC != CallingConv::C && 72284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman CC != CallingConv::Fast && 72384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman CC != CallingConv::X86_FastCall) 72484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 72584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 72684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (Subtarget->isTargetWin64()) 72784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 72884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 72984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Don't handle popping bytes on return for now. 730b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky if (X86MFInfo->getBytesToPopOnReturn() != 0) 731d61932bf844134d886b57e6730a5ae0831ebd115Jakub Staszak return false; 73284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 73384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // fastcc with -tailcallopt is intended to provide a guaranteed 73484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // tail call optimization. Fastisel doesn't know how to do that. 7358a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) 73684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 73784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 73884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Let SDISel handle vararg functions. 73984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (F.isVarArg()) 74084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 74184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 742c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen // Build a list of return value registers. 743c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen SmallVector<unsigned, 4> RetRegs; 744c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen 74584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (Ret->getNumOperands() > 0) { 74684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman SmallVector<ISD::OutputArg, 4> Outs; 7478b62abdd7b9c8fc5d78dad86093f4afdfeba949dBill Wendling GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI); 74884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 74984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Analyze operands of the call, assigning locations to each operand. 75084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman SmallVector<CCValAssign, 16> ValLocs; 751471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs, 75256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling I->getContext()); 753e26032d5b26e7b2a1158d6980b7e42390a1f34c5Duncan Sands CCInfo.AnalyzeReturn(Outs, RetCC_X86); 75484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 75584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman const Value *RV = Ret->getOperand(0); 75684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman unsigned Reg = getRegForValue(RV); 75784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (Reg == 0) 75884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 75984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 76084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Only handle a single return value for now. 76184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (ValLocs.size() != 1) 76284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 76384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 76484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman CCValAssign &VA = ValLocs[0]; 765bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 76684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Don't bother handling odd stuff for now. 76784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (VA.getLocInfo() != CCValAssign::Full) 76884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 76984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Only handle register returns for now. 77084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (!VA.isRegLoc()) 77184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 77284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 77384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // The calling-convention tables for x87 returns don't tell 77484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // the whole story. 77584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (VA.getLocReg() == X86::ST0 || VA.getLocReg() == X86::ST1) 77684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 77784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 77822486c9abacf32c47bf1707bee45f677d2b50358Eli Friedman unsigned SrcReg = Reg + VA.getValNo(); 779dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman EVT SrcVT = TLI.getValueType(RV->getType()); 780dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman EVT DstVT = VA.getValVT(); 781dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman // Special handling for extended integers. 782dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman if (SrcVT != DstVT) { 783dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16) 784dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman return false; 785dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman 786dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt()) 787dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman return false; 788dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman 789dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman assert(DstVT == MVT::i32 && "X86 should always ext to i32"); 790dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman 791dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman if (SrcVT == MVT::i1) { 792dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman if (Outs[0].Flags.isSExt()) 793dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman return false; 794dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman SrcReg = FastEmitZExtFromI1(MVT::i8, SrcReg, /*TODO: Kill=*/false); 795dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman SrcVT = MVT::i8; 796dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman } 797dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman unsigned Op = Outs[0].Flags.isZExt() ? ISD::ZERO_EXTEND : 798dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman ISD::SIGN_EXTEND; 799dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman SrcReg = FastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Op, 800dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman SrcReg, /*TODO: Kill=*/false); 801dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman } 802dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman 803dc51575a5f813164e96c7c1ab41aaf33585573f6Eli Friedman // Make the copy. 80484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman unsigned DstReg = VA.getLocReg(); 80584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman const TargetRegisterClass* SrcRC = MRI.getRegClass(SrcReg); 8061ba318982e4dcca66b6cf7ce624af2ba8a55d9d8Jakob Stoklund Olesen // Avoid a cross-class copy. This is very unlikely. 8071ba318982e4dcca66b6cf7ce624af2ba8a55d9d8Jakob Stoklund Olesen if (!SrcRC->contains(DstReg)) 80884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return false; 8091ba318982e4dcca66b6cf7ce624af2ba8a55d9d8Jakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 8101ba318982e4dcca66b6cf7ce624af2ba8a55d9d8Jakob Stoklund Olesen DstReg).addReg(SrcReg); 81184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 812c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen // Add register to return instruction. 813c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen RetRegs.push_back(VA.getLocReg()); 81484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman } 81584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 816b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky // The x86-64 ABI for returning structs by value requires that we copy 817b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky // the sret argument into %rax for the return. We saved the argument into 818b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky // a virtual register in the entry block, so now we copy the value out 819b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky // and into %rax. 820b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky if (Subtarget->is64Bit() && F.hasStructRetAttr()) { 821b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky unsigned Reg = X86MFInfo->getSRetReturnReg(); 822b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky assert(Reg && 823b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky "SRetReturnReg should have been set in LowerFormalArguments()!"); 824b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 825b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky X86::RAX).addReg(Reg); 826c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen RetRegs.push_back(X86::RAX); 827b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky } 828b09649b3356ab793e304ddd444206bf91000d7eeNick Lewycky 82984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman // Now emit the RET. 830c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen MachineInstrBuilder MIB = 831c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::RET)); 832c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen for (unsigned i = 0, e = RetRegs.size(); i != e; ++i) 833c3afc760e1a49f29634b7442a3d38bc88a1f113eJakob Stoklund Olesen MIB.addReg(RetRegs[i], RegState::Implicit); 83484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return true; 83584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman} 83684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman 8378b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng/// X86SelectLoad - Select and emit code to implement load instructions. 8388b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng/// 83946510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectLoad(const Instruction *I) { 8404136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman // Atomic loads need special handling. 8414136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman if (cast<LoadInst>(I)->isAtomic()) 8424136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman return false; 8434136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman 8441440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 8457e7f06e70a07be4a5fad81883da6bebf33e1b3f6Dan Gohman if (!isTypeLegal(I->getType(), VT, /*AllowI1=*/true)) 8468b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng return false; 8478b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng 8480586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman X86AddressMode AM; 8490aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (!X86SelectAddress(I->getOperand(0), AM)) 8500586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman return false; 8518b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng 8520de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng unsigned ResultReg = 0; 8530586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman if (X86FastEmitLoad(VT, AM, ResultReg)) { 8540de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng UpdateValueMap(I, ResultReg); 8550de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng return true; 8568b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng } 8570de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng return false; 8588b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng} 8598b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng 86075be45cb2ef637f62744a5ac114a5029c5b41503Jakob Stoklund Olesenstatic unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget) { 861645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes bool HasAVX = Subtarget->hasAVX(); 8621accb7ed98d823c291a4d5df172d0538451aba9eCraig Topper bool X86ScalarSSEf32 = Subtarget->hasSSE1(); 8631accb7ed98d823c291a4d5df172d0538451aba9eCraig Topper bool X86ScalarSSEf64 = Subtarget->hasSSE2(); 864645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes 865825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 86645ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner default: return 0; 867825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: return X86::CMP8rr; 868825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: return X86::CMP16rr; 869825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: return X86::CMP32rr; 870825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: return X86::CMP64rr; 871645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes case MVT::f32: 872645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes return X86ScalarSSEf32 ? (HasAVX ? X86::VUCOMISSrr : X86::UCOMISSrr) : 0; 873645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes case MVT::f64: 874645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes return X86ScalarSSEf64 ? (HasAVX ? X86::VUCOMISDrr : X86::UCOMISDrr) : 0; 875d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman } 876d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman} 877d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman 8780e13c78347bdcd1a4ba9b2e78d1389a46bf52c2cChris Lattner/// X86ChooseCmpImmediateOpcode - If we have a comparison with RHS as the RHS 8790e13c78347bdcd1a4ba9b2e78d1389a46bf52c2cChris Lattner/// of the comparison, return an opcode that works for the compare (e.g. 8800e13c78347bdcd1a4ba9b2e78d1389a46bf52c2cChris Lattner/// CMP32ri) otherwise return 0. 88146510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanstatic unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC) { 882825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 8830e13c78347bdcd1a4ba9b2e78d1389a46bf52c2cChris Lattner // Otherwise, we can't fold the immediate into this comparison. 88445ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner default: return 0; 885825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: return X86::CMP8ri; 886825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: return X86::CMP16ri; 887825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: return X86::CMP32ri; 888825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: 88945ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner // 64-bit comparisons are only valid if the immediate fits in a 32-bit sext 89045ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner // field. 891438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner if ((int)RHSC->getSExtValue() == RHSC->getSExtValue()) 89245ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner return X86::CMP64ri32; 89345ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner return 0; 89445ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner } 8950e13c78347bdcd1a4ba9b2e78d1389a46bf52c2cChris Lattner} 8960e13c78347bdcd1a4ba9b2e78d1389a46bf52c2cChris Lattner 89746510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86FastEmitCompare(const Value *Op0, const Value *Op1, 89846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman EVT VT) { 8999a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner unsigned Op0Reg = getRegForValue(Op0); 9009a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner if (Op0Reg == 0) return false; 901bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 902d53886bb488fbef11b8083d7e99bcf53a51861a0Chris Lattner // Handle 'null' like i32/i64 0. 903ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth if (isa<ConstantPointerNull>(Op1)) 904ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth Op1 = Constant::getNullValue(TD.getIntPtrType(Op0->getContext())); 905bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9069a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner // We have two options: compare with register or immediate. If the RHS of 9079a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner // the compare is an immediate that we can fold into this compare, use 9089a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner // CMPri, otherwise use CMPrr. 90946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { 91045ac17f5213ee9ad080b9876578ffa49c61121a5Chris Lattner if (unsigned CompareImmOpc = X86ChooseCmpImmediateOpcode(VT, Op1C)) { 91184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CompareImmOpc)) 91284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Op0Reg) 91384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addImm(Op1C->getSExtValue()); 9149a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner return true; 9159a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner } 9169a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner } 917bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 91875be45cb2ef637f62744a5ac114a5029c5b41503Jakob Stoklund Olesen unsigned CompareOpc = X86ChooseCmpOpcode(VT, Subtarget); 9199a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner if (CompareOpc == 0) return false; 920bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9219a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner unsigned Op1Reg = getRegForValue(Op1); 9229a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner if (Op1Reg == 0) return false; 92384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CompareOpc)) 92484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Op0Reg) 92584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Op1Reg); 926bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9279a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner return true; 9289a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner} 9299a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner 93046510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectCmp(const Instruction *I) { 93146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const CmpInst *CI = cast<CmpInst>(I); 9326e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman 9331440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 934160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner if (!isTypeLegal(I->getOperand(0)->getType(), VT)) 9354f22bb0676e09aacf6898c5b9ab489a8b01f8fc0Dan Gohman return false; 9364f22bb0676e09aacf6898c5b9ab489a8b01f8fc0Dan Gohman 9376e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman unsigned ResultReg = createResultReg(&X86::GR8RegClass); 93854aebde0be490d6d3d925b0fc1c3f4de0a5356bfChris Lattner unsigned SetCCOpc; 9398aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner bool SwapArgs; // false -> compare Op0, Op1. true -> compare Op1, Op0. 9406e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman switch (CI->getPredicate()) { 9416e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman case CmpInst::FCMP_OEQ: { 94251ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner if (!X86FastEmitCompare(CI->getOperand(0), CI->getOperand(1), VT)) 94351ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner return false; 944bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9456e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman unsigned EReg = createResultReg(&X86::GR8RegClass); 9466e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman unsigned NPReg = createResultReg(&X86::GR8RegClass); 94784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::SETEr), EReg); 94884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 94984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(X86::SETNPr), NPReg); 950bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 9518d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen TII.get(X86::AND8rr), ResultReg).addReg(NPReg).addReg(EReg); 95254aebde0be490d6d3d925b0fc1c3f4de0a5356bfChris Lattner UpdateValueMap(I, ResultReg); 95354aebde0be490d6d3d925b0fc1c3f4de0a5356bfChris Lattner return true; 9546e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman } 9556e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman case CmpInst::FCMP_UNE: { 95651ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner if (!X86FastEmitCompare(CI->getOperand(0), CI->getOperand(1), VT)) 95751ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner return false; 95851ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner 9596e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman unsigned NEReg = createResultReg(&X86::GR8RegClass); 9606e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman unsigned PReg = createResultReg(&X86::GR8RegClass); 96190cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::SETNEr), NEReg); 96290cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::SETPr), PReg); 96390cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::OR8rr),ResultReg) 96484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(PReg).addReg(NEReg); 96554aebde0be490d6d3d925b0fc1c3f4de0a5356bfChris Lattner UpdateValueMap(I, ResultReg); 96654aebde0be490d6d3d925b0fc1c3f4de0a5356bfChris Lattner return true; 9676e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman } 9688aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_OGT: SwapArgs = false; SetCCOpc = X86::SETAr; break; 9698aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_OGE: SwapArgs = false; SetCCOpc = X86::SETAEr; break; 9708aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_OLT: SwapArgs = true; SetCCOpc = X86::SETAr; break; 9718aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_OLE: SwapArgs = true; SetCCOpc = X86::SETAEr; break; 9728aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_ONE: SwapArgs = false; SetCCOpc = X86::SETNEr; break; 9738aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_ORD: SwapArgs = false; SetCCOpc = X86::SETNPr; break; 9748aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_UNO: SwapArgs = false; SetCCOpc = X86::SETPr; break; 9758aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_UEQ: SwapArgs = false; SetCCOpc = X86::SETEr; break; 9768aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_UGT: SwapArgs = true; SetCCOpc = X86::SETBr; break; 9778aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_UGE: SwapArgs = true; SetCCOpc = X86::SETBEr; break; 9788aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_ULT: SwapArgs = false; SetCCOpc = X86::SETBr; break; 9798aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::FCMP_ULE: SwapArgs = false; SetCCOpc = X86::SETBEr; break; 980bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9818aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_EQ: SwapArgs = false; SetCCOpc = X86::SETEr; break; 9828aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_NE: SwapArgs = false; SetCCOpc = X86::SETNEr; break; 9838aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_UGT: SwapArgs = false; SetCCOpc = X86::SETAr; break; 9848aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_UGE: SwapArgs = false; SetCCOpc = X86::SETAEr; break; 9858aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_ULT: SwapArgs = false; SetCCOpc = X86::SETBr; break; 9868aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_ULE: SwapArgs = false; SetCCOpc = X86::SETBEr; break; 9878aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_SGT: SwapArgs = false; SetCCOpc = X86::SETGr; break; 9888aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_SGE: SwapArgs = false; SetCCOpc = X86::SETGEr; break; 9898aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_SLT: SwapArgs = false; SetCCOpc = X86::SETLr; break; 9908aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner case CmpInst::ICMP_SLE: SwapArgs = false; SetCCOpc = X86::SETLEr; break; 9916e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman default: 9926e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman return false; 9936e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman } 9946e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman 99546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1); 9968aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner if (SwapArgs) 9979a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner std::swap(Op0, Op1); 9988aeeeb9d24fe36dab5d193174487f05a1fa640d3Chris Lattner 9999a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner // Emit a compare of Op0/Op1. 100051ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner if (!X86FastEmitCompare(Op0, Op1, VT)) 100151ccb3deba7ccf2a3f154a9c4e4182146eccc846Chris Lattner return false; 1002bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 100384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(SetCCOpc), ResultReg); 10046e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman UpdateValueMap(I, ResultReg); 10056e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman return true; 10066e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman} 10078b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng 100846510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectZExt(const Instruction *I) { 100914ea1ec2324cb595f2e035bbf54ddcd483f17c11Dan Gohman // Handle zero-extension from i1 to i8, which is common. 1010471e4224809f51652c71f319532697a879a75a0dEric Christopher if (!I->getOperand(0)->getType()->isIntegerTy(1)) 101176927d7303046058c627691bd45d6bff608f49f4Eli Friedman return false; 101276927d7303046058c627691bd45d6bff608f49f4Eli Friedman 101376927d7303046058c627691bd45d6bff608f49f4Eli Friedman EVT DstVT = TLI.getValueType(I->getType()); 101476927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (!TLI.isTypeLegal(DstVT)) 101576927d7303046058c627691bd45d6bff608f49f4Eli Friedman return false; 101676927d7303046058c627691bd45d6bff608f49f4Eli Friedman 101776927d7303046058c627691bd45d6bff608f49f4Eli Friedman unsigned ResultReg = getRegForValue(I->getOperand(0)); 101876927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (ResultReg == 0) 101976927d7303046058c627691bd45d6bff608f49f4Eli Friedman return false; 102076927d7303046058c627691bd45d6bff608f49f4Eli Friedman 102176927d7303046058c627691bd45d6bff608f49f4Eli Friedman // Set the high bits to zero. 102276927d7303046058c627691bd45d6bff608f49f4Eli Friedman ResultReg = FastEmitZExtFromI1(MVT::i8, ResultReg, /*TODO: Kill=*/false); 102376927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (ResultReg == 0) 102476927d7303046058c627691bd45d6bff608f49f4Eli Friedman return false; 102576927d7303046058c627691bd45d6bff608f49f4Eli Friedman 102676927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (DstVT != MVT::i8) { 102776927d7303046058c627691bd45d6bff608f49f4Eli Friedman ResultReg = FastEmit_r(MVT::i8, DstVT.getSimpleVT(), ISD::ZERO_EXTEND, 102876927d7303046058c627691bd45d6bff608f49f4Eli Friedman ResultReg, /*Kill=*/true); 102976927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (ResultReg == 0) 103076927d7303046058c627691bd45d6bff608f49f4Eli Friedman return false; 1031d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman } 1032d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman 103376927d7303046058c627691bd45d6bff608f49f4Eli Friedman UpdateValueMap(I, ResultReg); 103476927d7303046058c627691bd45d6bff608f49f4Eli Friedman return true; 1035d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman} 1036d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman 10379a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner 103846510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectBranch(const Instruction *I) { 1039d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman // Unconditional branches are selected by tablegen-generated code. 1040d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman // Handle a conditional branch. 104146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const BranchInst *BI = cast<BranchInst>(I); 1042a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman MachineBasicBlock *TrueMBB = FuncInfo.MBBMap[BI->getSuccessor(0)]; 1043a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman MachineBasicBlock *FalseMBB = FuncInfo.MBBMap[BI->getSuccessor(1)]; 1044d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman 10458bef744518e5904b77ad903d6f05241f9f807a97Dan Gohman // Fold the common case of a conditional branch with a comparison 10468bef744518e5904b77ad903d6f05241f9f807a97Dan Gohman // in the same block (values defined on other blocks may not have 10478bef744518e5904b77ad903d6f05241f9f807a97Dan Gohman // initialized registers). 104846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) { 10498bef744518e5904b77ad903d6f05241f9f807a97Dan Gohman if (CI->hasOneUse() && CI->getParent() == I->getParent()) { 1050e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = TLI.getValueType(CI->getOperand(0)->getType()); 1051d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman 1052d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman // Try to take advantage of fallthrough opportunities. 1053d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman CmpInst::Predicate Predicate = CI->getPredicate(); 105484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) { 1055d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman std::swap(TrueMBB, FalseMBB); 1056d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman Predicate = CmpInst::getInversePredicate(Predicate); 1057d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman } 1058d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman 1059871d246fd4d14d590297123b2a6cb0a601b3d81aChris Lattner bool SwapArgs; // false -> compare Op0, Op1. true -> compare Op1, Op0. 1060871d246fd4d14d590297123b2a6cb0a601b3d81aChris Lattner unsigned BranchOpc; // Opcode to jump on, e.g. "X86::JA" 1061871d246fd4d14d590297123b2a6cb0a601b3d81aChris Lattner 1062d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman switch (Predicate) { 10637b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman case CmpInst::FCMP_OEQ: 10647b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman std::swap(TrueMBB, FalseMBB); 10657b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman Predicate = CmpInst::FCMP_UNE; 10667b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman // FALL THROUGH 1067bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_UNE: SwapArgs = false; BranchOpc = X86::JNE_4; break; 1068bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_OGT: SwapArgs = false; BranchOpc = X86::JA_4; break; 1069bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_OGE: SwapArgs = false; BranchOpc = X86::JAE_4; break; 1070bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_OLT: SwapArgs = true; BranchOpc = X86::JA_4; break; 1071bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_OLE: SwapArgs = true; BranchOpc = X86::JAE_4; break; 1072bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_ONE: SwapArgs = false; BranchOpc = X86::JNE_4; break; 1073bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_ORD: SwapArgs = false; BranchOpc = X86::JNP_4; break; 1074bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_UNO: SwapArgs = false; BranchOpc = X86::JP_4; break; 1075bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_UEQ: SwapArgs = false; BranchOpc = X86::JE_4; break; 1076bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_UGT: SwapArgs = true; BranchOpc = X86::JB_4; break; 1077bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_UGE: SwapArgs = true; BranchOpc = X86::JBE_4; break; 1078bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_ULT: SwapArgs = false; BranchOpc = X86::JB_4; break; 1079bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::FCMP_ULE: SwapArgs = false; BranchOpc = X86::JBE_4; break; 1080bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1081bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_EQ: SwapArgs = false; BranchOpc = X86::JE_4; break; 1082bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_NE: SwapArgs = false; BranchOpc = X86::JNE_4; break; 1083bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_UGT: SwapArgs = false; BranchOpc = X86::JA_4; break; 1084bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_UGE: SwapArgs = false; BranchOpc = X86::JAE_4; break; 1085bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_ULT: SwapArgs = false; BranchOpc = X86::JB_4; break; 1086bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_ULE: SwapArgs = false; BranchOpc = X86::JBE_4; break; 1087bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_SGT: SwapArgs = false; BranchOpc = X86::JG_4; break; 1088bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_SGE: SwapArgs = false; BranchOpc = X86::JGE_4; break; 1089bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_SLT: SwapArgs = false; BranchOpc = X86::JL_4; break; 1090bd13fb62541136a4891d702feec8b7aba5bf695aChris Lattner case CmpInst::ICMP_SLE: SwapArgs = false; BranchOpc = X86::JLE_4; break; 1091d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman default: 1092d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman return false; 1093d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman } 1094bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 109546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1); 1096871d246fd4d14d590297123b2a6cb0a601b3d81aChris Lattner if (SwapArgs) 1097709d829d3cb451599f1834b8cd9af0d9083107e0Chris Lattner std::swap(Op0, Op1); 1098709d829d3cb451599f1834b8cd9af0d9083107e0Chris Lattner 10999a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner // Emit a compare of the LHS and RHS, setting the flags. 11009a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner if (!X86FastEmitCompare(Op0, Op1, VT)) 11019a08a61d7908004b061d560b11917e5c1c7ecc02Chris Lattner return false; 1102bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 110384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BranchOpc)) 110484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addMBB(TrueMBB); 11057b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman 11067b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman if (Predicate == CmpInst::FCMP_UNE) { 11077b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman // X86 requires a second branch to handle UNE (and OEQ, 11087b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman // which is mapped to UNE above). 110984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::JP_4)) 111084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addMBB(TrueMBB); 11117b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman } 11127b66e041821309306beccda0fe58ffa096ee1f4aDan Gohman 11133bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings FastEmitBranch(FalseMBB, DL); 111484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman FuncInfo.MBB->addSuccessor(TrueMBB); 1115d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman return true; 1116d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman } 111790cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) { 111890cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner // Handle things like "%cond = trunc i32 %X to i1 / br i1 %cond", which 111990cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner // typically happen for _Bool and C++ bools. 112090cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner MVT SourceVT; 112190cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner if (TI->hasOneUse() && TI->getParent() == I->getParent() && 112290cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) { 112390cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner unsigned TestOpc = 0; 112490cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner switch (SourceVT.SimpleTy) { 112590cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner default: break; 112690cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner case MVT::i8: TestOpc = X86::TEST8ri; break; 112790cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner case MVT::i16: TestOpc = X86::TEST16ri; break; 112890cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner case MVT::i32: TestOpc = X86::TEST32ri; break; 112990cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner case MVT::i64: TestOpc = X86::TEST64ri32; break; 113090cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner } 113190cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner if (TestOpc) { 113290cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner unsigned OpReg = getRegForValue(TI->getOperand(0)); 113390cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner if (OpReg == 0) return false; 113490cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TestOpc)) 113590cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner .addReg(OpReg).addImm(1); 1136471e4224809f51652c71f319532697a879a75a0dEric Christopher 1137c76d12180765782d6abd0fdeb359c3fec7983e2cChris Lattner unsigned JmpOpc = X86::JNE_4; 1138c76d12180765782d6abd0fdeb359c3fec7983e2cChris Lattner if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) { 1139c76d12180765782d6abd0fdeb359c3fec7983e2cChris Lattner std::swap(TrueMBB, FalseMBB); 1140c76d12180765782d6abd0fdeb359c3fec7983e2cChris Lattner JmpOpc = X86::JE_4; 1141c76d12180765782d6abd0fdeb359c3fec7983e2cChris Lattner } 1142471e4224809f51652c71f319532697a879a75a0dEric Christopher 1143c76d12180765782d6abd0fdeb359c3fec7983e2cChris Lattner BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(JmpOpc)) 114490cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner .addMBB(TrueMBB); 114590cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner FastEmitBranch(FalseMBB, DL); 114690cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner FuncInfo.MBB->addSuccessor(TrueMBB); 114790cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner return true; 114890cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner } 114990cb88a9b43764ae945e137bcb83fe14ac97d6fdChris Lattner } 1150d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman } 1151d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman 1152d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman // Otherwise do a clumsy setcc and re-test it. 1153547eb4fd560cdd77e06c88eed1722bdb94c82b26Eli Friedman // Note that i1 essentially gets ANY_EXTEND'ed to i8 where it isn't used 1154547eb4fd560cdd77e06c88eed1722bdb94c82b26Eli Friedman // in an explicit cast, so make sure to handle that correctly. 1155d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman unsigned OpReg = getRegForValue(BI->getCondition()); 1156d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman if (OpReg == 0) return false; 1157d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman 1158547eb4fd560cdd77e06c88eed1722bdb94c82b26Eli Friedman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::TEST8ri)) 1159547eb4fd560cdd77e06c88eed1722bdb94c82b26Eli Friedman .addReg(OpReg).addImm(1); 116084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::JNE_4)) 116184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addMBB(TrueMBB); 11623bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings FastEmitBranch(FalseMBB, DL); 116384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman FuncInfo.MBB->addSuccessor(TrueMBB); 1164d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman return true; 1165d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman} 1166d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman 116746510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectShift(const Instruction *I) { 1168602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner unsigned CReg = 0, OpReg = 0; 1169c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman const TargetRegisterClass *RC = NULL; 1170b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (I->getType()->isIntegerTy(8)) { 1171c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman CReg = X86::CL; 1172c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR8RegClass; 1173c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman switch (I->getOpcode()) { 1174602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::LShr: OpReg = X86::SHR8rCL; break; 1175602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::AShr: OpReg = X86::SAR8rCL; break; 1176602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::Shl: OpReg = X86::SHL8rCL; break; 1177c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman default: return false; 1178c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } 1179b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands } else if (I->getType()->isIntegerTy(16)) { 1180c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman CReg = X86::CX; 1181c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR16RegClass; 1182c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman switch (I->getOpcode()) { 1183602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::LShr: OpReg = X86::SHR16rCL; break; 1184602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::AShr: OpReg = X86::SAR16rCL; break; 1185602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::Shl: OpReg = X86::SHL16rCL; break; 1186c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman default: return false; 1187c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } 1188b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands } else if (I->getType()->isIntegerTy(32)) { 1189c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman CReg = X86::ECX; 1190c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR32RegClass; 1191c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman switch (I->getOpcode()) { 1192602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::LShr: OpReg = X86::SHR32rCL; break; 1193602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::AShr: OpReg = X86::SAR32rCL; break; 1194602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::Shl: OpReg = X86::SHL32rCL; break; 1195c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman default: return false; 1196c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } 1197b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands } else if (I->getType()->isIntegerTy(64)) { 1198c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman CReg = X86::RCX; 1199c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR64RegClass; 1200c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman switch (I->getOpcode()) { 1201602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::LShr: OpReg = X86::SHR64rCL; break; 1202602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::AShr: OpReg = X86::SAR64rCL; break; 1203602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner case Instruction::Shl: OpReg = X86::SHL64rCL; break; 1204c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman default: return false; 1205c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } 1206c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } else { 1207c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman return false; 1208c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } 1209c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 12101440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 12111440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands if (!isTypeLegal(I->getType(), VT)) 1212f58cb6d224999631e54537dd04232ec9bb570b14Dan Gohman return false; 1213f58cb6d224999631e54537dd04232ec9bb570b14Dan Gohman 1214c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned Op0Reg = getRegForValue(I->getOperand(0)); 1215c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman if (Op0Reg == 0) return false; 1216bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1217c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned Op1Reg = getRegForValue(I->getOperand(1)); 1218c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman if (Op1Reg == 0) return false; 12195127f7991373d1c69e4d3241ec11913f4f44bb21Jakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 12205127f7991373d1c69e4d3241ec11913f4f44bb21Jakob Stoklund Olesen CReg).addReg(Op1Reg); 1221145b828014397f02ec0e35f3ba768b61a36b0b9fDan Gohman 1222145b828014397f02ec0e35f3ba768b61a36b0b9fDan Gohman // The shift instruction uses X86::CL. If we defined a super-register 12230bc25f40402f48ba42fc45403f635b20d90fabb3Jakob Stoklund Olesen // of X86::CL, emit a subreg KILL to precisely describe what we're doing here. 1224145b828014397f02ec0e35f3ba768b61a36b0b9fDan Gohman if (CReg != X86::CL) 122584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 122684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(TargetOpcode::KILL), X86::CL) 12270bc25f40402f48ba42fc45403f635b20d90fabb3Jakob Stoklund Olesen .addReg(CReg, RegState::Kill); 1228145b828014397f02ec0e35f3ba768b61a36b0b9fDan Gohman 1229c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned ResultReg = createResultReg(RC); 123084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(OpReg), ResultReg) 123184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Op0Reg); 1232c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman UpdateValueMap(I, ResultReg); 1233c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman return true; 1234c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman} 1235c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 123646510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectSelect(const Instruction *I) { 12371440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 12381440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands if (!isTypeLegal(I->getType(), VT)) 1239160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner return false; 1240bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1241e487b017e94393ec4e90e8bb02818cab39190787Eric Christopher // We only use cmov here, if we don't have a cmov instruction bail. 1242e487b017e94393ec4e90e8bb02818cab39190787Eric Christopher if (!Subtarget->hasCMov()) return false; 1243bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1244c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned Opc = 0; 1245c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman const TargetRegisterClass *RC = NULL; 12461440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands if (VT == MVT::i16) { 124731d26912cc2624d39ee4fa7accb4aca5cf1aacd6Dan Gohman Opc = X86::CMOVE16rr; 1248c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR16RegClass; 12491440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands } else if (VT == MVT::i32) { 125031d26912cc2624d39ee4fa7accb4aca5cf1aacd6Dan Gohman Opc = X86::CMOVE32rr; 1251c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR32RegClass; 12521440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands } else if (VT == MVT::i64) { 125331d26912cc2624d39ee4fa7accb4aca5cf1aacd6Dan Gohman Opc = X86::CMOVE64rr; 1254c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman RC = &X86::GR64RegClass; 1255c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } else { 1256bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return false; 1257c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman } 1258c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 1259c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned Op0Reg = getRegForValue(I->getOperand(0)); 1260c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman if (Op0Reg == 0) return false; 1261c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned Op1Reg = getRegForValue(I->getOperand(1)); 1262c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman if (Op1Reg == 0) return false; 1263c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned Op2Reg = getRegForValue(I->getOperand(2)); 1264c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman if (Op2Reg == 0) return false; 1265c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 126684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::TEST8rr)) 126784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Op0Reg).addReg(Op0Reg); 1268c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman unsigned ResultReg = createResultReg(RC); 126984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg) 127084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Op1Reg).addReg(Op2Reg); 1271c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman UpdateValueMap(I, ResultReg); 1272c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman return true; 1273c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman} 1274c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman 127546510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectFPExt(const Instruction *I) { 1276160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner // fpext from float to double. 1277645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes if (X86ScalarSSEf64 && 1278cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner I->getType()->isDoubleTy()) { 127946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Value *V = I->getOperand(0); 1280cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (V->getType()->isFloatTy()) { 1281160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner unsigned OpReg = getRegForValue(V); 1282160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner if (OpReg == 0) return false; 1283c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper unsigned ResultReg = createResultReg(&X86::FR64RegClass); 128484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 128584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(X86::CVTSS2SDrr), ResultReg) 128684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(OpReg); 1287160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner UpdateValueMap(I, ResultReg); 1288160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner return true; 128978efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman } 129078efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman } 129178efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman 129278efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman return false; 129378efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman} 129478efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman 129546510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectFPTrunc(const Instruction *I) { 1296645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes if (X86ScalarSSEf64) { 1297cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (I->getType()->isFloatTy()) { 129846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Value *V = I->getOperand(0); 1299cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (V->getType()->isDoubleTy()) { 130078efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman unsigned OpReg = getRegForValue(V); 130178efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman if (OpReg == 0) return false; 1302c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper unsigned ResultReg = createResultReg(&X86::FR32RegClass); 130384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 130484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(X86::CVTSD2SSrr), ResultReg) 130584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(OpReg); 130678efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman UpdateValueMap(I, ResultReg); 130778efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman return true; 130878efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman } 130978efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman } 131078efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman } 131178efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman 131278efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman return false; 131378efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman} 131478efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman 131546510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectTrunc(const Instruction *I) { 1316e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); 1317e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DstVT = TLI.getValueType(I->getType()); 1318bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 131976927d7303046058c627691bd45d6bff608f49f4Eli Friedman // This code only handles truncation to byte. 1320825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (DstVT != MVT::i8 && DstVT != MVT::i1) 132110a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng return false; 132276927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (!TLI.isTypeLegal(SrcVT)) 132310a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng return false; 132410a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng 132510a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng unsigned InputReg = getRegForValue(I->getOperand(0)); 132610a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng if (!InputReg) 132710a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng // Unhandled operand. Halt "fast" selection and bail. 132810a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng return false; 132910a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng 133076927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (SrcVT == MVT::i8) { 133176927d7303046058c627691bd45d6bff608f49f4Eli Friedman // Truncate from i8 to i1; no code needed. 133276927d7303046058c627691bd45d6bff608f49f4Eli Friedman UpdateValueMap(I, InputReg); 133376927d7303046058c627691bd45d6bff608f49f4Eli Friedman return true; 133476927d7303046058c627691bd45d6bff608f49f4Eli Friedman } 133576927d7303046058c627691bd45d6bff608f49f4Eli Friedman 133676927d7303046058c627691bd45d6bff608f49f4Eli Friedman if (!Subtarget->is64Bit()) { 133776927d7303046058c627691bd45d6bff608f49f4Eli Friedman // If we're on x86-32; we can't extract an i8 from a general register. 133876927d7303046058c627691bd45d6bff608f49f4Eli Friedman // First issue a copy to GR16_ABCD or GR32_ABCD. 1339c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper const TargetRegisterClass *CopyRC = (SrcVT == MVT::i16) ? 1340c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper (const TargetRegisterClass*)&X86::GR16_ABCDRegClass : 1341c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper (const TargetRegisterClass*)&X86::GR32_ABCDRegClass; 134276927d7303046058c627691bd45d6bff608f49f4Eli Friedman unsigned CopyReg = createResultReg(CopyRC); 134376927d7303046058c627691bd45d6bff608f49f4Eli Friedman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 134476927d7303046058c627691bd45d6bff608f49f4Eli Friedman CopyReg).addReg(InputReg); 134576927d7303046058c627691bd45d6bff608f49f4Eli Friedman InputReg = CopyReg; 134676927d7303046058c627691bd45d6bff608f49f4Eli Friedman } 134710a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng 134876927d7303046058c627691bd45d6bff608f49f4Eli Friedman // Issue an extract_subreg. 1349825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson unsigned ResultReg = FastEmitInst_extractsubreg(MVT::i8, 135076927d7303046058c627691bd45d6bff608f49f4Eli Friedman InputReg, /*Kill=*/true, 13513458e9e4dfc8689179a74e954aad78d3a4b564ffJakob Stoklund Olesen X86::sub_8bit); 135210a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng if (!ResultReg) 135310a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng return false; 135410a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng 135510a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng UpdateValueMap(I, ResultReg); 135610a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng return true; 135710a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng} 135810a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng 1359c088345f1377a36c35c037be63830d0e6892f904Eli Friedmanbool X86FastISel::IsMemcpySmall(uint64_t Len) { 1360c088345f1377a36c35c037be63830d0e6892f904Eli Friedman return Len <= (Subtarget->is64Bit() ? 32 : 16); 1361c088345f1377a36c35c037be63830d0e6892f904Eli Friedman} 1362c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 1363d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedmanbool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM, 1364d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman X86AddressMode SrcAM, uint64_t Len) { 1365c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 1366d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman // Make sure we don't bloat code by inlining very large memcpy's. 1367c088345f1377a36c35c037be63830d0e6892f904Eli Friedman if (!IsMemcpySmall(Len)) 1368c088345f1377a36c35c037be63830d0e6892f904Eli Friedman return false; 1369c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 1370c088345f1377a36c35c037be63830d0e6892f904Eli Friedman bool i64Legal = Subtarget->is64Bit(); 1371d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 1372d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman // We don't care about alignment here since we just emit integer accesses. 1373d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman while (Len) { 1374d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman MVT VT; 1375d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman if (Len >= 8 && i64Legal) 1376d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman VT = MVT::i64; 1377d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman else if (Len >= 4) 1378d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman VT = MVT::i32; 1379d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman else if (Len >= 2) 1380d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman VT = MVT::i16; 1381d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman else { 1382d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman VT = MVT::i8; 1383d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman } 1384d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 1385d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman unsigned Reg; 1386d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman bool RV = X86FastEmitLoad(VT, SrcAM, Reg); 1387d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman RV &= X86FastEmitStore(VT, Reg, DestAM); 1388d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman assert(RV && "Failed to emit load or store??"); 1389d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 1390d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman unsigned Size = VT.getSizeInBits()/8; 1391d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman Len -= Size; 1392d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman DestAM.Disp += Size; 1393d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman SrcAM.Disp += Size; 1394d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman } 1395d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 1396d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman return true; 1397d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman} 1398d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 139946510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86VisitIntrinsicCall(const IntrinsicInst &I) { 140052370a10891673c1065a354f2497c22b82a32b1bBill Wendling // FIXME: Handle more intrinsics. 1401a9a42259ed0cd418466bcaeff93eca933dae7efbChris Lattner switch (I.getIntrinsicID()) { 140252370a10891673c1065a354f2497c22b82a32b1bBill Wendling default: return false; 1403832e4943598d821687cec79f512803c1ca03cff7Chris Lattner case Intrinsic::memcpy: { 1404832e4943598d821687cec79f512803c1ca03cff7Chris Lattner const MemCpyInst &MCI = cast<MemCpyInst>(I); 1405832e4943598d821687cec79f512803c1ca03cff7Chris Lattner // Don't handle volatile or variable length memcpys. 140625255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (MCI.isVolatile()) 1407832e4943598d821687cec79f512803c1ca03cff7Chris Lattner return false; 1408d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 140925255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (isa<ConstantInt>(MCI.getLength())) { 141025255cbe0000abd64194e9e34098243cd689fd47Eli Friedman // Small memcpy's are common enough that we want to do them 141125255cbe0000abd64194e9e34098243cd689fd47Eli Friedman // without a call if possible. 141225255cbe0000abd64194e9e34098243cd689fd47Eli Friedman uint64_t Len = cast<ConstantInt>(MCI.getLength())->getZExtValue(); 141325255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (IsMemcpySmall(Len)) { 141425255cbe0000abd64194e9e34098243cd689fd47Eli Friedman X86AddressMode DestAM, SrcAM; 141525255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (!X86SelectAddress(MCI.getRawDest(), DestAM) || 141625255cbe0000abd64194e9e34098243cd689fd47Eli Friedman !X86SelectAddress(MCI.getRawSource(), SrcAM)) 141725255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return false; 141825255cbe0000abd64194e9e34098243cd689fd47Eli Friedman TryEmitSmallMemcpy(DestAM, SrcAM, Len); 141925255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return true; 142025255cbe0000abd64194e9e34098243cd689fd47Eli Friedman } 142125255cbe0000abd64194e9e34098243cd689fd47Eli Friedman } 142225255cbe0000abd64194e9e34098243cd689fd47Eli Friedman 142325255cbe0000abd64194e9e34098243cd689fd47Eli Friedman unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32; 142425255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (!MCI.getLength()->getType()->isIntegerTy(SizeWidth)) 142525255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return false; 1426471e4224809f51652c71f319532697a879a75a0dEric Christopher 142725255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (MCI.getSourceAddressSpace() > 255 || MCI.getDestAddressSpace() > 255) 1428832e4943598d821687cec79f512803c1ca03cff7Chris Lattner return false; 1429d5089a9794b46918128c2fec1b5ec1d20f7572faEli Friedman 143025255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return DoSelectCall(&I, "memcpy"); 1431832e4943598d821687cec79f512803c1ca03cff7Chris Lattner } 143225255cbe0000abd64194e9e34098243cd689fd47Eli Friedman case Intrinsic::memset: { 143325255cbe0000abd64194e9e34098243cd689fd47Eli Friedman const MemSetInst &MSI = cast<MemSetInst>(I); 143425255cbe0000abd64194e9e34098243cd689fd47Eli Friedman 14353207c9a44093156c3906b62cd9cb74726751b7b4Nick Lewycky if (MSI.isVolatile()) 14363207c9a44093156c3906b62cd9cb74726751b7b4Nick Lewycky return false; 14373207c9a44093156c3906b62cd9cb74726751b7b4Nick Lewycky 143825255cbe0000abd64194e9e34098243cd689fd47Eli Friedman unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32; 143925255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (!MSI.getLength()->getType()->isIntegerTy(SizeWidth)) 144025255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return false; 144125255cbe0000abd64194e9e34098243cd689fd47Eli Friedman 144225255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (MSI.getDestAddressSpace() > 255) 144325255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return false; 1444471e4224809f51652c71f319532697a879a75a0dEric Christopher 144525255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return DoSelectCall(&I, "memset"); 144625255cbe0000abd64194e9e34098243cd689fd47Eli Friedman } 144707754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher case Intrinsic::stackprotector: { 1448e1093e5503060b3031980dc14a141c3236108c50Chad Rosier // Emit code to store the stack guard onto the stack. 144907754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher EVT PtrTy = TLI.getPointerTy(); 145007754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher 14511cfe44a4609a36cbf1cc0e70091c30f4162a5b36Gabor Greif const Value *Op1 = I.getArgOperand(0); // The guard's value. 14521cfe44a4609a36cbf1cc0e70091c30f4162a5b36Gabor Greif const AllocaInst *Slot = cast<AllocaInst>(I.getArgOperand(1)); 145307754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher 145407754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher // Grab the frame index. 145507754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher X86AddressMode AM; 145607754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher if (!X86SelectAddress(Slot, AM)) return false; 145788dee30a6ed6979e253cc402e9b94082f60ad534Eric Christopher if (!X86FastEmitStore(PtrTy, Op1, AM)) return false; 145807754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher return true; 145907754c2a1b06b5d027cf4cdf532e25f4e8055058Eric Christopher } 14605ed17ae92a9239c2ff7d3ba494bf96651598ee7aDale Johannesen case Intrinsic::dbg_declare: { 146146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const DbgDeclareInst *DI = cast<DbgDeclareInst>(&I); 14625ed17ae92a9239c2ff7d3ba494bf96651598ee7aDale Johannesen X86AddressMode AM; 1463973f46790fada0c949a887e0fcef3aeeb3a13430Dale Johannesen assert(DI->getAddress() && "Null address should be checked earlier!"); 14645ed17ae92a9239c2ff7d3ba494bf96651598ee7aDale Johannesen if (!X86SelectAddress(DI->getAddress(), AM)) 14655ed17ae92a9239c2ff7d3ba494bf96651598ee7aDale Johannesen return false; 1466e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE); 1467116b799488327cb95f24ca321f9ab838d5d5e73dDale Johannesen // FIXME may need to add RegState::Debug to any registers produced, 1468116b799488327cb95f24ca321f9ab838d5d5e73dDale Johannesen // although ESP/EBP should be the only ones at the moment. 146984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II), AM). 147084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addImm(0).addMetadata(DI->getVariable()); 14715ed17ae92a9239c2ff7d3ba494bf96651598ee7aDale Johannesen return true; 14725ed17ae92a9239c2ff7d3ba494bf96651598ee7aDale Johannesen } 147377f79895f8e8ba88f0a9a98610c4461c1d692296Eric Christopher case Intrinsic::trap: { 147484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::TRAP)); 147577f79895f8e8ba88f0a9a98610c4461c1d692296Eric Christopher return true; 147677f79895f8e8ba88f0a9a98610c4461c1d692296Eric Christopher } 147752370a10891673c1065a354f2497c22b82a32b1bBill Wendling case Intrinsic::sadd_with_overflow: 147852370a10891673c1065a354f2497c22b82a32b1bBill Wendling case Intrinsic::uadd_with_overflow: { 1479832e4943598d821687cec79f512803c1ca03cff7Chris Lattner // FIXME: Should fold immediates. 1480471e4224809f51652c71f319532697a879a75a0dEric Christopher 1481c065b3f5ec5c165f57e26e8a26edbbd250682ea2Bill Wendling // Replace "add with overflow" intrinsics with an "add" instruction followed 1482482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman // by a seto/setc instruction. 148352370a10891673c1065a354f2497c22b82a32b1bBill Wendling const Function *Callee = I.getCalledFunction(); 1484db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = 148552370a10891673c1065a354f2497c22b82a32b1bBill Wendling cast<StructType>(Callee->getReturnType())->getTypeAtIndex(unsigned(0)); 148652370a10891673c1065a354f2497c22b82a32b1bBill Wendling 14871440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 148852370a10891673c1065a354f2497c22b82a32b1bBill Wendling if (!isTypeLegal(RetTy, VT)) 148952370a10891673c1065a354f2497c22b82a32b1bBill Wendling return false; 149052370a10891673c1065a354f2497c22b82a32b1bBill Wendling 14911cfe44a4609a36cbf1cc0e70091c30f4162a5b36Gabor Greif const Value *Op1 = I.getArgOperand(0); 14921cfe44a4609a36cbf1cc0e70091c30f4162a5b36Gabor Greif const Value *Op2 = I.getArgOperand(1); 149352370a10891673c1065a354f2497c22b82a32b1bBill Wendling unsigned Reg1 = getRegForValue(Op1); 149452370a10891673c1065a354f2497c22b82a32b1bBill Wendling unsigned Reg2 = getRegForValue(Op2); 149552370a10891673c1065a354f2497c22b82a32b1bBill Wendling 149652370a10891673c1065a354f2497c22b82a32b1bBill Wendling if (Reg1 == 0 || Reg2 == 0) 149752370a10891673c1065a354f2497c22b82a32b1bBill Wendling // FIXME: Handle values *not* in registers. 149852370a10891673c1065a354f2497c22b82a32b1bBill Wendling return false; 149952370a10891673c1065a354f2497c22b82a32b1bBill Wendling 150052370a10891673c1065a354f2497c22b82a32b1bBill Wendling unsigned OpC = 0; 1501825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::i32) 150252370a10891673c1065a354f2497c22b82a32b1bBill Wendling OpC = X86::ADD32rr; 1503825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson else if (VT == MVT::i64) 150452370a10891673c1065a354f2497c22b82a32b1bBill Wendling OpC = X86::ADD64rr; 150552370a10891673c1065a354f2497c22b82a32b1bBill Wendling else 150652370a10891673c1065a354f2497c22b82a32b1bBill Wendling return false; 150752370a10891673c1065a354f2497c22b82a32b1bBill Wendling 1508482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman // The call to CreateRegs builds two sequential registers, to store the 1509c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru // both the returned values. 1510482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman unsigned ResultReg = FuncInfo.CreateRegs(I.getType()); 151184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(OpC), ResultReg) 151284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(Reg1).addReg(Reg2); 1513bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1514a9a42259ed0cd418466bcaeff93eca933dae7efbChris Lattner unsigned Opc = X86::SETBr; 1515a9a42259ed0cd418466bcaeff93eca933dae7efbChris Lattner if (I.getIntrinsicID() == Intrinsic::sadd_with_overflow) 1516a9a42259ed0cd418466bcaeff93eca933dae7efbChris Lattner Opc = X86::SETOr; 1517482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg+1); 1518482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman 1519482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman UpdateValueMap(&I, ResultReg, 2); 152052370a10891673c1065a354f2497c22b82a32b1bBill Wendling return true; 152152370a10891673c1065a354f2497c22b82a32b1bBill Wendling } 152252370a10891673c1065a354f2497c22b82a32b1bBill Wendling } 152352370a10891673c1065a354f2497c22b82a32b1bBill Wendling} 152452370a10891673c1065a354f2497c22b82a32b1bBill Wendling 1525fd3417d288c22673ec6d76dc4695989bb544373fChad Rosierbool X86FastISel::FastLowerArguments() { 1526fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (!FuncInfo.CanLowerReturn) 1527fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1528fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1529d9b306a4771106cf1005f8398d944a623bf1a9e9Chad Rosier if (Subtarget->isTargetWindows()) 1530d9b306a4771106cf1005f8398d944a623bf1a9e9Chad Rosier return false; 1531d9b306a4771106cf1005f8398d944a623bf1a9e9Chad Rosier 1532fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier const Function *F = FuncInfo.Fn; 1533fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (F->isVarArg()) 1534fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1535fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1536fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier CallingConv::ID CC = F->getCallingConv(); 1537fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (CC != CallingConv::C) 1538fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1539fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1540fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (!Subtarget->is64Bit()) 1541fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1542fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1543fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier // Only handle simple cases. i.e. Up to 6 i32/i64 scalar arguments. 1544fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier unsigned Idx = 1; 1545fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 1546fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier I != E; ++I, ++Idx) { 1547fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (Idx > 6) 1548fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1549fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1550fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (F->getAttributes().hasAttribute(Idx, Attribute::ByVal) || 1551fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier F->getAttributes().hasAttribute(Idx, Attribute::InReg) || 1552fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier F->getAttributes().hasAttribute(Idx, Attribute::StructRet) || 1553fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier F->getAttributes().hasAttribute(Idx, Attribute::Nest)) 1554fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1555fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1556fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier Type *ArgTy = I->getType(); 1557fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) 1558fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1559fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1560fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier EVT ArgVT = TLI.getValueType(ArgTy); 1561fe88aa0d148510e41bc3080dea4febcb1445855cChad Rosier if (!ArgVT.isSimple()) return false; 1562fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier switch (ArgVT.getSimpleVT().SimpleTy) { 1563fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier case MVT::i32: 1564fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier case MVT::i64: 1565fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier break; 1566fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier default: 1567fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return false; 1568fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier } 1569fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier } 1570fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1571fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier static const uint16_t GPR32ArgRegs[] = { 1572fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D 1573fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier }; 1574fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier static const uint16_t GPR64ArgRegs[] = { 1575fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9 1576fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier }; 1577fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 1578fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier Idx = 0; 1579fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier const TargetRegisterClass *RC32 = TLI.getRegClassFor(MVT::i32); 1580fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier const TargetRegisterClass *RC64 = TLI.getRegClassFor(MVT::i64); 1581fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 1582fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier I != E; ++I, ++Idx) { 1583fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier if (I->use_empty()) 1584fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier continue; 1585fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier bool is32Bit = TLI.getValueType(I->getType()) == MVT::i32; 1586fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier const TargetRegisterClass *RC = is32Bit ? RC32 : RC64; 1587fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier unsigned SrcReg = is32Bit ? GPR32ArgRegs[Idx] : GPR64ArgRegs[Idx]; 1588fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC); 1589fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier // FIXME: Unfortunately it's necessary to emit a copy from the livein copy. 1590fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier // Without this, EmitLiveInCopies may eliminate the livein if its only 1591fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier // use is a bitcast (which isn't turned into an instruction). 1592fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier unsigned ResultReg = createResultReg(RC); 1593fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 1594fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier ResultReg).addReg(DstReg, getKillRegState(true)); 1595fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier UpdateValueMap(I, ResultReg); 1596fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier } 1597fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier return true; 1598fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier} 1599fd3417d288c22673ec6d76dc4695989bb544373fChad Rosier 160046510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanbool X86FastISel::X86SelectCall(const Instruction *I) { 160146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const CallInst *CI = cast<CallInst>(I); 16021cfe44a4609a36cbf1cc0e70091c30f4162a5b36Gabor Greif const Value *Callee = CI->getCalledValue(); 1603f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1604f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Can't handle inline asm yet. 1605f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng if (isa<InlineAsm>(Callee)) 1606f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return false; 1607f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 160852370a10891673c1065a354f2497c22b82a32b1bBill Wendling // Handle intrinsic calls. 160946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) 1610a9a42259ed0cd418466bcaeff93eca933dae7efbChris Lattner return X86VisitIntrinsicCall(*II); 1611f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1612425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier // Allow SelectionDAG isel to handle tail calls. 1613425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier if (cast<CallInst>(I)->isTailCall()) 1614425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier return false; 1615425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier 161625255cbe0000abd64194e9e34098243cd689fd47Eli Friedman return DoSelectCall(I, 0); 161725255cbe0000abd64194e9e34098243cd689fd47Eli Friedman} 161825255cbe0000abd64194e9e34098243cd689fd47Eli Friedman 1619c338fe082860989d89b51520042a5f447339eb8cRafael Espindolastatic unsigned computeBytesPoppedByCallee(const X86Subtarget &Subtarget, 1620c338fe082860989d89b51520042a5f447339eb8cRafael Espindola const ImmutableCallSite &CS) { 1621742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola if (Subtarget.is64Bit()) 1622742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola return 0; 1623742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola if (Subtarget.isTargetWindows()) 1624742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola return 0; 1625742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola CallingConv::ID CC = CS.getCallingConv(); 1626742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola if (CC == CallingConv::Fast || CC == CallingConv::GHC) 1627742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola return 0; 1628034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (!CS.paramHasAttr(1, Attribute::StructRet)) 1629742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola return 0; 1630034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(1, Attribute::InReg)) 16311cee71099c0477c6bf0e8ff76a55b8873ce146b4Rafael Espindola return 0; 1632742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola return 4; 1633742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola} 1634742f2c9a43af3bae65922d2679de8835a6d4f302Rafael Espindola 163525255cbe0000abd64194e9e34098243cd689fd47Eli Friedman// Select either a call, or an llvm.memcpy/memmove/memset intrinsic 163625255cbe0000abd64194e9e34098243cd689fd47Eli Friedmanbool X86FastISel::DoSelectCall(const Instruction *I, const char *MemIntName) { 163725255cbe0000abd64194e9e34098243cd689fd47Eli Friedman const CallInst *CI = cast<CallInst>(I); 163825255cbe0000abd64194e9e34098243cd689fd47Eli Friedman const Value *Callee = CI->getCalledValue(); 163925255cbe0000abd64194e9e34098243cd689fd47Eli Friedman 1640f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Handle only C and fastcc calling conventions for now. 164146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman ImmutableCallSite CS(CI); 164265c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CC = CS.getCallingConv(); 1643e03b8d31624b415805940500a40195a540ca94beChris Lattner if (CC != CallingConv::C && CC != CallingConv::Fast && 1644f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng CC != CallingConv::X86_FastCall) 1645f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return false; 1646f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1647381993f1f2f947fcdaec814181a735091b22fcbaEvan Cheng // fastcc with -tailcallopt is intended to provide a guaranteed 1648381993f1f2f947fcdaec814181a735091b22fcbaEvan Cheng // tail call optimization. Fastisel doesn't know how to do that. 16498a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) 1650381993f1f2f947fcdaec814181a735091b22fcbaEvan Cheng return false; 1651381993f1f2f947fcdaec814181a735091b22fcbaEvan Cheng 1652db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType()); 1653db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = cast<FunctionType>(PT->getElementType()); 16543762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman bool isVarArg = FTy->isVarArg(); 16553762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman 16563762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman // Don't know how to handle Win64 varargs yet. Nothing special needed for 16573762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman // x86-32. Special handling for x86-64 is implemented. 16583762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman if (isVarArg && Subtarget->isTargetWin64()) 1659f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return false; 1660f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 16614d3d6e1a0c99e2212953a90185a8d027c595bf5aDan Gohman // Fast-isel doesn't know about callee-pop yet. 1662ef41ff618f2537539b538e6c7bf471c753391f92Evan Cheng if (X86::isCalleePop(CC, Subtarget->is64Bit(), isVarArg, 16638a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky TM.Options.GuaranteedTailCallOpt)) 16644d3d6e1a0c99e2212953a90185a8d027c595bf5aDan Gohman return false; 16654d3d6e1a0c99e2212953a90185a8d027c595bf5aDan Gohman 166619515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman // Check whether the function can return without sret-demotion. 166719515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman SmallVector<ISD::OutputArg, 4> Outs; 16688b62abdd7b9c8fc5d78dad86093f4afdfeba949dBill Wendling GetReturnInfo(I->getType(), CS.getAttributes(), Outs, TLI); 166919515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), 167056cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling *FuncInfo.MF, FTy->isVarArg(), 167156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Outs, FTy->getContext()); 167219515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman if (!CanLowerReturn) 1673c93943b6fef4d84a9934cf23f8b14d3a8952f26fEli Friedman return false; 1674c93943b6fef4d84a9934cf23f8b14d3a8952f26fEli Friedman 1675b5b6ec64889b6ee1f75c9a21efb99570e58a517fDan Gohman // Materialize callee address in a register. FIXME: GV address can be 1676b5b6ec64889b6ee1f75c9a21efb99570e58a517fDan Gohman // handled with a CALLpcrel32 instead. 16772ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman X86AddressMode CalleeAM; 16780aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (!X86SelectCallAddress(Callee, CalleeAM)) 16792ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman return false; 1680b5b6ec64889b6ee1f75c9a21efb99570e58a517fDan Gohman unsigned CalleeOp = 0; 168146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = 0; 1682553e571b436ae27cc8b322be6feecd357651b617Chris Lattner if (CalleeAM.GV != 0) { 16832ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman GV = CalleeAM.GV; 1684553e571b436ae27cc8b322be6feecd357651b617Chris Lattner } else if (CalleeAM.Base.Reg != 0) { 1685553e571b436ae27cc8b322be6feecd357651b617Chris Lattner CalleeOp = CalleeAM.Base.Reg; 16862ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman } else 16872ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman return false; 1688b5b6ec64889b6ee1f75c9a21efb99570e58a517fDan Gohman 1689f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Deal with call operands first. 169046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman SmallVector<const Value *, 8> ArgVals; 1691241ab47ac13e243e16b6725a04ba73b9b19a478eChris Lattner SmallVector<unsigned, 8> Args; 16921440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands SmallVector<MVT, 8> ArgVTs; 1693241ab47ac13e243e16b6725a04ba73b9b19a478eChris Lattner SmallVector<ISD::ArgFlagsTy, 8> ArgFlags; 169415b4497333430fbc3e20e5fb7718d4e0d838168bChad Rosier unsigned arg_size = CS.arg_size(); 169515b4497333430fbc3e20e5fb7718d4e0d838168bChad Rosier Args.reserve(arg_size); 169615b4497333430fbc3e20e5fb7718d4e0d838168bChad Rosier ArgVals.reserve(arg_size); 169715b4497333430fbc3e20e5fb7718d4e0d838168bChad Rosier ArgVTs.reserve(arg_size); 169815b4497333430fbc3e20e5fb7718d4e0d838168bChad Rosier ArgFlags.reserve(arg_size); 169946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); 1700f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng i != e; ++i) { 170125255cbe0000abd64194e9e34098243cd689fd47Eli Friedman // If we're lowering a mem intrinsic instead of a regular call, skip the 170225255cbe0000abd64194e9e34098243cd689fd47Eli Friedman // last two arguments, which should not passed to the underlying functions. 170325255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (MemIntName && e-i <= 2) 170425255cbe0000abd64194e9e34098243cd689fd47Eli Friedman break; 1705e03b8d31624b415805940500a40195a540ca94beChris Lattner Value *ArgVal = *i; 1706f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng ISD::ArgFlagsTy Flags; 1707f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng unsigned AttrInd = i - CS.arg_begin() + 1; 1708034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(AttrInd, Attribute::SExt)) 1709f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng Flags.setSExt(); 1710034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(AttrInd, Attribute::ZExt)) 1711f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng Flags.setZExt(); 1712f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1713034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(AttrInd, Attribute::ByVal)) { 1714db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner PointerType *Ty = cast<PointerType>(ArgVal->getType()); 1715db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ElementTy = Ty->getElementType(); 1716c088345f1377a36c35c037be63830d0e6892f904Eli Friedman unsigned FrameSize = TD.getTypeAllocSize(ElementTy); 1717c088345f1377a36c35c037be63830d0e6892f904Eli Friedman unsigned FrameAlign = CS.getParamAlignment(AttrInd); 1718c088345f1377a36c35c037be63830d0e6892f904Eli Friedman if (!FrameAlign) 1719c088345f1377a36c35c037be63830d0e6892f904Eli Friedman FrameAlign = TLI.getByValTypeAlignment(ElementTy); 1720c088345f1377a36c35c037be63830d0e6892f904Eli Friedman Flags.setByVal(); 1721c088345f1377a36c35c037be63830d0e6892f904Eli Friedman Flags.setByValSize(FrameSize); 1722c088345f1377a36c35c037be63830d0e6892f904Eli Friedman Flags.setByValAlign(FrameAlign); 1723c088345f1377a36c35c037be63830d0e6892f904Eli Friedman if (!IsMemcpySmall(FrameSize)) 1724c088345f1377a36c35c037be63830d0e6892f904Eli Friedman return false; 1725c088345f1377a36c35c037be63830d0e6892f904Eli Friedman } 1726c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 1727034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(AttrInd, Attribute::InReg)) 1728c088345f1377a36c35c037be63830d0e6892f904Eli Friedman Flags.setInReg(); 1729034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(AttrInd, Attribute::Nest)) 1730c088345f1377a36c35c037be63830d0e6892f904Eli Friedman Flags.setNest(); 1731c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 1732e03b8d31624b415805940500a40195a540ca94beChris Lattner // If this is an i1/i8/i16 argument, promote to i32 to avoid an extra 1733e03b8d31624b415805940500a40195a540ca94beChris Lattner // instruction. This is safe because it is common to all fastisel supported 1734e03b8d31624b415805940500a40195a540ca94beChris Lattner // calling conventions on x86. 1735e03b8d31624b415805940500a40195a540ca94beChris Lattner if (ConstantInt *CI = dyn_cast<ConstantInt>(ArgVal)) { 1736e03b8d31624b415805940500a40195a540ca94beChris Lattner if (CI->getBitWidth() == 1 || CI->getBitWidth() == 8 || 1737e03b8d31624b415805940500a40195a540ca94beChris Lattner CI->getBitWidth() == 16) { 1738e03b8d31624b415805940500a40195a540ca94beChris Lattner if (Flags.isSExt()) 1739e03b8d31624b415805940500a40195a540ca94beChris Lattner ArgVal = ConstantExpr::getSExt(CI,Type::getInt32Ty(CI->getContext())); 1740e03b8d31624b415805940500a40195a540ca94beChris Lattner else 1741e03b8d31624b415805940500a40195a540ca94beChris Lattner ArgVal = ConstantExpr::getZExt(CI,Type::getInt32Ty(CI->getContext())); 1742e03b8d31624b415805940500a40195a540ca94beChris Lattner } 1743e03b8d31624b415805940500a40195a540ca94beChris Lattner } 1744471e4224809f51652c71f319532697a879a75a0dEric Christopher 1745b44101c1401c23fb86fe649309f52e823206147dChris Lattner unsigned ArgReg; 1746471e4224809f51652c71f319532697a879a75a0dEric Christopher 1747ff009ad1e1152ac6941ea4a85910f125868bd3deChris Lattner // Passing bools around ends up doing a trunc to i1 and passing it. 1748ff009ad1e1152ac6941ea4a85910f125868bd3deChris Lattner // Codegen this as an argument + "and 1". 1749b44101c1401c23fb86fe649309f52e823206147dChris Lattner if (ArgVal->getType()->isIntegerTy(1) && isa<TruncInst>(ArgVal) && 1750b44101c1401c23fb86fe649309f52e823206147dChris Lattner cast<TruncInst>(ArgVal)->getParent() == I->getParent() && 1751b44101c1401c23fb86fe649309f52e823206147dChris Lattner ArgVal->hasOneUse()) { 1752b44101c1401c23fb86fe649309f52e823206147dChris Lattner ArgVal = cast<TruncInst>(ArgVal)->getOperand(0); 1753b44101c1401c23fb86fe649309f52e823206147dChris Lattner ArgReg = getRegForValue(ArgVal); 1754b44101c1401c23fb86fe649309f52e823206147dChris Lattner if (ArgReg == 0) return false; 1755471e4224809f51652c71f319532697a879a75a0dEric Christopher 1756b44101c1401c23fb86fe649309f52e823206147dChris Lattner MVT ArgVT; 1757b44101c1401c23fb86fe649309f52e823206147dChris Lattner if (!isTypeLegal(ArgVal->getType(), ArgVT)) return false; 1758471e4224809f51652c71f319532697a879a75a0dEric Christopher 1759b44101c1401c23fb86fe649309f52e823206147dChris Lattner ArgReg = FastEmit_ri(ArgVT, ArgVT, ISD::AND, ArgReg, 1760b44101c1401c23fb86fe649309f52e823206147dChris Lattner ArgVal->hasOneUse(), 1); 1761b44101c1401c23fb86fe649309f52e823206147dChris Lattner } else { 1762b44101c1401c23fb86fe649309f52e823206147dChris Lattner ArgReg = getRegForValue(ArgVal); 1763b44101c1401c23fb86fe649309f52e823206147dChris Lattner } 1764e03b8d31624b415805940500a40195a540ca94beChris Lattner 1765ff009ad1e1152ac6941ea4a85910f125868bd3deChris Lattner if (ArgReg == 0) return false; 1766ff009ad1e1152ac6941ea4a85910f125868bd3deChris Lattner 1767db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ArgTy = ArgVal->getType(); 17681440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT ArgVT; 1769160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner if (!isTypeLegal(ArgTy, ArgVT)) 1770f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return false; 1771c088345f1377a36c35c037be63830d0e6892f904Eli Friedman if (ArgVT == MVT::x86mmx) 1772c088345f1377a36c35c037be63830d0e6892f904Eli Friedman return false; 1773f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy); 1774f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng Flags.setOrigAlign(OriginalAlignment); 1775f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1776b44101c1401c23fb86fe649309f52e823206147dChris Lattner Args.push_back(ArgReg); 1777e03b8d31624b415805940500a40195a540ca94beChris Lattner ArgVals.push_back(ArgVal); 1778f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng ArgVTs.push_back(ArgVT); 1779f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng ArgFlags.push_back(Flags); 1780f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } 1781f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1782f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Analyze operands of the call, assigning locations to each operand. 1783f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng SmallVector<CCValAssign, 16> ArgLocs; 1784471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, ArgLocs, 178556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling I->getParent()->getContext()); 1786bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1787d8acddda587cda98d46edb6d5fc71edd79a41654Dan Gohman // Allocate shadow area for Win64 1788e03b8d31624b415805940500a40195a540ca94beChris Lattner if (Subtarget->isTargetWin64()) 1789bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck CCInfo.AllocateStack(32, 8); 1790d8acddda587cda98d46edb6d5fc71edd79a41654Dan Gohman 17914590766580ff94e3a7fa95cda7b602b23f14843eDuncan Sands CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CC_X86); 1792f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1793f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Get a count of how many bytes are to be pushed on the stack. 1794f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng unsigned NumBytes = CCInfo.getNextStackOffset(); 1795f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1796f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Issue CALLSEQ_START 1797d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng unsigned AdjStackDown = TII.getCallFrameSetupOpcode(); 179884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackDown)) 179984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addImm(NumBytes); 1800f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 1801438949aa9d95877a7815ae1a0139c63f0f6d533dChris Lattner // Process argument: walk the register/memloc assignments, inserting 1802f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // copies / loads. 1803f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng SmallVector<unsigned, 4> RegArgs; 1804f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1805f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng CCValAssign &VA = ArgLocs[i]; 1806f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng unsigned Arg = Args[VA.getValNo()]; 1807e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ArgVT = ArgVTs[VA.getValNo()]; 1808bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1809f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Promote the value if needed. 1810f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng switch (VA.getLocInfo()) { 1811f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng case CCValAssign::Full: break; 181224e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng case CCValAssign::SExt: { 1813c088345f1377a36c35c037be63830d0e6892f904Eli Friedman assert(VA.getLocVT().isInteger() && !VA.getLocVT().isVector() && 1814c088345f1377a36c35c037be63830d0e6892f904Eli Friedman "Unexpected extend"); 181524e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng bool Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), 181624e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng Arg, ArgVT, Arg); 1817c46ec649b109ee7c44b0c8b9df6e913bdb129fc1Chris Lattner assert(Emitted && "Failed to emit a sext!"); (void)Emitted; 181824e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng ArgVT = VA.getLocVT(); 1819f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng break; 182024e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng } 182124e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng case CCValAssign::ZExt: { 1822c088345f1377a36c35c037be63830d0e6892f904Eli Friedman assert(VA.getLocVT().isInteger() && !VA.getLocVT().isVector() && 1823c088345f1377a36c35c037be63830d0e6892f904Eli Friedman "Unexpected extend"); 182424e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng bool Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), 182524e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng Arg, ArgVT, Arg); 1826c46ec649b109ee7c44b0c8b9df6e913bdb129fc1Chris Lattner assert(Emitted && "Failed to emit a zext!"); (void)Emitted; 182724e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng ArgVT = VA.getLocVT(); 1828f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng break; 182924e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng } 183024e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng case CCValAssign::AExt: { 1831c088345f1377a36c35c037be63830d0e6892f904Eli Friedman assert(VA.getLocVT().isInteger() && !VA.getLocVT().isVector() && 1832c088345f1377a36c35c037be63830d0e6892f904Eli Friedman "Unexpected extend"); 183324e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng bool Emitted = X86FastEmitExtend(ISD::ANY_EXTEND, VA.getLocVT(), 183424e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng Arg, ArgVT, Arg); 1835b63691350d3e08d4bf6d400b79e3174b5bd1d61dOwen Anderson if (!Emitted) 1836b63691350d3e08d4bf6d400b79e3174b5bd1d61dOwen Anderson Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), 1837160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner Arg, ArgVT, Arg); 1838b63691350d3e08d4bf6d400b79e3174b5bd1d61dOwen Anderson if (!Emitted) 1839b63691350d3e08d4bf6d400b79e3174b5bd1d61dOwen Anderson Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), 1840b63691350d3e08d4bf6d400b79e3174b5bd1d61dOwen Anderson Arg, ArgVT, Arg); 1841bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1842c46ec649b109ee7c44b0c8b9df6e913bdb129fc1Chris Lattner assert(Emitted && "Failed to emit a aext!"); (void)Emitted; 184324e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng ArgVT = VA.getLocVT(); 1844f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng break; 1845f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } 1846c3c9c486e48fd8fe4ab9929b1aa614dd6e613d2cDan Gohman case CCValAssign::BCvt: { 18471440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands unsigned BC = FastEmit_r(ArgVT.getSimpleVT(), VA.getLocVT(), 1848bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck ISD::BITCAST, Arg, /*TODO: Kill=*/false); 1849c3c9c486e48fd8fe4ab9929b1aa614dd6e613d2cDan Gohman assert(BC != 0 && "Failed to emit a bitcast!"); 1850c3c9c486e48fd8fe4ab9929b1aa614dd6e613d2cDan Gohman Arg = BC; 1851c3c9c486e48fd8fe4ab9929b1aa614dd6e613d2cDan Gohman ArgVT = VA.getLocVT(); 1852c3c9c486e48fd8fe4ab9929b1aa614dd6e613d2cDan Gohman break; 1853c3c9c486e48fd8fe4ab9929b1aa614dd6e613d2cDan Gohman } 185436ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier case CCValAssign::VExt: 185536ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier // VExt has not been implemented, so this should be impossible to reach 185636ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier // for now. However, fallback to Selection DAG isel once implemented. 185736ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier return false; 185836ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier case CCValAssign::Indirect: 185936ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier // FIXME: Indirect doesn't need extending, but fast-isel doesn't fully 186036ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier // support this. 186136ec0caa0ba0378d0858e7baf5bd49a6161ccedcChad Rosier return false; 186224e3a90904601fc6caf9d1b8c1be965806d529aeEvan Cheng } 1863bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1864f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng if (VA.isRegLoc()) { 18655127f7991373d1c69e4d3241ec11913f4f44bb21Jakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 18665127f7991373d1c69e4d3241ec11913f4f44bb21Jakob Stoklund Olesen VA.getLocReg()).addReg(Arg); 1867f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng RegArgs.push_back(VA.getLocReg()); 1868f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } else { 1869f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng unsigned LocMemOffset = VA.getLocMemOffset(); 18700586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman X86AddressMode AM; 1871f0e06e8d4445a45b18d18efcdb7c6fef22e90047Michael Liao AM.Base.Reg = RegInfo->getStackRegister(); 18720586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman AM.Disp = LocMemOffset; 187346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Value *ArgVal = ArgVals[VA.getValNo()]; 1874c088345f1377a36c35c037be63830d0e6892f904Eli Friedman ISD::ArgFlagsTy Flags = ArgFlags[VA.getValNo()]; 1875c088345f1377a36c35c037be63830d0e6892f904Eli Friedman 1876c088345f1377a36c35c037be63830d0e6892f904Eli Friedman if (Flags.isByVal()) { 1877c088345f1377a36c35c037be63830d0e6892f904Eli Friedman X86AddressMode SrcAM; 1878c088345f1377a36c35c037be63830d0e6892f904Eli Friedman SrcAM.Base.Reg = Arg; 1879c088345f1377a36c35c037be63830d0e6892f904Eli Friedman bool Res = TryEmitSmallMemcpy(AM, SrcAM, Flags.getByValSize()); 1880c088345f1377a36c35c037be63830d0e6892f904Eli Friedman assert(Res && "memcpy length already checked!"); (void)Res; 1881c088345f1377a36c35c037be63830d0e6892f904Eli Friedman } else if (isa<ConstantInt>(ArgVal) || isa<ConstantPointerNull>(ArgVal)) { 1882c088345f1377a36c35c037be63830d0e6892f904Eli Friedman // If this is a really simple value, emit this with the Value* version 18831f9c6860bfa3b2f23c1d385fc37e4ebc93bc4645Nick Lewycky // of X86FastEmitStore. If it isn't simple, we don't want to do this, 1884c088345f1377a36c35c037be63830d0e6892f904Eli Friedman // as it can cause us to reevaluate the argument. 1885e4824714026a528fe4cb08ad73e048066980eda6Lang Hames if (!X86FastEmitStore(ArgVT, ArgVal, AM)) 1886e4824714026a528fe4cb08ad73e048066980eda6Lang Hames return false; 1887c088345f1377a36c35c037be63830d0e6892f904Eli Friedman } else { 1888e4824714026a528fe4cb08ad73e048066980eda6Lang Hames if (!X86FastEmitStore(ArgVT, Arg, AM)) 1889e4824714026a528fe4cb08ad73e048066980eda6Lang Hames return false; 1890c088345f1377a36c35c037be63830d0e6892f904Eli Friedman } 1891f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } 1892f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } 1893f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 18942cc3aa44591313307e2d596daca784419ab7286dDan Gohman // ELF / PIC requires GOT in the EBX register before function calls via PLT 1895bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // GOT pointer. 189615a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner if (Subtarget->isPICStyleGOT()) { 1897a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman unsigned Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF); 18985127f7991373d1c69e4d3241ec11913f4f44bb21Jakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 18995127f7991373d1c69e4d3241ec11913f4f44bb21Jakob Stoklund Olesen X86::EBX).addReg(Base); 19002cc3aa44591313307e2d596daca784419ab7286dDan Gohman } 1901bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 19023762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64()) { 19033762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman // Count the number of XMM registers allocated. 1904c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t XMMArgRegs[] = { 19053762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3, 19063762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7 19073762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman }; 19083762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8); 19093762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::MOV8ri), 19103762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman X86::AL).addImm(NumXMMRegs); 19113762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman } 19123762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman 1913f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Issue the call. 191451e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner MachineInstrBuilder MIB; 191551e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner if (CalleeOp) { 191651e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // Register-indirect call. 19170c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman unsigned CallOpc; 1918527a08b253795cf09de41c289c9dc071f00b1d4aJakob Stoklund Olesen if (Subtarget->is64Bit()) 19190c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman CallOpc = X86::CALL64r; 19200c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman else 19210c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman CallOpc = X86::CALL32r; 192284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)) 192384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman .addReg(CalleeOp); 1924bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 192551e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner } else { 192651e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // Direct call. 192751e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner assert(GV && "Not a direct call"); 19280c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman unsigned CallOpc; 1929527a08b253795cf09de41c289c9dc071f00b1d4aJakob Stoklund Olesen if (Subtarget->is64Bit()) 19300c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman CallOpc = X86::CALL64pcrel32; 19310c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman else 19320c07b64fec208aab7032633f3c8e8ba43c85e64eNate Begeman CallOpc = X86::CALLpcrel32; 1933bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 193451e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // See if we need any target-specific flags on the GV operand. 193551e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner unsigned char OpFlags = 0; 1936bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 193751e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // On ELF targets, in both X86-64 and X86-32 mode, direct calls to 193851e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // external symbols most go through the PLT in PIC mode. If the symbol 193951e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // has hidden or protected visibility, or if it is static or local, then 194051e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // we don't need to use the PLT - we can directly call it. 194151e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner if (Subtarget->isTargetELF() && 194251e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner TM.getRelocationModel() == Reloc::PIC_ && 194351e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) { 194451e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner OpFlags = X86II::MO_PLT; 19453b67e9ba015624a9904a41d6d0fd61cac1b02055Chris Lattner } else if (Subtarget->isPICStyleStubAny() && 194651e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner (GV->isDeclaration() || GV->isWeakForLinker()) && 1947558692fd0a31d4d3ae4fd09a3a02f80da2e44e5cDaniel Dunbar (!Subtarget->getTargetTriple().isMacOSX() || 1948558692fd0a31d4d3ae4fd09a3a02f80da2e44e5cDaniel Dunbar Subtarget->getTargetTriple().isMacOSXVersionLT(10, 5))) { 194951e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // PC-relative references to external symbols should go through $stub, 195051e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // unless we're building with the leopard linker or later, which 195151e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner // automatically synthesizes these stubs. 195251e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner OpFlags = X86II::MO_DARWIN_STUB; 195351e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner } 1954bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1955bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 195625255cbe0000abd64194e9e34098243cd689fd47Eli Friedman MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)); 195725255cbe0000abd64194e9e34098243cd689fd47Eli Friedman if (MemIntName) 19588a37aba693bcc85b33c12d9c67322ef5f674c9a6Eli Friedman MIB.addExternalSymbol(MemIntName, OpFlags); 195925255cbe0000abd64194e9e34098243cd689fd47Eli Friedman else 196025255cbe0000abd64194e9e34098243cd689fd47Eli Friedman MIB.addGlobalAddress(GV, 0, OpFlags); 196151e8eabd3c50fc60e909cbd1729a8698c267beb2Chris Lattner } 19622cc3aa44591313307e2d596daca784419ab7286dDan Gohman 196385dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen // Add a register mask with the call-preserved registers. 196485dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen // Proper defs for return values will be added by setPhysRegsDeadExcept(). 196585dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen MIB.addRegMask(TRI.getCallPreservedMask(CS.getCallingConv())); 196685dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen 19672cc3aa44591313307e2d596daca784419ab7286dDan Gohman // Add an implicit use GOT pointer in EBX. 196815a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner if (Subtarget->isPICStyleGOT()) 196985dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen MIB.addReg(X86::EBX, RegState::Implicit); 19702cc3aa44591313307e2d596daca784419ab7286dDan Gohman 19713762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64()) 197285dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen MIB.addReg(X86::AL, RegState::Implicit); 19733762046dbfbf17b0c21804cce39f02b2dce05ff9Eli Friedman 1974f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Add implicit physical register uses to the call. 19758c3f8b6dea6d8ddcc40e3d996caa93067ee64454Dan Gohman for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) 197685dccf18ea0e0b7258d1c5f186b616e022dbebf1Jakob Stoklund Olesen MIB.addReg(RegArgs[i], RegState::Implicit); 19778bcde2aa66415ba2e63b22d2a3c1750bfb25b550Jakob Stoklund Olesen 1978f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Issue CALLSEQ_END 1979d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); 1980c338fe082860989d89b51520042a5f447339eb8cRafael Espindola const unsigned NumBytesCallee = computeBytesPoppedByCallee(*Subtarget, CS); 198184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackUp)) 1982d227eedf8270f816270259742c17685f59044a22Eli Friedman .addImm(NumBytes).addImm(NumBytesCallee); 1983f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 198419515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman // Build info for return calling conv lowering code. 198519515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman // FIXME: This is practically a copy-paste from TargetLowering::LowerCallTo. 198619515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman SmallVector<ISD::InputArg, 32> Ins; 198719515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman SmallVector<EVT, 4> RetTys; 198819515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman ComputeValueVTs(TLI, I->getType(), RetTys); 198919515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman for (unsigned i = 0, e = RetTys.size(); i != e; ++i) { 199019515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman EVT VT = RetTys[i]; 1991dfcf33a287d1756721f1f735af687595ce2f5a21Patrik Hagglund MVT RegisterVT = TLI.getRegisterType(I->getParent()->getContext(), VT); 199219515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman unsigned NumRegs = TLI.getNumRegisters(I->getParent()->getContext(), VT); 199319515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman for (unsigned j = 0; j != NumRegs; ++j) { 199419515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman ISD::InputArg MyFlags; 1995dfcf33a287d1756721f1f735af687595ce2f5a21Patrik Hagglund MyFlags.VT = RegisterVT; 199619515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman MyFlags.Used = !CS.getInstruction()->use_empty(); 1997034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(0, Attribute::SExt)) 199819515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman MyFlags.Flags.setSExt(); 1999034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(0, Attribute::ZExt)) 200019515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman MyFlags.Flags.setZExt(); 2001034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling if (CS.paramHasAttr(0, Attribute::InReg)) 200219515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman MyFlags.Flags.setInReg(); 200319515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman Ins.push_back(MyFlags); 200419515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman } 200519515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman } 2006c93943b6fef4d84a9934cf23f8b14d3a8952f26fEli Friedman 200719515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman // Now handle call return values. 200819515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman SmallVector<unsigned, 4> UsedRegs; 200919515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman SmallVector<CCValAssign, 16> RVLocs; 2010471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCRetInfo(CC, false, *FuncInfo.MF, TM, RVLocs, 201156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling I->getParent()->getContext()); 201219515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman unsigned ResultReg = FuncInfo.CreateRegs(I->getType()); 201319515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman CCRetInfo.AnalyzeCallResult(Ins, RetCC_X86); 201419515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman for (unsigned i = 0; i != RVLocs.size(); ++i) { 201519515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman EVT CopyVT = RVLocs[i].getValVT(); 201619515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman unsigned CopyReg = ResultReg + i; 2017bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2018f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // If this is a call to a function that returns an fp value on the x87 fp 2019f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // stack, but where we prefer to use the value in xmm registers, copy it 2020f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // out as F80 and use a truncate to move it from fp stack reg to xmm reg. 202119515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman if ((RVLocs[i].getLocReg() == X86::ST0 || 20229bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen RVLocs[i].getLocReg() == X86::ST1)) { 2023098c7ac7c8bbc519a4ef4ab242140be459f0dae2Jakob Stoklund Olesen if (isScalarFPTypeInSSEReg(RVLocs[i].getValVT())) { 20249bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen CopyVT = MVT::f80; 2025c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper CopyReg = createResultReg(&X86::RFP80RegClass); 2026098c7ac7c8bbc519a4ef4ab242140be459f0dae2Jakob Stoklund Olesen } 20279bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::FpPOP_RETVAL), 20289bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen CopyReg); 20299bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen } else { 20309bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 20319bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen CopyReg).addReg(RVLocs[i].getLocReg()); 20329bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen UsedRegs.push_back(RVLocs[i].getLocReg()); 2033f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng } 2034f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 203519515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman if (CopyVT != RVLocs[i].getValVT()) { 2036f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // Round the F80 the right size, which also moves to the appropriate xmm 2037f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // register. This is accomplished by storing the F80 value in memory and 2038f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng // then loading it back. Ewww... 203919515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman EVT ResVT = RVLocs[i].getValVT(); 2040825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64; 2041f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng unsigned MemSize = ResVT.getSizeInBits()/8; 20423f2bf85d14759cc4b28a86805f566ac805a54d00David Greene int FI = MFI.CreateStackObject(MemSize, MemSize, false); 204384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 204484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(Opc)), FI) 204519515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman .addReg(CopyReg); 2046825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Opc = ResVT == MVT::f32 ? X86::MOVSSrm : X86::MOVSDrm; 204784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 204819515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman TII.get(Opc), ResultReg + i), FI); 2049debdea0a6693193d8a2968616c9c51c0bbede4aeEvan Cheng } 2050c93943b6fef4d84a9934cf23f8b14d3a8952f26fEli Friedman } 2051cdc9a20561ff6e2dc9cf7ee6aac70f54c06579c3Eli Friedman 205219515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman if (RVLocs.size()) 205319515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman UpdateValueMap(I, ResultReg, RVLocs.size()); 205419515b4e52c16723097c5b9c5f5fe65540db0187Eli Friedman 2055db4971259ce94cea26e555e9ade82672a3581f5cDan Gohman // Set all unused physreg defs as dead. 2056db4971259ce94cea26e555e9ade82672a3581f5cDan Gohman static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); 2057db4971259ce94cea26e555e9ade82672a3581f5cDan Gohman 2058f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return true; 2059f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng} 2060f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 2061f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng 206299b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohmanbool 206346510a73e977273ec67747eb34cbdb43f815e451Dan GohmanX86FastISel::TargetSelectInstruction(const Instruction *I) { 206499b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman switch (I->getOpcode()) { 206599b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman default: break; 20668b19e56051c45c3e48523238a5a0f33bbac0115dEvan Cheng case Instruction::Load: 20673df24e667f04a7003342b534310919abc9c87418Dan Gohman return X86SelectLoad(I); 206879924eb6f5708a2ae36ba22b674b2d7bea3167e6Owen Anderson case Instruction::Store: 206979924eb6f5708a2ae36ba22b674b2d7bea3167e6Owen Anderson return X86SelectStore(I); 207084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman case Instruction::Ret: 207184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman return X86SelectRet(I); 20726e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman case Instruction::ICmp: 20736e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman case Instruction::FCmp: 20746e3f05f5cebe230bb95f01b5afcc3c8e94106402Dan Gohman return X86SelectCmp(I); 2075d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman case Instruction::ZExt: 2076d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman return X86SelectZExt(I); 2077d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman case Instruction::Br: 2078d89ae99ec81f4806fe02b54c7dbe706a1f49ddabDan Gohman return X86SelectBranch(I); 2079f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng case Instruction::Call: 2080f3d4efe30cb324ed201a2a96d5850b67e850f520Evan Cheng return X86SelectCall(I); 2081c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman case Instruction::LShr: 2082c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman case Instruction::AShr: 2083c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman case Instruction::Shl: 2084c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman return X86SelectShift(I); 2085c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman case Instruction::Select: 2086c39f4dba1c79af56c1d41ca40ab07390db8a8fb0Dan Gohman return X86SelectSelect(I); 208710a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng case Instruction::Trunc: 208810a8d9c737eb0e55b9460e3743b0136ab91ed833Evan Cheng return X86SelectTrunc(I); 208978efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman case Instruction::FPExt: 209078efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman return X86SelectFPExt(I); 209178efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman case Instruction::FPTrunc: 209278efce61559ae42a26724eb302d3da8be8a6ede0Dan Gohman return X86SelectFPTrunc(I); 2093474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman case Instruction::IntToPtr: // Deliberate fall-through. 2094474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman case Instruction::PtrToInt: { 2095e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); 2096e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DstVT = TLI.getValueType(I->getType()); 2097474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman if (DstVT.bitsGT(SrcVT)) 2098474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman return X86SelectZExt(I); 2099474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman if (DstVT.bitsLT(SrcVT)) 2100474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman return X86SelectTrunc(I); 2101474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman unsigned Reg = getRegForValue(I->getOperand(0)); 2102474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman if (Reg == 0) return false; 2103474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman UpdateValueMap(I, Reg); 2104474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman return true; 2105474d3b3f40e117a66946e9fb9d2016b4c05caef0Dan Gohman } 210699b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman } 210799b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman 210899b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman return false; 210999b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman} 211099b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman 211146510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanunsigned X86FastISel::TargetMaterializeConstant(const Constant *C) { 21121440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands MVT VT; 2113160f6cc209068e5e2db6514a010d5a32cf28be4fChris Lattner if (!isTypeLegal(C->getType(), VT)) 2114faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao return 0; 2115faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao 2116faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao // Can't handle alternate code models yet. 2117faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao if (TM.getCodeModel() != CodeModel::Small) 2118faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao return 0; 2119bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 212095267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson // Get opcode and regclass of the output for the given load instruction. 212195267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson unsigned Opc = 0; 212295267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson const TargetRegisterClass *RC = NULL; 21231440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands switch (VT.SimpleTy) { 2124faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao default: return 0; 2125825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: 212695267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson Opc = X86::MOV8rm; 2127c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR8RegClass; 212895267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson break; 2129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 213095267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson Opc = X86::MOV16rm; 2131c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR16RegClass; 213295267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson break; 2133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 213495267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson Opc = X86::MOV32rm; 2135c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR32RegClass; 213695267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson break; 2137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: 213895267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson // Must be in x86-64 mode. 213995267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson Opc = X86::MOV64rm; 2140c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::GR64RegClass; 214195267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson break; 2142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f32: 2143645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes if (X86ScalarSSEf32) { 2144645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes Opc = Subtarget->hasAVX() ? X86::VMOVSSrm : X86::MOVSSrm; 2145c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::FR32RegClass; 214695267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson } else { 214795267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson Opc = X86::LD_Fp32m; 2148c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::RFP32RegClass; 214995267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson } 215095267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson break; 2151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f64: 2152645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes if (X86ScalarSSEf64) { 2153645b8be38a71f1a5d2d87ba4a649b11ad7875744Bruno Cardoso Lopes Opc = Subtarget->hasAVX() ? X86::VMOVSDrm : X86::MOVSDrm; 2154c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::FR64RegClass; 215595267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson } else { 215695267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson Opc = X86::LD_Fp64m; 2157c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper RC = &X86::RFP64RegClass; 215895267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson } 215995267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson break; 2160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f80: 21615af29c2e5709b56de701fa4adb4705b9f84973c8Dan Gohman // No f80 support yet. 2162faa1159a6915992d7f035ce06caf952fd4a4e96aMichael Liao return 0; 216395267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson } 2164bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 21652ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman // Materialize addresses with LEA instructions. 216695267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson if (isa<GlobalValue>(C)) { 21672ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman X86AddressMode AM; 21680aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (X86SelectAddress(C, AM)) { 2169685090f5988a03da1a515493bad1e592d26b9956Chris Lattner // If the expression is just a basereg, then we're done, otherwise we need 2170685090f5988a03da1a515493bad1e592d26b9956Chris Lattner // to emit an LEA. 2171685090f5988a03da1a515493bad1e592d26b9956Chris Lattner if (AM.BaseType == X86AddressMode::RegBase && 2172685090f5988a03da1a515493bad1e592d26b9956Chris Lattner AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == 0) 2173685090f5988a03da1a515493bad1e592d26b9956Chris Lattner return AM.Base.Reg; 2174471e4224809f51652c71f319532697a879a75a0dEric Christopher 2175685090f5988a03da1a515493bad1e592d26b9956Chris Lattner Opc = TLI.getPointerTy() == MVT::i32 ? X86::LEA32r : X86::LEA64r; 21762ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman unsigned ResultReg = createResultReg(RC); 217784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 217884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(Opc), ResultReg), AM); 217995267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson return ResultReg; 21802ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman } 21810de588fd89ca7374dc91623d6627cfb98cfe3fc8Evan Cheng return 0; 218295267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson } 2183bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 21843b217c6f5c21a5f16670b14e3beeaff5ee74df1cOwen Anderson // MachineConstantPool wants an explicit alignment. 21851606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Align = TD.getPrefTypeAlignment(C->getType()); 21863b217c6f5c21a5f16670b14e3beeaff5ee74df1cOwen Anderson if (Align == 0) { 21873b217c6f5c21a5f16670b14e3beeaff5ee74df1cOwen Anderson // Alignment of vector types. FIXME! 2188777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands Align = TD.getTypeAllocSize(C->getType()); 21893b217c6f5c21a5f16670b14e3beeaff5ee74df1cOwen Anderson } 2190bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 21915396c99baa8fe0c821b9157590d8e9cd498b15bcDan Gohman // x86-32 PIC requires a PIC base register for constant pools. 21925396c99baa8fe0c821b9157590d8e9cd498b15bcDan Gohman unsigned PICBase = 0; 219389da6990929d2a03a4ed5063f75a9d84bc0c17e9Chris Lattner unsigned char OpFlag = 0; 2194e2c920845a407957b8ae2600feae1f4c85a0d4d0Chris Lattner if (Subtarget->isPICStyleStubPIC()) { // Not dynamic-no-pic 219515a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner OpFlag = X86II::MO_PIC_BASE_OFFSET; 2196a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF); 219715a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner } else if (Subtarget->isPICStyleGOT()) { 219815a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner OpFlag = X86II::MO_GOTOFF; 2199a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF); 220015a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner } else if (Subtarget->isPICStyleRIPRel() && 220115a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner TM.getCodeModel() == CodeModel::Small) { 220215a380a03567deba90c074a2cd5a45b81ae0958bChris Lattner PICBase = X86::RIP; 220389da6990929d2a03a4ed5063f75a9d84bc0c17e9Chris Lattner } 22045396c99baa8fe0c821b9157590d8e9cd498b15bcDan Gohman 22055396c99baa8fe0c821b9157590d8e9cd498b15bcDan Gohman // Create the load from the constant pool. 22060586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman unsigned MCPOffset = MCP.getConstantPoolIndex(C, Align); 22072ff7fd146159d97abe94391a33b4385abb06bbb0Dan Gohman unsigned ResultReg = createResultReg(RC); 220884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addConstantPoolReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 220984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(Opc), ResultReg), 221089da6990929d2a03a4ed5063f75a9d84bc0c17e9Chris Lattner MCPOffset, PICBase, OpFlag); 22115396c99baa8fe0c821b9157590d8e9cd498b15bcDan Gohman 221295267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson return ResultReg; 221395267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson} 221495267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson 221546510a73e977273ec67747eb34cbdb43f815e451Dan Gohmanunsigned X86FastISel::TargetMaterializeAlloca(const AllocaInst *C) { 22164e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // Fail on dynamic allocas. At this point, getRegForValue has already 22174e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // checked its CSE maps, so if we're here trying to handle a dynamic 22184e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // alloca, we're not going to succeed. X86SelectAddress has a 22194e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // check for dynamic allocas, because it's called directly from 22204e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // various places, but TargetMaterializeAlloca also needs a check 22214e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // in order to avoid recursion between getRegForValue, 22224e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman // X86SelectAddrss, and TargetMaterializeAlloca. 2223a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman if (!FuncInfo.StaticAllocaMap.count(C)) 22244e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman return 0; 22254e6ed5eefd578db5bff172298d7ff7d7eb69b947Dan Gohman 22260586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman X86AddressMode AM; 22270aa43de1d0ef6b5ba3a1dd7fe4f2d40797d96f5aChris Lattner if (!X86SelectAddress(C, AM)) 22280586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman return 0; 22290586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman unsigned Opc = Subtarget->is64Bit() ? X86::LEA64r : X86::LEA32r; 223044d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper const TargetRegisterClass* RC = TLI.getRegClassFor(TLI.getPointerTy()); 22310586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman unsigned ResultReg = createResultReg(RC); 223284023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 223384023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman TII.get(Opc), ResultReg), AM); 22340586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman return ResultReg; 22350586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman} 22360586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman 22372790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedmanunsigned X86FastISel::TargetMaterializeFloatZero(const ConstantFP *CF) { 22382790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman MVT VT; 22392790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman if (!isTypeLegal(CF->getType(), VT)) 22401c1c49372c23f6e22ef423c1d69779549dfe34bfJakub Staszak return 0; 22412790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman 22422790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman // Get opcode and regclass for the given zero. 22432790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman unsigned Opc = 0; 22442790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman const TargetRegisterClass *RC = NULL; 22452790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman switch (VT.SimpleTy) { 22461c1c49372c23f6e22ef423c1d69779549dfe34bfJakub Staszak default: return 0; 2247f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper case MVT::f32: 2248f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper if (X86ScalarSSEf32) { 2249f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper Opc = X86::FsFLD0SS; 2250f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper RC = &X86::FR32RegClass; 2251f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper } else { 2252f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper Opc = X86::LD_Fp032; 2253f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper RC = &X86::RFP32RegClass; 2254f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper } 2255f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper break; 2256f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper case MVT::f64: 2257f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper if (X86ScalarSSEf64) { 2258f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper Opc = X86::FsFLD0SD; 2259f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper RC = &X86::FR64RegClass; 2260f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper } else { 2261f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper Opc = X86::LD_Fp064; 2262f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper RC = &X86::RFP64RegClass; 2263f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper } 2264f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper break; 2265f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper case MVT::f80: 2266f4cfc4423cd48fd673e1de17aafe4db21e52f876Craig Topper // No f80 support yet. 22671c1c49372c23f6e22ef423c1d69779549dfe34bfJakub Staszak return 0; 22682790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman } 22692790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman 22702790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman unsigned ResultReg = createResultReg(RC); 22712790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg); 22722790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman return ResultReg; 22732790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman} 22742790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman 22752790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman 2276beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner/// TryToFoldLoad - The specified machine instr operand is a vreg, and that 2277beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner/// vreg is being provided by the specified load instruction. If possible, 2278beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner/// try to fold the load as an operand to the instruction, returning true if 2279beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner/// possible. 2280beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattnerbool X86FastISel::TryToFoldLoad(MachineInstr *MI, unsigned OpNo, 2281beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner const LoadInst *LI) { 2282beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner X86AddressMode AM; 2283beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner if (!X86SelectAddress(LI->getOperand(0), AM)) 2284beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner return false; 2285bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2286dca72541d55fce71feffcb5c5a7e3ad573f7d55aCraig Topper const X86InstrInfo &XII = (const X86InstrInfo&)TII; 2287bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2288beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner unsigned Size = TD.getTypeAllocSize(LI->getType()); 2289beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner unsigned Alignment = LI->getAlignment(); 2290beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner 2291beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner SmallVector<MachineOperand, 8> AddrOps; 2292beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner AM.getFullAddress(AddrOps); 2293bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2294beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner MachineInstr *Result = 2295beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner XII.foldMemoryOperandImpl(*FuncInfo.MF, MI, OpNo, AddrOps, Size, Alignment); 2296beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner if (Result == 0) return false; 2297bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2298b99fdee325fe677081dc27bb7d719518452f3256Chris Lattner FuncInfo.MBB->insert(FuncInfo.InsertPt, Result); 2299beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner MI->eraseFromParent(); 2300beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner return true; 2301beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner} 2302beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner 2303beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner 2304c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Chengnamespace llvm { 2305d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson FastISel *X86::createFastISel(FunctionLoweringInfo &funcInfo, 2306d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson const TargetLibraryInfo *libInfo) { 2307d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson return new X86FastISel(funcInfo, libInfo); 2308c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng } 230999b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman} 2310