SparcISelLowering.cpp revision b58126124081a9bf8da1368441b00070ed2db232
1d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===// 2d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// 3d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// The LLVM Compiler Infrastructure 4d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// 5d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// This file is distributed under the University of Illinois Open Source 6d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// License. See LICENSE.TXT for details. 7d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// 8d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===// 9d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// 10d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// This file implements the interfaces that Sparc uses to lower LLVM code into a 11d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// selection DAG. 12d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// 13d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===// 14d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 15d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "SparcISelLowering.h" 161e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman#include "SparcMachineFunctionInfo.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "SparcTargetMachine.h" 180ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen#include "MCTargetDesc/SparcBaseInfo.h" 195a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner#include "llvm/CodeGen/CallingConvLower.h" 20d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 21d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineFunction.h" 22d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineInstrBuilder.h" 23d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h" 24d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/SelectionDAG.h" 25362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 29c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 30d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattnerusing namespace llvm; 31d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 33d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===// 345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner// Calling Convention Implementation 35d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===// 36d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 378184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindarajustatic bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT, 388184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MVT &LocVT, CCValAssign::LocInfo &LocInfo, 398184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju ISD::ArgFlagsTy &ArgFlags, CCState &State) 408184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju{ 418184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju assert (ArgFlags.isSRet()); 428184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 431e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Assign SRet argument. 448184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 458184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 0, 468184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju LocVT, LocInfo)); 478184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju return true; 488184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju} 498184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 50687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindarajustatic bool CC_Sparc_Assign_f64(unsigned &ValNo, MVT &ValVT, 51687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MVT &LocVT, CCValAssign::LocInfo &LocInfo, 52687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ISD::ArgFlagsTy &ArgFlags, CCState &State) 53687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju{ 54c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t RegList[] = { 55687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 56687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju }; 571e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Try to get first reg. 58687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (unsigned Reg = State.AllocateReg(RegList, 6)) { 59687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 60687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 611e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Assign whole thing in stack. 62687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 63687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.AllocateStack(8,4), 64687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LocVT, LocInfo)); 65687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju return true; 66687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 67687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 681e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Try to get second reg. 69687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (unsigned Reg = State.AllocateReg(RegList, 6)) 70687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 71687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju else 72687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 73687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.AllocateStack(4,4), 74687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LocVT, LocInfo)); 75687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju return true; 76687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju} 77687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 781f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// Allocate a full-sized argument for the 64-bit ABI. 791f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesenstatic bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, 801f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen MVT &LocVT, CCValAssign::LocInfo &LocInfo, 811f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen ISD::ArgFlagsTy &ArgFlags, CCState &State) { 821f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen assert((LocVT == MVT::f32 || LocVT.getSizeInBits() == 64) && 831f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen "Can't handle non-64 bits locations"); 841f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 851f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Stack space is allocated for all arguments starting from [%fp+BIAS+128]. 861f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Offset = State.AllocateStack(8, 8); 871f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Reg = 0; 881f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 891f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::i64 && Offset < 6*8) 901f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote integers to %i0-%i5. 911f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Reg = SP::I0 + Offset/8; 921f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen else if (LocVT == MVT::f64 && Offset < 16*8) 931f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote doubles to %d0-%d30. (Which LLVM calls D0-D15). 941f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Reg = SP::D0 + Offset/8; 951f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen else if (LocVT == MVT::f32 && Offset < 16*8) 961f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote floats to %f1, %f3, ... 971f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Reg = SP::F1 + Offset/4; 981f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 991f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote to register when possible, otherwise use the stack slot. 1001f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (Reg) { 1011f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 1021f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1031f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen } 1041f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1051f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // This argument goes on the stack in an 8-byte slot. 1061f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to 1071f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // the right-aligned float. The first 4 bytes of the stack slot are undefined. 1081f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::f32) 1091f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Offset += 4; 1101f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1111f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 1121f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1131f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen} 1141f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1151f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// Allocate a half-sized argument for the 64-bit ABI. 1161f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// 1171f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// This is used when passing { float, int } structs by value in registers. 1181f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesenstatic bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, 1191f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen MVT &LocVT, CCValAssign::LocInfo &LocInfo, 1201f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen ISD::ArgFlagsTy &ArgFlags, CCState &State) { 1211f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations"); 1221f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Offset = State.AllocateStack(4, 4); 1231f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1241f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::f32 && Offset < 16*8) { 1251f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote floats to %f0-%f31. 1261f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getReg(ValNo, ValVT, SP::F0 + Offset/4, 1271f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocVT, LocInfo)); 1281f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1291f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen } 1301f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1311f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::i32 && Offset < 6*8) { 1321f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote integers to %i0-%i5, using half the register. 1331f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Reg = SP::I0 + Offset/8; 1341f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocVT = MVT::i64; 1351f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocInfo = CCValAssign::AExt; 1361f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1371f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Set the Custom bit if this i32 goes in the high bits of a register. 1381f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (Offset % 8 == 0) 1391f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, 1401f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocVT, LocInfo)); 1411f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen else 1421f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 1431f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1441f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen } 1451f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1461f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 1471f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1481f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen} 1491f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1505a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner#include "SparcGenCallingConv.inc" 151d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1521b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// The calling conventions in SparcCallingConv.td are described in terms of the 1531b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// callee's register window. This function translates registers to the 1541b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// corresponding caller window %o register. 1551b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesenstatic unsigned toCallerWindow(unsigned Reg) { 1561b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen assert(SP::I0 + 7 == SP::I7 && SP::O0 + 7 == SP::O7 && "Unexpected enum"); 1571b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen if (Reg >= SP::I0 && Reg <= SP::I7) 1581b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen return Reg - SP::I0 + SP::O0; 1591b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen return Reg; 1601b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen} 1611b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen 16298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 16398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSparcTargetLowering::LowerReturn(SDValue Chain, 16453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CallingConv::ID CallConv, bool IsVarArg, 16598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 166c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 167ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 16853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (Subtarget->is64Bit()) 16953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen return LowerReturn_64(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG); 17053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen return LowerReturn_32(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG); 17153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen} 17298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 17353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSDValue 17453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSparcTargetLowering::LowerReturn_32(SDValue Chain, 17553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CallingConv::ID CallConv, bool IsVarArg, 17653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<ISD::OutputArg> &Outs, 17753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<SDValue> &OutVals, 178ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 1798184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MachineFunction &MF = DAG.getMachineFunction(); 1808184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 1815a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // CCValAssign - represent the assignment of the return value to locations. 1825a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner SmallVector<CCValAssign, 16> RVLocs; 18353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1845a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // CCState - Info about the registers and stack slot. 18553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), 18656cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling DAG.getTarget(), RVLocs, *DAG.getContext()); 18753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 18853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Analyze return values. 18953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32); 19053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 191475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Flag; 192067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 193067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen // Make room for the return address offset. 194067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(SDValue()); 195d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1965a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Copy the result values into the output registers. 1975a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner for (unsigned i = 0; i != RVLocs.size(); ++i) { 1985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner CCValAssign &VA = RVLocs[i]; 1995a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner assert(VA.isRegLoc() && "Can only return in registers!"); 20053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 20153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), 202c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 20353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2045a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Guarantee that all emitted copies are stuck together with flags. 2055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner Flag = Chain.getValue(1); 206067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 207d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 20858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 2091e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju unsigned RetAddrOffset = 8; // Call Inst + Delay Slot 2108184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju // If the function returns a struct, copy the SRetReturnReg to I0 2118184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (MF.getFunction()->hasStructRetAttr()) { 2128184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>(); 2138184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju unsigned Reg = SFI->getSRetReturnReg(); 2148184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (!Reg) 2158184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju llvm_unreachable("sret virtual register not created in the entry block"); 21653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy()); 21753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Flag); 2188184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju Flag = Chain.getValue(1); 219067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(DAG.getRegister(SP::I0, getPointerTy())); 22058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju RetAddrOffset = 12; // CallInst + Delay Slot + Unimp 2218184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 22253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 223067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 224067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps[1] = DAG.getConstant(RetAddrOffset, MVT::i32); 22558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 226067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen // Add the flag if we have it. 227ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Flag.getNode()) 228067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(Flag); 229067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen 23053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, 23153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen &RetOps[0], RetOps.size()); 23253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen} 23353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 23453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen// Lower return values for the 64-bit ABI. 23553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen// Return values are passed the exactly the same way as function arguments. 23653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSDValue 23753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSparcTargetLowering::LowerReturn_64(SDValue Chain, 23853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CallingConv::ID CallConv, bool IsVarArg, 23953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<ISD::OutputArg> &Outs, 24053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<SDValue> &OutVals, 241ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 24253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // CCValAssign - represent the assignment of the return value to locations. 24353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SmallVector<CCValAssign, 16> RVLocs; 24453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 24553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // CCState - Info about the registers and stack slot. 24653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), 24753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen DAG.getTarget(), RVLocs, *DAG.getContext()); 24853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 24953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Analyze return values. 25053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCInfo.AnalyzeReturn(Outs, CC_Sparc64); 25153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 25253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue Flag; 25353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 25453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 25553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The second operand on the return instruction is the return address offset. 25653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The return address is always %i7+8 with the 64-bit ABI. 25753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps.push_back(DAG.getConstant(8, MVT::i32)); 25853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 25953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Copy the result values into the output registers. 26053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen for (unsigned i = 0; i != RVLocs.size(); ++i) { 26153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCValAssign &VA = RVLocs[i]; 26253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen assert(VA.isRegLoc() && "Can only return in registers!"); 26353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue OutVal = OutVals[i]; 26453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 26553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Integer return values must be sign or zero extended by the callee. 26653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen switch (VA.getLocInfo()) { 26753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen case CCValAssign::SExt: 26853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); 26953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen break; 27053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen case CCValAssign::ZExt: 27153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal); 27253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen break; 27353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen case CCValAssign::AExt: 27453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); 27553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen default: 27653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen break; 27753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 27853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 27953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The custom bit on an i32 return value indicates that it should be passed 28053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // in the high bits of the register. 28153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) { 28253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal, 28353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 28453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 28553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The next value may go in the low bits of the same register. 28653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Handle both at once. 28753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) { 28853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]); 28953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV); 29053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Skip the next value, it's already done. 29153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen ++i; 29253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 29353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 29453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 29553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag); 29653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 29753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Guarantee that all emitted copies are stuck together with flags. 29853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Flag = Chain.getValue(1); 29953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 30053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 30153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 30253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 30353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 30453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Add the flag if we have it. 30553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (Flag.getNode()) 30653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps.push_back(Flag); 30753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 30853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, 309067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen &RetOps[0], RetOps.size()); 310d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 311d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 312f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering:: 313f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments(SDValue Chain, 314f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CallingConv::ID CallConv, 315f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen bool IsVarArg, 316f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen const SmallVectorImpl<ISD::InputArg> &Ins, 317ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, 318f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SelectionDAG &DAG, 319f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 320f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen if (Subtarget->is64Bit()) 321f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins, 322f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DL, DAG, InVals); 323f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins, 324f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DL, DAG, InVals); 325f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen} 326f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 327f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are 32898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// passed in either one or two GPRs, including FP values. TODO: we should 32998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// pass FP values in FP registers for fastcc functions. 330f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering:: 331f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments_32(SDValue Chain, 332f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CallingConv::ID CallConv, 333f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen bool isVarArg, 334f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen const SmallVectorImpl<ISD::InputArg> &Ins, 335ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 336f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SelectionDAG &DAG, 337f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 338d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineFunction &MF = DAG.getMachineFunction(); 339d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineRegisterInfo &RegInfo = MF.getRegInfo(); 3401e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 341a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman 342a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman // Assign locations to all of the incoming arguments. 343a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman SmallVector<CCValAssign, 16> ArgLocs; 344471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 34556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 34698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32); 34753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 348687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju const unsigned StackOffset = 92; 34953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 350a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 351a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman CCValAssign &VA = ArgLocs[i]; 35253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 3538184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (i == 0 && Ins[i].Flags.isSRet()) { 3541e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Get SRet from [%fp+64]. 3558184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true); 3568184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 3578184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, 3588184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MachinePointerInfo(), 359d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 3608184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju InVals.push_back(Arg); 3618184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju continue; 3628184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 3638184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 364687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isRegLoc()) { 365687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.needsCustom()) { 366687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.getLocVT() == MVT::f64); 367687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 368687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi); 369687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32); 370d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 371687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(i+1 < e); 372687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju CCValAssign &NextVA = ArgLocs[++i]; 37353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 374475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LoVal; 375687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (NextVA.isMemLoc()) { 376687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FrameIdx = MF.getFrameInfo()-> 377687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true); 378825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 379687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, 380687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 381d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 382687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 383687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned loReg = MF.addLiveIn(NextVA.getLocReg(), 38468e6beeccc0b9ac2e8d3687a8a5b7d4b172edca1Devang Patel &SP::IntRegsRegClass); 385687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32); 386d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 38753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov SDValue WholeValue = 388825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); 389687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue); 390687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(WholeValue); 391687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 392687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 393687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 394687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg); 395687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 396687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.getLocVT() == MVT::f32) 397687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg); 398687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju else if (VA.getLocVT() != MVT::i32) { 399687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg, 400687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju DAG.getValueType(VA.getLocVT())); 401687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg); 402687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 403687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(Arg); 404687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 405687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 40653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 407687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.isMemLoc()); 40853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 409687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = VA.getLocMemOffset()+StackOffset; 410687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 411687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.needsCustom()) { 412687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.getValVT() == MVT::f64); 4131e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // If it is double-word aligned, just load. 414687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (Offset % 8 == 0) { 415687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI = MF.getFrameInfo()->CreateFixedObject(8, 416687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset, 417687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 418687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 419687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, 420687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 421d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false,false, false, 0); 422687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(Load); 423687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 424d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 425687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 426687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI = MF.getFrameInfo()->CreateFixedObject(4, 427687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset, 428687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 429687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 430687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, 431687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 432d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 433687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI2 = MF.getFrameInfo()->CreateFixedObject(4, 434687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset+4, 435687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 436687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr2 = DAG.getFrameIndex(FI2, getPointerTy()); 437687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 438687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr2, 439687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 440d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 441687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 442687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue WholeValue = 443687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); 444687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue); 445687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(WholeValue); 446687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 447d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 448687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 449687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI = MF.getFrameInfo()->CreateFixedObject(4, 450687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset, 451687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 452687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 453687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Load ; 454687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) { 455687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, 456687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 457d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 458687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 459687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ISD::LoadExtType LoadOp = ISD::SEXTLOAD; 460687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Sparc is big endian, so add an offset based on the ObjectVT. 461687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = 4-std::max(1U, VA.getValVT().getSizeInBits()/8); 462687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr, 463687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju DAG.getConstant(Offset, MVT::i32)); 464a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr, 465687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 466687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju VA.getValVT(), false, false,0); 467687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Load = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Load); 468687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 469687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(Load); 470d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 47153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 4728184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (MF.getFunction()->hasStructRetAttr()) { 4731e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Copy the SRet Argument to SRetReturnReg. 4748184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>(); 4758184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju unsigned Reg = SFI->getSRetReturnReg(); 4768184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (!Reg) { 4778184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass); 4788184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SFI->setSRetReturnReg(Reg); 4798184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 4808184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]); 4818184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); 4828184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 4838184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 484d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Store remaining ArgRegs to the stack if this is a varargs function. 485a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman if (isVarArg) { 486c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t ArgRegs[] = { 487687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 488687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju }; 489687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs, 6); 490c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper const uint16_t *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6; 491687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned ArgOffset = CCInfo.getNextStackOffset(); 492687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (NumAllocated == 6) 493687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ArgOffset += StackOffset; 494687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju else { 495687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(!ArgOffset); 496687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ArgOffset = 68+4*NumAllocated; 497687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 498687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 499d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Remember the vararg offset for the va_start implementation. 5001e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman FuncInfo->setVarArgsFrameOffset(ArgOffset); 50153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 502a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman std::vector<SDValue> OutChains; 503a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman 504d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner for (; CurArgReg != ArgRegEnd; ++CurArgReg) { 505d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 506d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MF.getRegInfo().addLiveIn(*CurArgReg, VReg); 507825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32); 508d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 5093f2bf85d14759cc4b28a86805f566ac805a54d00David Greene int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset, 510ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 511825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 512d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 5136229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, 5146229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), 51554a7aa84294e31140a023e0c721703a647fe227bDavid Greene false, false, 0)); 516d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ArgOffset += 4; 517d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 518a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman 519a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman if (!OutChains.empty()) { 52098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman OutChains.push_back(Chain); 521825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 52298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &OutChains[0], OutChains.size()); 523a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman } 524d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 52553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 52698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 527d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 528d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 529f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen// Lower formal arguments for the 64 bit ABI. 530f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering:: 531f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments_64(SDValue Chain, 532f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CallingConv::ID CallConv, 533f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen bool IsVarArg, 534f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen const SmallVectorImpl<ISD::InputArg> &Ins, 535ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, 536f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SelectionDAG &DAG, 537f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 538f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen MachineFunction &MF = DAG.getMachineFunction(); 539f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 540f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // Analyze arguments according to CC_Sparc64. 541f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVector<CCValAssign, 16> ArgLocs; 542f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), 543f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen getTargetMachine(), ArgLocs, *DAG.getContext()); 544f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64); 545f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 546da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // The argument array begins at %fp+BIAS+128, after the register save area. 547da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen const unsigned ArgArea = 128; 548da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 549f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 550f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CCValAssign &VA = ArgLocs[i]; 551f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen if (VA.isRegLoc()) { 552f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // This argument is passed in a register. 553f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // All integer register arguments are promoted by the caller to i64. 554f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 555f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // Create a virtual register for the promoted live-in value. 556f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen unsigned VReg = MF.addLiveIn(VA.getLocReg(), 557f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen getRegClassFor(VA.getLocVT())); 558f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()); 559f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 5601f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Get the high bits for i32 struct elements. 5611f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 5621f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg, 5631f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 5641f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 565f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // The caller promoted the argument, so insert an Assert?ext SDNode so we 566f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // won't promote the value again in this function. 567f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen switch (VA.getLocInfo()) { 568f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen case CCValAssign::SExt: 569f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg, 570f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 571f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen break; 572f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen case CCValAssign::ZExt: 573f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg, 574f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 575f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen break; 576f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen default: 577f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen break; 578f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen } 579f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 580f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // Truncate the register down to the argument type. 581f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen if (VA.isExtInLoc()) 582f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg); 583f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 584f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen InVals.push_back(Arg); 585f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen continue; 586f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen } 587f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 588f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // The registers are exhausted. This argument was passed on the stack. 589f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen assert(VA.isMemLoc()); 5901f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // The CC_Sparc64_Full/Half functions compute stack offsets relative to the 5911f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // beginning of the arguments area at %fp+BIAS+128. 592da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen unsigned Offset = VA.getLocMemOffset() + ArgArea; 5931f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned ValSize = VA.getValVT().getSizeInBits() / 8; 5941f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Adjust offset for extended arguments, SPARC is big-endian. 5951f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // The caller will have written the full slot with extended bytes, but we 5961f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // prefer our own extending loads. 5971f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (VA.isExtInLoc()) 5981f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Offset += 8 - ValSize; 5991f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true); 6001f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, 6011f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen DAG.getFrameIndex(FI, getPointerTy()), 6021f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen MachinePointerInfo::getFixedStack(FI), 6031f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen false, false, false, 0)); 604f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen } 605da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 606da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen if (!IsVarArg) 607da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen return Chain; 608da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 609da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // This function takes variable arguments, some of which may have been passed 610da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // in registers %i0-%i5. Variable floating point arguments are never passed 611da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // in floating point registers. They go on %i0-%i5 or on the stack like 612da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // integer arguments. 613da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // 614da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // The va_start intrinsic needs to know the offset to the first variable 615da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // argument. 616da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen unsigned ArgOffset = CCInfo.getNextStackOffset(); 617da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 618da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Skip the 128 bytes of register save area. 619da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgArea + 620da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen Subtarget->getStackPointerBias()); 621da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 622da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Save the variable arguments that were passed in registers. 623da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // The caller is required to reserve stack space for 6 arguments regardless 624da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // of how many arguments were actually passed. 625da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SmallVector<SDValue, 8> OutChains; 626da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen for (; ArgOffset < 6*8; ArgOffset += 8) { 627da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen unsigned VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass); 628da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64); 629da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen int FI = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset + ArgArea, true); 630da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen OutChains.push_back(DAG.getStore(Chain, DL, VArg, 631da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getFrameIndex(FI, getPointerTy()), 632da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen MachinePointerInfo::getFixedStack(FI), 633da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen false, false, 0)); 634da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen } 635da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 636da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen if (!OutChains.empty()) 637da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, 638da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen &OutChains[0], OutChains.size()); 639da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 640f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen return Chain; 641f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen} 642f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 64398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 644d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiSparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 645d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 64618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (Subtarget->is64Bit()) 64718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen return LowerCall_64(CLI, InVals); 64818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen return LowerCall_32(CLI, InVals); 64918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen} 65018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 65118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen// Lower a call for the 32-bit ABI. 65218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSDValue 65318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, 65418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 655d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 656ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &dl = CLI.DL; 657a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 658a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 659a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 660d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 661d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 662d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 663d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 664d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 665d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 6660c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // Sparc target does not yet support tail call optimization. 6670c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 66898949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner 669315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Analyze operands of the call, assigning locations to each operand. 670315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner SmallVector<CCValAssign, 16> ArgLocs; 671471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 67256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling DAG.getTarget(), ArgLocs, *DAG.getContext()); 67398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32); 67453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 675315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Get the size of the outgoing arguments stack space requirement. 676315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner unsigned ArgsSize = CCInfo.getNextStackOffset(); 67753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 678d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Keep stack frames 8-byte aligned. 679d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ArgsSize = (ArgsSize+7) & ~7; 680d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 68146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 68246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 6831e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Create local copies for byval args. 68446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SmallVector<SDValue, 8> ByValArgs; 68546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 68646713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju ISD::ArgFlagsTy Flags = Outs[i].Flags; 68746713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju if (!Flags.isByVal()) 68846713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju continue; 68946713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 69046713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SDValue Arg = OutVals[i]; 69146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju unsigned Size = Flags.getByValSize(); 69246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju unsigned Align = Flags.getByValAlign(); 69346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 69446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju int FI = MFI->CreateStackObject(Size, Align, false); 69546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 69646713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SDValue SizeNode = DAG.getConstant(Size, MVT::i32); 69746713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 69846713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Align, 6991e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju false, // isVolatile, 7001e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju (Size <= 32), // AlwaysInline if size <= 32 70146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju MachinePointerInfo(), MachinePointerInfo()); 70246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju ByValArgs.push_back(FIPtr); 70346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju } 70446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 7056e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true), 7066e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick dl); 70753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 708475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 709475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> MemOpChains; 71053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 711687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju const unsigned StackOffset = 92; 71258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju bool hasStructRetAttr = false; 713315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Walk the register/memloc assignments, inserting copies/loads. 71446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size(); 715687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju i != e; 716687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ++i, ++realArgIdx) { 717315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner CCValAssign &VA = ArgLocs[i]; 718687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Arg = OutVals[realArgIdx]; 719315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner 72046713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags; 72146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 7221e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Use local copy if it is a byval arg. 72346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju if (Flags.isByVal()) 72446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju Arg = ByValArgs[byvalArgIdx++]; 72546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 726315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Promote the value if needed. 727315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner switch (VA.getLocInfo()) { 728c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 729315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::Full: break; 730315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::SExt: 731687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 732315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner break; 733315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::ZExt: 734687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 735315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner break; 736315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::AExt: 737687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 738687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju break; 739687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju case CCValAssign::BCvt: 740687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg); 741315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner break; 742315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner } 74353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 7448184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (Flags.isSRet()) { 7458184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju assert(VA.needsCustom()); 7468184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju // store SRet argument in %sp+64 7478184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 7488184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(64); 7498184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 7508184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 7518184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MachinePointerInfo(), 7528184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju false, false, 0)); 75358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju hasStructRetAttr = true; 7548184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju continue; 7558184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 7568184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 757687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.needsCustom()) { 758687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.getLocVT() == MVT::f64); 759687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 760687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isMemLoc()) { 761687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = VA.getLocMemOffset() + StackOffset; 7621e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // if it is double-word aligned, just store. 763687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (Offset % 8 == 0) { 764687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 765687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(Offset); 766687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 767687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 768687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 769687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 770687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 77112db7b68b683371a6ae464e76b4c850fa0199eebVenkatraman Govindaraju } 7728c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 773687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 774825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32); 775bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, 776687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg, StackPtr, MachinePointerInfo(), 77754a7aa84294e31140a023e0c721703a647fe227bDavid Greene false, false, 0); 7788c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands // Sparc is big-endian, so the high part comes first. 779d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, 780d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 7818c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands // Increment the pointer to the other half. 78233c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 7838c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands DAG.getIntPtrConstant(4)); 7848c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands // Load the low part. 785d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, 786d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 7878c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands 788687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isRegLoc()) { 789687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(VA.getLocReg(), Hi)); 790687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(i+1 != e); 791687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju CCValAssign &NextVA = ArgLocs[++i]; 792687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (NextVA.isRegLoc()) { 793687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Lo)); 794687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 7951e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Store the low part in stack. 796687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = NextVA.getLocMemOffset() + StackOffset; 797687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 798687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(Offset); 799687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 800687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff, 801687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 802687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 803687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 8048c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } else { 805687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = VA.getLocMemOffset() + StackOffset; 806687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Store the high part. 807687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 808687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(Offset); 809687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 810687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Hi, PtrOff, 811687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 812687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 813687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Store the low part. 814687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getIntPtrConstant(Offset+4); 815687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 816687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff, 817687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 818687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 8198c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 820687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 8218c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 82253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 823687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Arguments that can be passed on register must be kept at 824687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // RegsToPass vector 825687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isRegLoc()) { 826687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.getLocVT() != MVT::f32) { 827687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 828687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 829d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 830687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg); 831687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 832687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 8338c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 83453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 835687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.isMemLoc()); 836687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 837687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Create a store off the stack pointer for this argument. 838687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 839687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+StackOffset); 840687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 841687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 842687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 843687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 844d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 845687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 84653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 847d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Emit all stores, make sure the occur before any copies into physregs. 848315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner if (!MemOpChains.empty()) 849825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 850315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner &MemOpChains[0], MemOpChains.size()); 85153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 85253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token 853315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // chain and flag operands which copy the outgoing args into registers. 8547a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // The InFlag in necessary since all emitted instructions must be 855315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // stuck together. 856475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InFlag; 857315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 8581b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen unsigned Reg = toCallerWindow(RegsToPass[i].first); 85933c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen Chain = DAG.getCopyToReg(Chain, dl, Reg, RegsToPass[i].second, InFlag); 860d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner InFlag = Chain.getValue(1); 861d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 862d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 86358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju unsigned SRetArgSize = (hasStructRetAttr)? getSRetArgSize(DAG, Callee):0; 86458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 865d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // If the callee is a GlobalAddress node (quite common, every direct call is) 866d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 867056292fd738924f3f7703725d8f630983794b5a5Bill Wendling // Likewise ExternalSymbol -> TargetExternalSymbol. 868d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 8690d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); 870056292fd738924f3f7703725d8f630983794b5a5Bill Wendling else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 871825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 872d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 8737d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju // Returns a chain & a flag for retval copy to use 8747d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 8757d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju SmallVector<SDValue, 8> Ops; 8767d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Ops.push_back(Chain); 8777d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Ops.push_back(Callee); 87858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (hasStructRetAttr) 87958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju Ops.push_back(DAG.getTargetConstant(SRetArgSize, MVT::i32)); 8801b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 8811b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen Ops.push_back(DAG.getRegister(toCallerWindow(RegsToPass[i].first), 8821b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen RegsToPass[i].second.getValueType())); 883b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen 884b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen // Add a register mask operand representing the call-preserved registers. 885b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); 886b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen const uint32_t *Mask = TRI->getCallPreservedMask(CallConv); 887b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen assert(Mask && "Missing call preserved mask for calling convention"); 888b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen Ops.push_back(DAG.getRegisterMask(Mask)); 889b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen 8907d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju if (InFlag.getNode()) 8917d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Ops.push_back(InFlag); 8927d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju 8937d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 894d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner InFlag = Chain.getValue(1); 89553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 896e563bbc312f8b11ecfe12b8187176f667df1dff3Chris Lattner Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), 8976e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick DAG.getIntPtrConstant(0, true), InFlag, dl); 89898949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner InFlag = Chain.getValue(1); 89953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 90098949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner // Assign locations to each value returned by this call. 90198949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner SmallVector<CCValAssign, 16> RVLocs; 902471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(), 90356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling DAG.getTarget(), RVLocs, *DAG.getContext()); 90453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 90598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32); 90653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 90798949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner // Copy all of the result registers out of their specified physreg. 90898949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner for (unsigned i = 0; i != RVLocs.size(); ++i) { 9091b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen Chain = DAG.getCopyFromReg(Chain, dl, toCallerWindow(RVLocs[i].getLocReg()), 91098949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner RVLocs[i].getValVT(), InFlag).getValue(1); 91198949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner InFlag = Chain.getValue(2); 91298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 913d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 91453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 91598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 916d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 917d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 91858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindarajuunsigned 91958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman GovindarajuSparcTargetLowering::getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const 92058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju{ 92158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju const Function *CalleeFn = 0; 92258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 92358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju CalleeFn = dyn_cast<Function>(G->getGlobal()); 92458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju } else if (ExternalSymbolSDNode *E = 92558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju dyn_cast<ExternalSymbolSDNode>(Callee)) { 92658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju const Function *Fn = DAG.getMachineFunction().getFunction(); 92758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju const Module *M = Fn->getParent(); 92858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju CalleeFn = M->getFunction(E->getSymbol()); 92958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju } 93058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 93158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (!CalleeFn) 93258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju return 0; 9335a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 93458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju assert(CalleeFn->hasStructRetAttr() && 93558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju "Callee does not have the StructRet attribute."); 93658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 937db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner PointerType *Ty = cast<PointerType>(CalleeFn->arg_begin()->getType()); 938db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ElementTy = Ty->getElementType(); 9393574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow return getDataLayout()->getTypeAllocSize(ElementTy); 94058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju} 9415a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 942ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 943ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// Fixup floating point arguments in the ... part of a varargs call. 944ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// 945ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// The SPARC v9 ABI requires that floating point arguments are treated the same 946ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// as integers when calling a varargs function. This does not apply to the 947ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// fixed arguments that are part of the function's prototype. 948ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// 949ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// This function post-processes a CCValAssign array created by 950ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// AnalyzeCallOperands(). 951ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesenstatic void fixupVariableFloatArgs(SmallVectorImpl<CCValAssign> &ArgLocs, 952ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen ArrayRef<ISD::OutputArg> Outs) { 953ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 954ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen const CCValAssign &VA = ArgLocs[i]; 955ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // FIXME: What about f32 arguments? C promotes them to f64 when calling 956ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // varargs functions. 957ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (!VA.isRegLoc() || VA.getLocVT() != MVT::f64) 958ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen continue; 959ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // The fixed arguments to a varargs function still go in FP registers. 960ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (Outs[VA.getValNo()].IsFixed) 961ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen continue; 962ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 963ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // This floating point argument should be reassigned. 964ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen CCValAssign NewVA; 965ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 966ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // Determine the offset into the argument array. 967ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen unsigned Offset = 8 * (VA.getLocReg() - SP::D0); 968ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen assert(Offset < 16*8 && "Offset out of range, bad register enum?"); 969ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 970ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (Offset < 6*8) { 971ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // This argument should go in %i0-%i5. 972ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen unsigned IReg = SP::I0 + Offset/8; 973ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // Full register, just bitconvert into i64. 974ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), 975ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen IReg, MVT::i64, CCValAssign::BCvt); 976ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen } else { 977ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // This needs to go to memory, we're out of integer registers. 978ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen NewVA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(), 979ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen Offset, VA.getLocVT(), VA.getLocInfo()); 980ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen } 981ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen ArgLocs[i] = NewVA; 982ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen } 983ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen} 984ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 98518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen// Lower a call for the 64-bit ABI. 98618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSDValue 98718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, 98818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 98918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SelectionDAG &DAG = CLI.DAG; 990ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL = CLI.DL; 99118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue Chain = CLI.Chain; 99218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 99318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Analyze operands of the call, assigning locations to each operand. 99418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<CCValAssign, 16> ArgLocs; 99518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 99618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getTarget(), ArgLocs, *DAG.getContext()); 99718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64); 99818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 99918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Get the size of the outgoing arguments stack space requirement. 100018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The stack offset computed by CC_Sparc64 includes all arguments. 10016ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen // Called functions expect 6 argument words to exist in the stack frame, used 10026ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen // or not. 10036ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen unsigned ArgsSize = std::max(6*8u, CCInfo.getNextStackOffset()); 100418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 100518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Keep stack frames 16-byte aligned. 100618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen ArgsSize = RoundUpToAlignment(ArgsSize, 16); 100718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 1008ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // Varargs calls require special treatment. 1009ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (CLI.IsVarArg) 1010ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen fixupVariableFloatArgs(ArgLocs, CLI.Outs); 1011ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 101218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Adjust the stack pointer to make room for the arguments. 101318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls 101418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // with more than 6 arguments. 10156e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true), 10166e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick DL); 101718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 101818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Collect the set of registers to pass to the function and their values. 101918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // This will be emitted as a sequence of CopyToReg nodes glued to the call 102018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // instruction. 102118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 102218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 102318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Collect chains from all the memory opeations that copy arguments to the 102418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // stack. They must follow the stack pointer adjustment above and precede the 102518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // call instruction itself. 102618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<SDValue, 8> MemOpChains; 102718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 102818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 102918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen const CCValAssign &VA = ArgLocs[i]; 103018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue Arg = CLI.OutVals[i]; 103118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 103218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Promote the value if needed. 103318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen switch (VA.getLocInfo()) { 103418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen default: 103518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen llvm_unreachable("Unknown location info!"); 103618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::Full: 103718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 103818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::SExt: 103918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg); 104018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 104118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::ZExt: 104218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg); 104318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 104418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::AExt: 104518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); 104618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 104718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::BCvt: 104818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg); 104918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 105018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 105118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 105218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.isRegLoc()) { 105318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The custom bit on an i32 return value indicates that it should be 105418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // passed in the high bits of the register. 105518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) { 105618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::SHL, DL, MVT::i64, Arg, 105718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 105818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 105918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The next value may go in the low bits of the same register. 106018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Handle both at once. 106118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (i+1 < ArgLocs.size() && ArgLocs[i+1].isRegLoc() && 106218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen ArgLocs[i+1].getLocReg() == VA.getLocReg()) { 106318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, 106418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CLI.OutVals[i+1]); 106518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::OR, DL, MVT::i64, Arg, NV); 106618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Skip the next value, it's already done. 106718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen ++i; 106818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 106918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 10701b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()), Arg)); 107118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen continue; 107218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 107318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 107418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen assert(VA.isMemLoc()); 107518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 107618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Create a store off the stack pointer for this argument. 107718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy()); 107818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The argument area starts at %fp+BIAS+128 in the callee frame, 107918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // %sp+BIAS+128 in ours. 108018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() + 108118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Subtarget->getStackPointerBias() + 108218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 128); 108318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, PtrOff); 108418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen MemOpChains.push_back(DAG.getStore(Chain, DL, Arg, PtrOff, 108518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen MachinePointerInfo(), 108618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen false, false, 0)); 108718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 108818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 108918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Emit all stores, make sure they occur before the call. 109018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (!MemOpChains.empty()) 109118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, 109218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen &MemOpChains[0], MemOpChains.size()); 109318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 109418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Build a sequence of CopyToReg nodes glued together with token chain and 109518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // glue operands which copy the outgoing args into registers. The InGlue is 109618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // necessary since all emitted instructions must be stuck together in order 109718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // to pass the live physical registers. 109818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue InGlue; 109918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 110018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, 110118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RegsToPass[i].first, RegsToPass[i].second, InGlue); 110218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(1); 110318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 110418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 110518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // If the callee is a GlobalAddress node (quite common, every direct call is) 110618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 110718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Likewise ExternalSymbol -> TargetExternalSymbol. 110818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue Callee = CLI.Callee; 110918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 111018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy()); 111118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 111218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy()); 111318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 111418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Build the operands for the call instruction itself. 111518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<SDValue, 8> Ops; 111618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(Chain); 111718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(Callee); 111818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 111918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(DAG.getRegister(RegsToPass[i].first, 112018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RegsToPass[i].second.getValueType())); 112118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 1122b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen // Add a register mask operand representing the call-preserved registers. 1123b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); 1124b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen const uint32_t *Mask = TRI->getCallPreservedMask(CLI.CallConv); 1125b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen assert(Mask && "Missing call preserved mask for calling convention"); 1126b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen Ops.push_back(DAG.getRegisterMask(Mask)); 1127b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen 112818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Make sure the CopyToReg nodes are glued to the call instruction which 112918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // consumes the registers. 113018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (InGlue.getNode()) 113118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(InGlue); 113218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 113318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Now the call itself. 113418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 113518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, &Ops[0], Ops.size()); 113618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(1); 113718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 113818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Revert the stack pointer immediately after the call. 113918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), 11406e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick DAG.getIntPtrConstant(0, true), InGlue, DL); 114118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(1); 114218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 114318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Now extract the return values. This is more or less the same as 114418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // LowerFormalArguments_64. 114518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 114618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Assign locations to each value returned by this call. 114718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<CCValAssign, 16> RVLocs; 114818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 114918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getTarget(), RVLocs, *DAG.getContext()); 115018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64); 115118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 115218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Copy all of the result registers out of their specified physreg. 115318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0; i != RVLocs.size(); ++i) { 115418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCValAssign &VA = RVLocs[i]; 11551b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen unsigned Reg = toCallerWindow(VA.getLocReg()); 115618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 115718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can 115818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // reside in the same register in the high and low bits. Reuse the 115918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // CopyFromReg previous node to avoid duplicate copies. 116018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue RV; 116118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1))) 116218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg) 116318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = Chain.getValue(0); 116418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 116518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // But usually we'll create a new CopyFromReg for a different register. 116618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (!RV.getNode()) { 116718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue); 116818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = RV.getValue(1); 116918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(2); 117018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 117118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 117218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Get the high bits for i32 struct elements. 117318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 117418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV, 117518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 117618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 117718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The callee promoted the return value, so insert an Assert?ext SDNode so 117818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // we won't promote the value again in this function. 117918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen switch (VA.getLocInfo()) { 118018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::SExt: 118118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV, 118218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 118318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 118418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::ZExt: 118518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV, 118618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 118718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 118818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen default: 118918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 119018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 119118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 119218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Truncate the register down to the return value type. 119318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.isExtInLoc()) 119418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV); 119518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 119618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InVals.push_back(RV); 119718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 119818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 119918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen return Chain; 120018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen} 120118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 12025a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner//===----------------------------------------------------------------------===// 12035a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner// TargetLowering Implementation 12045a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner//===----------------------------------------------------------------------===// 12055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12065a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC 12075a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// condition. 12085a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerstatic SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { 12095a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (CC) { 1210c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown integer condition code!"); 12115a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETEQ: return SPCC::ICC_E; 12125a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETNE: return SPCC::ICC_NE; 12135a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLT: return SPCC::ICC_L; 12145a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGT: return SPCC::ICC_G; 12155a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLE: return SPCC::ICC_LE; 12165a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGE: return SPCC::ICC_GE; 12175a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULT: return SPCC::ICC_CS; 12185a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULE: return SPCC::ICC_LEU; 12195a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGT: return SPCC::ICC_GU; 12205a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGE: return SPCC::ICC_CC; 12215a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 12225a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 12235a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12245a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC 12255a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// FCC condition. 12265a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerstatic SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { 12275a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (CC) { 1228c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown fp condition code!"); 12295a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETEQ: 12305a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOEQ: return SPCC::FCC_E; 12315a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETNE: 12325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUNE: return SPCC::FCC_NE; 12335a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLT: 12345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOLT: return SPCC::FCC_L; 12355a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGT: 12365a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOGT: return SPCC::FCC_G; 12375a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLE: 12385a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOLE: return SPCC::FCC_LE; 12395a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGE: 12405a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOGE: return SPCC::FCC_GE; 12415a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULT: return SPCC::FCC_UL; 12425a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULE: return SPCC::FCC_ULE; 12435a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGT: return SPCC::FCC_UG; 12445a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGE: return SPCC::FCC_UGE; 12455a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUO: return SPCC::FCC_U; 12465a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETO: return SPCC::FCC_O; 12475a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETONE: return SPCC::FCC_LG; 12485a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUEQ: return SPCC::FCC_UE; 12495a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 12505a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 12515a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12525a65b928302494ad2b3051980ce956e8f9e95023Chris LattnerSparcTargetLowering::SparcTargetLowering(TargetMachine &TM) 12535277b22687d3513dd29d5a9c8510cac740f933f6Chris Lattner : TargetLowering(TM, new TargetLoweringObjectFileELF()) { 1254fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen Subtarget = &TM.getSubtarget<SparcSubtarget>(); 125553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 12565a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Set up the register classes. 1257c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper addRegisterClass(MVT::i32, &SP::IntRegsRegClass); 1258c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper addRegisterClass(MVT::f32, &SP::FPRegsRegClass); 1259c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper addRegisterClass(MVT::f64, &SP::DFPRegsRegClass); 1260fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen if (Subtarget->is64Bit()) 1261fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen addRegisterClass(MVT::i64, &SP::I64RegsRegClass); 12625a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12635a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Turn FP extload into load/fextend 1264825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 12655a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc doesn't have i1 sign extending load 1266825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 12675a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Turn FP truncstore into trunc + store. 1268825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::f64, MVT::f32, Expand); 12695a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12705a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Custom legalize GlobalAddress nodes into LO/HI parts. 127141d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen setOperationAction(ISD::GlobalAddress, getPointerTy(), Custom); 127241d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen setOperationAction(ISD::GlobalTLSAddress, getPointerTy(), Custom); 127341d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen setOperationAction(ISD::ConstantPool, getPointerTy(), Custom); 1274e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju setOperationAction(ISD::BlockAddress, getPointerTy(), Custom); 127553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 12765a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc doesn't have sext_inreg, replace them with shl/sra 1277825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 1278825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); 1279825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); 12805a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12815a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc has no REM or DIVREM operations. 1282825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i32, Expand); 1283825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i32, Expand); 1284825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i32, Expand); 1285825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i32, Expand); 12865a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12875a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Custom expand fp<->sint 1288825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 1289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 12905a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 12915a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Expand fp<->uint 1292825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 1293825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 129453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1295bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck setOperationAction(ISD::BITCAST, MVT::f32, Expand); 1296bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck setOperationAction(ISD::BITCAST, MVT::i32, Expand); 129753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 12985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc has no select or setcc: expand to SELECT_CC. 1299825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i32, Expand); 1300825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::f32, Expand); 1301825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::f64, Expand); 1302825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i32, Expand); 1303825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::f32, Expand); 1304825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::f64, Expand); 130553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 13065a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc doesn't have BRCOND either, it has BR_CC. 1307825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1308825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRIND, MVT::Other, Expand); 1309825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 1310825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i32, Custom); 1311825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::f32, Custom); 1312825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::f64, Custom); 131353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1314825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 1315825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 1316825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 131753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 13188534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen if (Subtarget->is64Bit()) { 131989f530ebbfa91d1583a72d86dc6ca2804f4f450dJakob Stoklund Olesen setOperationAction(ISD::BITCAST, MVT::f64, Expand); 132089f530ebbfa91d1583a72d86dc6ca2804f4f450dJakob Stoklund Olesen setOperationAction(ISD::BITCAST, MVT::i64, Expand); 1321900622e099054da4a213074581d8501ac27e7ea7Jakob Stoklund Olesen setOperationAction(ISD::SELECT, MVT::i64, Expand); 1322900622e099054da4a213074581d8501ac27e7ea7Jakob Stoklund Olesen setOperationAction(ISD::SETCC, MVT::i64, Expand); 13238534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen setOperationAction(ISD::BR_CC, MVT::i64, Custom); 13240e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); 13258534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen } 13268534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen 132714648468011c92a4210f8118721d58c25043daf8Eli Friedman // FIXME: There are instructions available for ATOMIC_FENCE 132814648468011c92a4210f8118721d58c25043daf8Eli Friedman // on SparcV8 and later. 132914648468011c92a4210f8118721d58c25043daf8Eli Friedman setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand); 1330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 13311799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju if (!Subtarget->isV9()) { 13321799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // SparcV8 does not have FNEGD and FABSD. 13331799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju setOperationAction(ISD::FNEG, MVT::f64, Custom); 13341799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju setOperationAction(ISD::FABS, MVT::f64, Custom); 13351799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju } 13361799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 1337825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FSIN , MVT::f64, Expand); 1338825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOS , MVT::f64, Expand); 13398688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng setOperationAction(ISD::FSINCOS, MVT::f64, Expand); 1340825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FREM , MVT::f64, Expand); 134133390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich setOperationAction(ISD::FMA , MVT::f64, Expand); 1342825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FSIN , MVT::f32, Expand); 1343825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOS , MVT::f32, Expand); 13448688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng setOperationAction(ISD::FSINCOS, MVT::f32, Expand); 1345825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FREM , MVT::f32, Expand); 134633390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich setOperationAction(ISD::FMA , MVT::f32, Expand); 1347825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i32, Expand); 1348825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ , MVT::i32, Expand); 134963974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand); 1350825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ , MVT::i32, Expand); 135163974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand); 1352825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL , MVT::i32, Expand); 1353825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR , MVT::i32, Expand); 1354825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BSWAP, MVT::i32, Expand); 1355825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); 1356825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); 1357825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FPOW , MVT::f64, Expand); 1358825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FPOW , MVT::f32, Expand); 1359825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1360825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 1361825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 1362825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 13635a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13645a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // FIXME: Sparc provides these multiplies, but we don't have them yet. 1365825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); 1366825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 136753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1368825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); 13695a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13705a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // VASTART needs to be custom lowered to use the VarArgsFrameIndex. 1371825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VASTART , MVT::Other, Custom); 13725a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // VAARG needs to be lowered to not do unaligned accesses for doubles. 1373825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VAARG , MVT::Other, Custom); 137453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 13755a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Use the default implementation. 1376825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VACOPY , MVT::Other, Expand); 1377825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VAEND , MVT::Other, Expand); 1378825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); 1379825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); 1380825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom); 13815a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13825a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // No debug info support yet. 1383825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); 138453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 13855a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner setStackPointerRegisterToSaveRestore(SP::O6); 13865a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13871799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju if (Subtarget->isV9()) 1388825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i32, Legal); 138953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1390fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(2); 1391fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 13925a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner computeRegisterProperties(); 13935a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 13945a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13955a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerconst char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const { 13965a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (Opcode) { 13975a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner default: return 0; 13985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::CMPICC: return "SPISD::CMPICC"; 13995a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::CMPFCC: return "SPISD::CMPFCC"; 14005a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::BRICC: return "SPISD::BRICC"; 14018534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen case SPISD::BRXCC: return "SPISD::BRXCC"; 14025a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::BRFCC: return "SPISD::BRFCC"; 14035a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC"; 14040e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC"; 14055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC"; 14065a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::Hi: return "SPISD::Hi"; 14075a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::Lo: return "SPISD::Lo"; 14085a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::FTOI: return "SPISD::FTOI"; 14095a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::ITOF: return "SPISD::ITOF"; 14105a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::CALL: return "SPISD::CALL"; 14115a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::RET_FLAG: return "SPISD::RET_FLAG"; 1412860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG"; 1413fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju case SPISD::FLUSHW: return "SPISD::FLUSHW"; 14145a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 14155a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 14165a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 14175a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to 14185a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// be zero. Op is expected to be a target specific node. Used by DAG 14195a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// combiner. 14201e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindarajuvoid SparcTargetLowering::computeMaskedBitsForTargetNode 14211e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju (const SDValue Op, 14221e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju APInt &KnownZero, 14231e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju APInt &KnownOne, 14241e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju const SelectionDAG &DAG, 14251e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju unsigned Depth) const { 14265a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner APInt KnownZero2, KnownOne2; 142726c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0); 142853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 14295a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (Op.getOpcode()) { 14305a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner default: break; 14315a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_ICC: 14320e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen case SPISD::SELECT_XCC: 14335a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_FCC: 143426c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola DAG.ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); 143526c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola DAG.ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); 143653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); 143753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); 143853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 14395a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Only known if known in both the LHS and RHS. 14405a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner KnownOne &= KnownOne2; 14415a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner KnownZero &= KnownZero2; 14425a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner break; 14435a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 14445a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 14455a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 1446d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so 1447d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition. 1448475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic void LookThroughSetCC(SDValue &LHS, SDValue &RHS, 1449d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ISD::CondCode CC, unsigned &SPCC) { 1450f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman if (isa<ConstantSDNode>(RHS) && 1451e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman cast<ConstantSDNode>(RHS)->isNullValue() && 145253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov CC == ISD::SETNE && 14530e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen (((LHS.getOpcode() == SPISD::SELECT_ICC || 14540e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen LHS.getOpcode() == SPISD::SELECT_XCC) && 1455d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LHS.getOperand(3).getOpcode() == SPISD::CMPICC) || 1456d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner (LHS.getOpcode() == SPISD::SELECT_FCC && 1457d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) && 1458d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner isa<ConstantSDNode>(LHS.getOperand(0)) && 1459d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner isa<ConstantSDNode>(LHS.getOperand(1)) && 1460e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman cast<ConstantSDNode>(LHS.getOperand(0))->isOne() && 1461e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) { 1462475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CMPCC = LHS.getOperand(3); 1463f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue(); 1464d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LHS = CMPCC.getOperand(0); 1465d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner RHS = CMPCC.getOperand(1); 1466d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 1467d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1468d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 14690ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Convert to a target node and set target flags. 14700ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund OlesenSDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF, 14710ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SelectionDAG &DAG) const { 14720ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) 14730ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen return DAG.getTargetGlobalAddress(GA->getGlobal(), 1474ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc(GA), 14750ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen GA->getValueType(0), 14760ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen GA->getOffset(), TF); 147726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 147826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) 147926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return DAG.getTargetConstantPool(CP->getConstVal(), 148026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen CP->getValueType(0), 148126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen CP->getAlignment(), 148226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen CP->getOffset(), TF); 148326932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 1484e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) 1485e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju return DAG.getTargetBlockAddress(BA->getBlockAddress(), 1486e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju Op.getValueType(), 1487e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju 0, 1488e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju TF); 1489e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju 149026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) 149126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return DAG.getTargetExternalSymbol(ES->getSymbol(), 149226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen ES->getValueType(0), TF); 149326932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 14940ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen llvm_unreachable("Unhandled address SDNode"); 14950ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen} 14960ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen 14970ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Split Op into high and low parts according to HiTF and LoTF. 14980ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Return an ADD node combining the parts. 14990ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund OlesenSDValue SparcTargetLowering::makeHiLoPair(SDValue Op, 15000ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen unsigned HiTF, unsigned LoTF, 15010ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SelectionDAG &DAG) const { 1502ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 15030ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen EVT VT = Op.getValueType(); 15040ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG)); 15050ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG)); 15060ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 15070ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen} 15080ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen 150926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen// Build SDNodes for producing an address from a GlobalAddress, ConstantPool, 151026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen// or ExternalSymbol SDNode. 151126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund OlesenSDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { 1512ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 151387ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen EVT VT = getPointerTy(); 151487ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen 151526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen // Handle PIC mode first. 151626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { 151726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen // This is the pic32 code model, the GOT is known to be smaller than 4GB. 151826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); 151926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT); 152026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); 152126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr, 152226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen MachinePointerInfo::getGOT(), false, false, false, 0); 152326932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen } 152426932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 152526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen // This is one of the absolute code models. 152687ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen switch(getTargetMachine().getCodeModel()) { 152787ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen default: 152887ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen llvm_unreachable("Unsupported absolute code model"); 152987ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen case CodeModel::Small: 1530618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen // abs32. 153187ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen return makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); 153287ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen case CodeModel::Medium: { 1533618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen // abs44. 153487ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen SDValue H44 = makeHiLoPair(Op, SPII::MO_H44, SPII::MO_M44, DAG); 1535d9f88da7b329c54ccb0d2ebd3b3a4b0e4b1e2b06Jakob Stoklund Olesen H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getConstant(12, MVT::i32)); 153687ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen SDValue L44 = withTargetFlags(Op, SPII::MO_L44, DAG); 153787ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen L44 = DAG.getNode(SPISD::Lo, DL, VT, L44); 153887ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen return DAG.getNode(ISD::ADD, DL, VT, H44, L44); 153987ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen } 1540618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen case CodeModel::Large: { 1541618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen // abs64. 1542618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen SDValue Hi = makeHiLoPair(Op, SPII::MO_HH, SPII::MO_HM, DAG); 1543d9f88da7b329c54ccb0d2ebd3b3a4b0e4b1e2b06Jakob Stoklund Olesen Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(32, MVT::i32)); 1544618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen SDValue Lo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); 1545618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 1546618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen } 154787ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen } 154826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen} 154926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 1550bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op, 1551d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 155226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return makeAddress(Op, DAG); 1553d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1554d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1555db486a6d5311944f61b92db9f6074944dbbdb242Chris LattnerSDValue SparcTargetLowering::LowerConstantPool(SDValue Op, 1556d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 155726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return makeAddress(Op, DAG); 1558d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1559d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1560e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman GovindarajuSDValue SparcTargetLowering::LowerBlockAddress(SDValue Op, 1561e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju SelectionDAG &DAG) const { 1562e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju return makeAddress(Op, DAG); 1563e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju} 1564e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju 1565475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) { 1566ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1567d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Convert the fp value to integer in an FP register. 1568825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(Op.getValueType() == MVT::i32); 1569825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0)); 1570bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op); 1571d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1572d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1573475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) { 1574ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1575825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(Op.getOperand(0).getValueType() == MVT::i32); 1576bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Op.getOperand(0)); 1577d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Convert the int value to FP in an FP register. 1578b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen return DAG.getNode(SPISD::ITOF, dl, Op.getValueType(), Tmp); 1579d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1580d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1581475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) { 1582475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = Op.getOperand(0); 1583d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 1584475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LHS = Op.getOperand(2); 1585475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue RHS = Op.getOperand(3); 1586475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Dest = Op.getOperand(4); 1587ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1588d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned Opc, SPCC = ~0U; 158953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1590d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // If this is a br_cc of a "setcc", and if the setcc got lowered into 1591d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. 1592d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LookThroughSetCC(LHS, RHS, CC, SPCC); 159353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1594d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Get the condition flag. 1595475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CompareFlag; 15968534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen if (LHS.getValueType().isInteger()) { 159701021a8b93989a3c9e17dea540fe66809bf25403Venkatraman Govindaraju CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS); 1598d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); 15998534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen // 32-bit compares use the icc flags, 64-bit uses the xcc flags. 16008534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC; 1601d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } else { 1602f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS); 1603d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); 1604d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner Opc = SPISD::BRFCC; 1605d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 1606825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest, 1607825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getConstant(SPCC, MVT::i32), CompareFlag); 1608d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1609d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1610475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { 1611475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LHS = Op.getOperand(0); 1612475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue RHS = Op.getOperand(1); 1613d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 1614475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue TrueVal = Op.getOperand(2); 1615475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FalseVal = Op.getOperand(3); 1616ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1617d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned Opc, SPCC = ~0U; 161853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1619d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // If this is a select_cc of a "setcc", and if the setcc got lowered into 1620d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. 1621d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LookThroughSetCC(LHS, RHS, CC, SPCC); 162253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1623475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CompareFlag; 16240e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen if (LHS.getValueType().isInteger()) { 162501021a8b93989a3c9e17dea540fe66809bf25403Venkatraman Govindaraju CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS); 16260e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen Opc = LHS.getValueType() == MVT::i32 ? 16270e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen SPISD::SELECT_ICC : SPISD::SELECT_XCC; 1628d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); 1629d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } else { 1630f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS); 1631d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner Opc = SPISD::SELECT_FCC; 1632d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); 1633d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 16343484c09e0da3c05c8a78946e090c7610208d937bDale Johannesen return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal, 1635825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getConstant(SPCC, MVT::i32), CompareFlag); 1636d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1637d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1638475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, 1639d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const SparcTargetLowering &TLI) { 16401e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman MachineFunction &MF = DAG.getMachineFunction(); 16411e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 16421e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman 16431e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Need frame address to find the address of VarArgsFrameIndex. 1644a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju MF.getFrameInfo()->setFrameAddressIsTaken(true); 1645a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju 1646d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // vastart just stores the address of the VarArgsFrameIndex slot into the 1647d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // memory location argument. 1648ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16491e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SDValue Offset = 1650da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getNode(ISD::ADD, DL, TLI.getPointerTy(), 1651da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getRegister(SP::I6, TLI.getPointerTy()), 1652da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset())); 1653d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 1654da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1), 16556229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(SV), false, false, 0); 1656d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1657d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1658475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) { 1659ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *Node = Op.getNode(); 1660e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 1661475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InChain = Node->getOperand(0); 1662475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue VAListPtr = Node->getOperand(1); 1663da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen EVT PtrVT = VAListPtr.getValueType(); 1664d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 1665ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 1666da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SDValue VAList = DAG.getLoad(PtrVT, DL, InChain, VAListPtr, 1667d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(SV), false, false, false, 0); 1668da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Increment the pointer, VAList, to the next vaarg. 1669da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SDValue NextPtr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 1670da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getIntPtrConstant(VT.getSizeInBits()/8)); 1671da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Store the incremented VAList to the legalized pointer. 1672da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen InChain = DAG.getStore(VAList.getValue(1), DL, NextPtr, 16736229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner VAListPtr, MachinePointerInfo(SV), false, false, 0); 1674da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Load the actual argument out of the pointer VAList. 1675da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // We can't count on greater alignment than the word size. 1676da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen return DAG.getLoad(VT, DL, InChain, VAList, MachinePointerInfo(), 1677da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen false, false, false, 1678da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen std::min(PtrVT.getSizeInBits(), VT.getSizeInBits())/8); 1679d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1680d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1681475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) { 1682475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = Op.getOperand(0); // Legalize the chain. 1683475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Size = Op.getOperand(1); // Legalize the size. 1684ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 168553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1686d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned SPReg = SP::O6; 1687825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, MVT::i32); 1688825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue NewSP = DAG.getNode(ISD::SUB, dl, MVT::i32, SP, Size); // Value 1689a05dca4f9e051fad19fe9b5f6cce2715c1e5d505Dale Johannesen Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP); // Output chain 169053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1691d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // The resultant pointer is actually 16 words from the bottom of the stack, 1692d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // to provide a register spill area. 1693825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue NewVal = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP, 1694825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getConstant(96, MVT::i32)); 1695475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[2] = { NewVal, Chain }; 1696a05dca4f9e051fad19fe9b5f6cce2715c1e5d505Dale Johannesen return DAG.getMergeValues(Ops, 2, dl); 1697d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1698d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1699d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1700fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindarajustatic SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) { 1701ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1702fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju SDValue Chain = DAG.getNode(SPISD::FLUSHW, 1703860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju dl, MVT::Other, DAG.getEntryNode()); 1704860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju return Chain; 1705860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju} 1706860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 1707860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindarajustatic SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 1708860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 1709860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju MFI->setFrameAddressIsTaken(true); 1710860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 1711860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju EVT VT = Op.getValueType(); 1712ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1713860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju unsigned FrameReg = SP::I6; 1714860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 1715860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju uint64_t depth = Op.getConstantOperandVal(0); 1716860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 1717860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju SDValue FrameAddr; 1718fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju if (depth == 0) 1719860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 1720860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju else { 1721860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju // flush first to make sure the windowed registers' values are in stack 1722fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju SDValue Chain = getFLUSHW(Op, DAG); 1723860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); 1724fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju 1725860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju for (uint64_t i = 0; i != depth; ++i) { 1726fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju SDValue Ptr = DAG.getNode(ISD::ADD, 1727860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju dl, MVT::i32, 1728860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju FrameAddr, DAG.getIntPtrConstant(56)); 1729fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju FrameAddr = DAG.getLoad(MVT::i32, dl, 1730fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju Chain, 1731860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju Ptr, 1732d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 1733860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju } 1734860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju } 1735860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju return FrameAddr; 1736860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju} 1737860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 17388717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindarajustatic SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, 17398717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju const SparcTargetLowering &TLI) { 17408717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju MachineFunction &MF = DAG.getMachineFunction(); 17418717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju MachineFrameInfo *MFI = MF.getFrameInfo(); 1742860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju MFI->setReturnAddressIsTaken(true); 1743860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 1744860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju EVT VT = Op.getValueType(); 1745ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1746860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju uint64_t depth = Op.getConstantOperandVal(0); 1747860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 1748860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju SDValue RetAddr; 17498717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju if (depth == 0) { 17508717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju unsigned RetReg = MF.addLiveIn(SP::I7, 17518717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju TLI.getRegClassFor(TLI.getPointerTy())); 1752860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT); 17538717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju } else { 17541e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Need frame address to find return address of the caller. 1755a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju MFI->setFrameAddressIsTaken(true); 1756a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju 1757860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju // flush first to make sure the windowed registers' values are in stack 1758fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju SDValue Chain = getFLUSHW(Op, DAG); 1759860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT); 1760fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju 1761860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju for (uint64_t i = 0; i != depth; ++i) { 1762fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju SDValue Ptr = DAG.getNode(ISD::ADD, 1763860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju dl, MVT::i32, 1764fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju RetAddr, 1765860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju DAG.getIntPtrConstant((i == depth-1)?60:56)); 1766fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju RetAddr = DAG.getLoad(MVT::i32, dl, 1767fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju Chain, 1768860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju Ptr, 1769d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 1770860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju } 1771860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju } 1772860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju return RetAddr; 1773860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju} 1774860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 17751799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindarajustatic SDValue LowerF64Op(SDValue Op, SelectionDAG &DAG) 17761799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju{ 17771799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDLoc dl(Op); 17781799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 17791799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju assert(Op.getValueType() == MVT::f64 && "LowerF64Op called on non-double!"); 17801799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju assert(Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS); 17811799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 17821799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // Lower fneg/fabs on f64 to fneg/fabs on f32. 17831799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // fneg f64 => fneg f32:sub_even, fmov f32:sub_odd. 17841799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // fabs f64 => fabs f32:sub_even, fmov f32:sub_odd. 17851799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 17861799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue SrcReg64 = Op.getOperand(0); 17871799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue Hi32 = DAG.getTargetExtractSubreg(SP::sub_even, dl, MVT::f32, 17881799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SrcReg64); 17891799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue Lo32 = DAG.getTargetExtractSubreg(SP::sub_odd, dl, MVT::f32, 17901799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SrcReg64); 17911799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 17921799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju Hi32 = DAG.getNode(Op.getOpcode(), dl, MVT::f32, Hi32); 17931799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 17941799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue DstReg64 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, 17951799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju dl, MVT::f64), 0); 17961799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64 = DAG.getTargetInsertSubreg(SP::sub_even, dl, MVT::f64, 17971799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64, Hi32); 17981799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64 = DAG.getTargetInsertSubreg(SP::sub_odd, dl, MVT::f64, 17991799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64, Lo32); 18001799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju return DstReg64; 18011799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju} 18021799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 1803475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SparcTargetLowering:: 1804d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerOperation(SDValue Op, SelectionDAG &DAG) const { 1805d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner switch (Op.getOpcode()) { 1806c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Should not custom lower this!"); 18071799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 18081799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju case ISD::FNEG: 18091799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju case ISD::FABS: return LowerF64Op(Op, DAG); 18101799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 18118717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this); 1812860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 1813d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::GlobalTLSAddress: 1814c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("TLS not implemented for Sparc."); 1815db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 1816e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 1817db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 1818d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); 1819d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); 1820d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1821d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 1822d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::VASTART: return LowerVASTART(Op, DAG, *this); 1823d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::VAARG: return LowerVAARG(Op, DAG); 1824d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); 1825d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 1826d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1827d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1828d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris LattnerMachineBasicBlock * 1829d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris LattnerSparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1830af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 1831d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 1832d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned BROpcode; 1833d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned CC; 1834d552eee4a05789e80ef3298df473edb888471302Dale Johannesen DebugLoc dl = MI->getDebugLoc(); 1835d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Figure out the conditional branch opcode to use for this select_cc. 1836d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner switch (MI->getOpcode()) { 1837c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown SELECT_CC!"); 1838d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_Int_ICC: 1839d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_FP_ICC: 1840d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_DFP_ICC: 1841d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BROpcode = SP::BCOND; 1842d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner break; 1843d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_Int_FCC: 1844d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_FP_FCC: 1845d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_DFP_FCC: 1846d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BROpcode = SP::FBCOND; 1847d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner break; 1848d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 1849d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1850d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner CC = (SPCC::CondCodes)MI->getOperand(3).getImm(); 185153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1852d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 1853d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // control-flow pattern. The incoming instruction knows the destination vreg 1854d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // to set, the condition code register to branch on, the true/false values to 1855d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // select between, and a branch opcode to use. 1856d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const BasicBlock *LLVM_BB = BB->getBasicBlock(); 18578e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineFunction::iterator It = BB; 1858d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ++It; 185953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1860d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // thisMBB: 1861d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // ... 1862d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // TrueVal = ... 1863d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // [f]bCC copy1MBB 1864d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // fallthrough --> copy0MBB 1865d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineBasicBlock *thisMBB = BB; 1866d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineFunction *F = BB->getParent(); 18678e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 18688e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 1869f661277a9b26590648aca585c0572f200470290dVenkatraman Govindaraju F->insert(It, copy0MBB); 1870f661277a9b26590648aca585c0572f200470290dVenkatraman Govindaraju F->insert(It, sinkMBB); 187114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 187214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman // Transfer the remainder of BB and its successor edges to sinkMBB. 187314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman sinkMBB->splice(sinkMBB->begin(), BB, 187414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 187514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 187614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 187714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 187814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman // Add the true and fallthrough blocks as its successors. 187914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->addSuccessor(copy0MBB); 188014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->addSuccessor(sinkMBB); 188114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 1882d552eee4a05789e80ef3298df473edb888471302Dale Johannesen BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC); 188353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1884d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // copy0MBB: 1885d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // %FalseValue = ... 1886d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // # fallthrough to sinkMBB 1887d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BB = copy0MBB; 188853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1889d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Update machine-CFG edges 1890d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BB->addSuccessor(sinkMBB); 189153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1892d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // sinkMBB: 1893d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 1894d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // ... 1895d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BB = sinkMBB; 189614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(SP::PHI), MI->getOperand(0).getReg()) 1897d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 1898d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 189953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 190014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 1901d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner return BB; 1902d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 19030eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 19040eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//===----------------------------------------------------------------------===// 19050eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov// Sparc Inline Assembly Support 19060eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//===----------------------------------------------------------------------===// 19070eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 19080eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 19090eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov/// constraint it is for this target. 19100eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::ConstraintType 19110eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::getConstraintType(const std::string &Constraint) const { 19120eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov if (Constraint.size() == 1) { 19130eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov switch (Constraint[0]) { 19140eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov default: break; 19150eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov case 'r': return C_RegisterClass; 19160eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 19170eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 19180eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 19190eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 19200eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov} 19210eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 19220eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 19230eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, 19245b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier MVT VT) const { 19250eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov if (Constraint.size() == 1) { 19260eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov switch (Constraint[0]) { 19270eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov case 'r': 1928c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper return std::make_pair(0U, &SP::IntRegsRegClass); 19290eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 19300eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 19310eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 19320eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 19330eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov} 19340eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 19356520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohmanbool 19366520e20e4fb31f2e65e25c38b372b19d33a83df4Dan GohmanSparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { 19376520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman // The Sparc target isn't yet aware of offsets. 19386520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman return false; 19396520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman} 1940