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" 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/SparcMCExpr.h" 171e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman#include "SparcMachineFunctionInfo.h" 181b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju#include "SparcRegisterInfo.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "SparcTargetMachine.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "SparcTargetObjectFile.h" 215a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner#include "llvm/CodeGen/CallingConvLower.h" 22d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 23d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineFunction.h" 24d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineInstrBuilder.h" 25d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h" 26d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/SelectionDAG.h" 27362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 31c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 32d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattnerusing namespace llvm; 33d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 35d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===// 365a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner// Calling Convention Implementation 37d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===// 38d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 398184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindarajustatic bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT, 408184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MVT &LocVT, CCValAssign::LocInfo &LocInfo, 418184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju ISD::ArgFlagsTy &ArgFlags, CCState &State) 428184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju{ 438184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju assert (ArgFlags.isSRet()); 448184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 451e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Assign SRet argument. 468184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 478184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 0, 488184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju LocVT, LocInfo)); 498184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju return true; 508184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju} 518184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 52687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindarajustatic bool CC_Sparc_Assign_f64(unsigned &ValNo, MVT &ValVT, 53687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MVT &LocVT, CCValAssign::LocInfo &LocInfo, 54687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ISD::ArgFlagsTy &ArgFlags, CCState &State) 55687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju{ 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const MCPhysReg RegList[] = { 57687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 58687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju }; 591e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Try to get first reg. 60687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (unsigned Reg = State.AllocateReg(RegList, 6)) { 61687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 62687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 631e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Assign whole thing in stack. 64687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 65687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.AllocateStack(8,4), 66687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LocVT, LocInfo)); 67687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju return true; 68687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 69687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 701e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Try to get second reg. 71687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (unsigned Reg = State.AllocateReg(RegList, 6)) 72687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 73687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju else 74687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 75687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju State.AllocateStack(4,4), 76687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LocVT, LocInfo)); 77687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju return true; 78687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju} 79687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 801f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// Allocate a full-sized argument for the 64-bit ABI. 811f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesenstatic bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, 821f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen MVT &LocVT, CCValAssign::LocInfo &LocInfo, 831f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen ISD::ArgFlagsTy &ArgFlags, CCState &State) { 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((LocVT == MVT::f32 || LocVT == MVT::f128 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines || LocVT.getSizeInBits() == 64) && 861f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen "Can't handle non-64 bits locations"); 871f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 881f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Stack space is allocated for all arguments starting from [%fp+BIAS+128]. 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned size = (LocVT == MVT::f128) ? 16 : 8; 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned alignment = (LocVT == MVT::f128) ? 16 : 8; 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = State.AllocateStack(size, alignment); 921f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Reg = 0; 931f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 941f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::i64 && Offset < 6*8) 951f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote integers to %i0-%i5. 961f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Reg = SP::I0 + Offset/8; 971f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen else if (LocVT == MVT::f64 && Offset < 16*8) 981f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote doubles to %d0-%d30. (Which LLVM calls D0-D15). 991f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Reg = SP::D0 + Offset/8; 1001f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen else if (LocVT == MVT::f32 && Offset < 16*8) 1011f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote floats to %f1, %f3, ... 1021f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Reg = SP::F1 + Offset/4; 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (LocVT == MVT::f128 && Offset < 16*8) 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Promote long doubles to %q0-%q28. (Which LLVM calls Q0-Q7). 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg = SP::Q0 + Offset/16; 1061f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1071f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote to register when possible, otherwise use the stack slot. 1081f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (Reg) { 1091f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 1101f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1111f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen } 1121f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1131f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // This argument goes on the stack in an 8-byte slot. 1141f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to 1151f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // the right-aligned float. The first 4 bytes of the stack slot are undefined. 1161f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::f32) 1171f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Offset += 4; 1181f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1191f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 1201f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1211f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen} 1221f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1231f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// Allocate a half-sized argument for the 64-bit ABI. 1241f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// 1251f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// This is used when passing { float, int } structs by value in registers. 1261f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesenstatic bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, 1271f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen MVT &LocVT, CCValAssign::LocInfo &LocInfo, 1281f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen ISD::ArgFlagsTy &ArgFlags, CCState &State) { 1291f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations"); 1301f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Offset = State.AllocateStack(4, 4); 1311f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1321f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::f32 && Offset < 16*8) { 1331f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote floats to %f0-%f31. 1341f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getReg(ValNo, ValVT, SP::F0 + Offset/4, 1351f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocVT, LocInfo)); 1361f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1371f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen } 1381f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1391f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (LocVT == MVT::i32 && Offset < 6*8) { 1401f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Promote integers to %i0-%i5, using half the register. 1411f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned Reg = SP::I0 + Offset/8; 1421f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocVT = MVT::i64; 1431f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocInfo = CCValAssign::AExt; 1441f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1451f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Set the Custom bit if this i32 goes in the high bits of a register. 1461f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (Offset % 8 == 0) 1471f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, 1481f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen LocVT, LocInfo)); 1491f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen else 1501f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 1511f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1521f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen } 1531f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1541f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 1551f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen return true; 1561f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen} 1571f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 1585a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner#include "SparcGenCallingConv.inc" 159d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1601b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// The calling conventions in SparcCallingConv.td are described in terms of the 1611b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// callee's register window. This function translates registers to the 1621b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// corresponding caller window %o register. 1631b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesenstatic unsigned toCallerWindow(unsigned Reg) { 1641b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen assert(SP::I0 + 7 == SP::I7 && SP::O0 + 7 == SP::O7 && "Unexpected enum"); 1651b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen if (Reg >= SP::I0 && Reg <= SP::I7) 1661b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen return Reg - SP::I0 + SP::O0; 1671b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen return Reg; 1681b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen} 1691b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen 17098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 17198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSparcTargetLowering::LowerReturn(SDValue Chain, 17253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CallingConv::ID CallConv, bool IsVarArg, 17398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 174c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 175ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 17653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (Subtarget->is64Bit()) 17753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen return LowerReturn_64(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG); 17853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen return LowerReturn_32(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG); 17953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen} 18098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 18153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSDValue 18253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSparcTargetLowering::LowerReturn_32(SDValue Chain, 18353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CallingConv::ID CallConv, bool IsVarArg, 18453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<ISD::OutputArg> &Outs, 18553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<SDValue> &OutVals, 186ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 1878184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MachineFunction &MF = DAG.getMachineFunction(); 1888184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 1895a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // CCValAssign - represent the assignment of the return value to locations. 1905a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner SmallVector<CCValAssign, 16> RVLocs; 19153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1925a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // CCState - Info about the registers and stack slot. 19353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), 19456cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling DAG.getTarget(), RVLocs, *DAG.getContext()); 19553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 19653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Analyze return values. 19753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32); 19853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 199475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Flag; 200067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 201067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen // Make room for the return address offset. 202067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(SDValue()); 203d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2045a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Copy the result values into the output registers. 2055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner for (unsigned i = 0; i != RVLocs.size(); ++i) { 2065a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner CCValAssign &VA = RVLocs[i]; 2075a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner assert(VA.isRegLoc() && "Can only return in registers!"); 20853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 20953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), 210c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 21153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2125a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Guarantee that all emitted copies are stuck together with flags. 2135a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner Flag = Chain.getValue(1); 214067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 215d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 21658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 2171e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju unsigned RetAddrOffset = 8; // Call Inst + Delay Slot 2188184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju // If the function returns a struct, copy the SRetReturnReg to I0 2198184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (MF.getFunction()->hasStructRetAttr()) { 2208184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>(); 2218184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju unsigned Reg = SFI->getSRetReturnReg(); 2228184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (!Reg) 2238184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju llvm_unreachable("sret virtual register not created in the entry block"); 22453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy()); 22553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Flag); 2268184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju Flag = Chain.getValue(1); 227067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(DAG.getRegister(SP::I0, getPointerTy())); 22858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju RetAddrOffset = 12; // CallInst + Delay Slot + Unimp 2298184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 23053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 231067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 232067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps[1] = DAG.getConstant(RetAddrOffset, MVT::i32); 23358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 234067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen // Add the flag if we have it. 235ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Flag.getNode()) 236067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen RetOps.push_back(Flag); 237067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen 238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, RetOps); 23953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen} 24053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 24153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen// Lower return values for the 64-bit ABI. 24253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen// Return values are passed the exactly the same way as function arguments. 24353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSDValue 24453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSparcTargetLowering::LowerReturn_64(SDValue Chain, 24553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CallingConv::ID CallConv, bool IsVarArg, 24653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<ISD::OutputArg> &Outs, 24753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen const SmallVectorImpl<SDValue> &OutVals, 248ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 24953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // CCValAssign - represent the assignment of the return value to locations. 25053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SmallVector<CCValAssign, 16> RVLocs; 25153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 25253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // CCState - Info about the registers and stack slot. 25353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), 25453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen DAG.getTarget(), RVLocs, *DAG.getContext()); 25553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 25653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Analyze return values. 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CCInfo.AnalyzeReturn(Outs, RetCC_Sparc64); 25853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 25953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue Flag; 26053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 26153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 26253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The second operand on the return instruction is the return address offset. 26353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The return address is always %i7+8 with the 64-bit ABI. 26453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps.push_back(DAG.getConstant(8, MVT::i32)); 26553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 26653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Copy the result values into the output registers. 26753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen for (unsigned i = 0; i != RVLocs.size(); ++i) { 26853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen CCValAssign &VA = RVLocs[i]; 26953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen assert(VA.isRegLoc() && "Can only return in registers!"); 27053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue OutVal = OutVals[i]; 27153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 27253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Integer return values must be sign or zero extended by the callee. 27353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen switch (VA.getLocInfo()) { 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case CCValAssign::Full: break; 27553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen case CCValAssign::SExt: 27653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); 27753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen break; 27853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen case CCValAssign::ZExt: 27953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal); 28053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen break; 28153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen case CCValAssign::AExt: 28253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); 28353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen break; 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unknown loc info!"); 28653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 28753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 28853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The custom bit on an i32 return value indicates that it should be passed 28953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // in the high bits of the register. 29053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) { 29153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal, 29253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 29353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 29453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // The next value may go in the low bits of the same register. 29553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Handle both at once. 29653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) { 29753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]); 29853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV); 29953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Skip the next value, it's already done. 30053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen ++i; 30153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 30253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 30353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 30453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag); 30553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 30653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Guarantee that all emitted copies are stuck together with flags. 30753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen Flag = Chain.getValue(1); 30853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 30953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen } 31053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 31153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 31253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 31353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen // Add the flag if we have it. 31453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen if (Flag.getNode()) 31553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen RetOps.push_back(Flag); 31653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen 317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, RetOps); 318d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 319d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 320f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering:: 321f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments(SDValue Chain, 322f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CallingConv::ID CallConv, 323f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen bool IsVarArg, 324f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen const SmallVectorImpl<ISD::InputArg> &Ins, 325ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, 326f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SelectionDAG &DAG, 327f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 328f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen if (Subtarget->is64Bit()) 329f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins, 330f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DL, DAG, InVals); 331f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins, 332f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DL, DAG, InVals); 333f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen} 334f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 335f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are 33698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// passed in either one or two GPRs, including FP values. TODO: we should 33798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// pass FP values in FP registers for fastcc functions. 338f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering:: 339f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments_32(SDValue Chain, 340f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CallingConv::ID CallConv, 341f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen bool isVarArg, 342f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen const SmallVectorImpl<ISD::InputArg> &Ins, 343ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 344f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SelectionDAG &DAG, 345f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 346d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineFunction &MF = DAG.getMachineFunction(); 347d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineRegisterInfo &RegInfo = MF.getRegInfo(); 3481e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 349a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman 350a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman // Assign locations to all of the incoming arguments. 351a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman SmallVector<CCValAssign, 16> ArgLocs; 352471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 35356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 35498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32); 35553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 356687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju const unsigned StackOffset = 92; 35753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned InIdx = 0; 359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i, ++InIdx) { 360a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman CCValAssign &VA = ArgLocs[i]; 36153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Ins[InIdx].Flags.isSRet()) { 363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (InIdx != 0) 364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines report_fatal_error("sparc only supports sret on the first parameter"); 3651e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Get SRet from [%fp+64]. 3668184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true); 3678184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 3688184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, 3698184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MachinePointerInfo(), 370d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 3718184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju InVals.push_back(Arg); 3728184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju continue; 3738184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 3748184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 375687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isRegLoc()) { 376687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.needsCustom()) { 377687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.getLocVT() == MVT::f64); 378687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 379687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi); 380687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32); 381d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 382687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(i+1 < e); 383687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju CCValAssign &NextVA = ArgLocs[++i]; 38453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 385475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LoVal; 386687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (NextVA.isMemLoc()) { 387687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FrameIdx = MF.getFrameInfo()-> 388687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true); 389825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 390687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, 391687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 392d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 393687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 394687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned loReg = MF.addLiveIn(NextVA.getLocReg(), 39568e6beeccc0b9ac2e8d3687a8a5b7d4b172edca1Devang Patel &SP::IntRegsRegClass); 396687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32); 397d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 39853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov SDValue WholeValue = 399825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); 400687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue); 401687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(WholeValue); 402687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 403687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 404687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 405687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg); 406687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 407687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.getLocVT() == MVT::f32) 408687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg); 409687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju else if (VA.getLocVT() != MVT::i32) { 410687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg, 411687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju DAG.getValueType(VA.getLocVT())); 412687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg); 413687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 414687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(Arg); 415687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 416687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 41753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 418687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.isMemLoc()); 41953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 420687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = VA.getLocMemOffset()+StackOffset; 421687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 422687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.needsCustom()) { 423687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.getValVT() == MVT::f64); 4241e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // If it is double-word aligned, just load. 425687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (Offset % 8 == 0) { 426687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI = MF.getFrameInfo()->CreateFixedObject(8, 427687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset, 428687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 429687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 430687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, 431687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 432d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false,false, false, 0); 433687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(Load); 434687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 435d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 436687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 437687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI = MF.getFrameInfo()->CreateFixedObject(4, 438687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset, 439687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 440687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 441687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, 442687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 443d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 444687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI2 = MF.getFrameInfo()->CreateFixedObject(4, 445687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset+4, 446687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 447687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr2 = DAG.getFrameIndex(FI2, getPointerTy()); 448687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 449687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr2, 450687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 451d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 452687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 453687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue WholeValue = 454687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); 455687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue); 456687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(WholeValue); 457687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 458d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 459687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 460687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju int FI = MF.getFrameInfo()->CreateFixedObject(4, 461687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Offset, 462687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju true); 463687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 464687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Load ; 465687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) { 466687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, 467687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 468d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 469687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 470687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ISD::LoadExtType LoadOp = ISD::SEXTLOAD; 471687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Sparc is big endian, so add an offset based on the ObjectVT. 472687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = 4-std::max(1U, VA.getValVT().getSizeInBits()/8); 473687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr, 474687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju DAG.getConstant(Offset, MVT::i32)); 475a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr, 476687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 477687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju VA.getValVT(), false, false,0); 478687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Load = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Load); 479687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 480687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju InVals.push_back(Load); 481d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 48253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 4838184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (MF.getFunction()->hasStructRetAttr()) { 4841e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Copy the SRet Argument to SRetReturnReg. 4858184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>(); 4868184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju unsigned Reg = SFI->getSRetReturnReg(); 4878184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (!Reg) { 4888184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass); 4898184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SFI->setSRetReturnReg(Reg); 4908184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 4918184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]); 4928184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); 4938184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 4948184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 495d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Store remaining ArgRegs to the stack if this is a varargs function. 496a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman if (isVarArg) { 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const MCPhysReg ArgRegs[] = { 498687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 499687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju }; 500687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs, 6); 501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCPhysReg *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6; 502687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned ArgOffset = CCInfo.getNextStackOffset(); 503687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (NumAllocated == 6) 504687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ArgOffset += StackOffset; 505687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju else { 506687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(!ArgOffset); 507687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ArgOffset = 68+4*NumAllocated; 508687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 509687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 510d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Remember the vararg offset for the va_start implementation. 5111e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman FuncInfo->setVarArgsFrameOffset(ArgOffset); 51253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 513a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman std::vector<SDValue> OutChains; 514a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman 515d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner for (; CurArgReg != ArgRegEnd; ++CurArgReg) { 516d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 517d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MF.getRegInfo().addLiveIn(*CurArgReg, VReg); 518825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32); 519d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 5203f2bf85d14759cc4b28a86805f566ac805a54d00David Greene int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset, 521ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 522825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 523d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 5246229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, 5256229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), 52654a7aa84294e31140a023e0c721703a647fe227bDavid Greene false, false, 0)); 527d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ArgOffset += 4; 528d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 529a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman 530a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman if (!OutChains.empty()) { 53198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman OutChains.push_back(Chain); 532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); 533a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman } 534d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 53553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 53698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 537d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 538d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 539f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen// Lower formal arguments for the 64 bit ABI. 540f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering:: 541f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments_64(SDValue Chain, 542f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CallingConv::ID CallConv, 543f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen bool IsVarArg, 544f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen const SmallVectorImpl<ISD::InputArg> &Ins, 545ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, 546f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SelectionDAG &DAG, 547f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 548f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen MachineFunction &MF = DAG.getMachineFunction(); 549f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 550f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // Analyze arguments according to CC_Sparc64. 551f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SmallVector<CCValAssign, 16> ArgLocs; 552f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), 553f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen getTargetMachine(), ArgLocs, *DAG.getContext()); 554f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64); 555f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 556da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // The argument array begins at %fp+BIAS+128, after the register save area. 557da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen const unsigned ArgArea = 128; 558da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 559f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 560f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen CCValAssign &VA = ArgLocs[i]; 561f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen if (VA.isRegLoc()) { 562f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // This argument is passed in a register. 563f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // All integer register arguments are promoted by the caller to i64. 564f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 565f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // Create a virtual register for the promoted live-in value. 566f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen unsigned VReg = MF.addLiveIn(VA.getLocReg(), 567f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen getRegClassFor(VA.getLocVT())); 568f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()); 569f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 5701f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Get the high bits for i32 struct elements. 5711f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 5721f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg, 5731f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 5741f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen 575f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // The caller promoted the argument, so insert an Assert?ext SDNode so we 576f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // won't promote the value again in this function. 577f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen switch (VA.getLocInfo()) { 578f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen case CCValAssign::SExt: 579f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg, 580f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 581f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen break; 582f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen case CCValAssign::ZExt: 583f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg, 584f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 585f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen break; 586f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen default: 587f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen break; 588f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen } 589f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 590f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // Truncate the register down to the argument type. 591f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen if (VA.isExtInLoc()) 592f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg); 593f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 594f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen InVals.push_back(Arg); 595f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen continue; 596f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen } 597f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 598f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen // The registers are exhausted. This argument was passed on the stack. 599f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen assert(VA.isMemLoc()); 6001f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // The CC_Sparc64_Full/Half functions compute stack offsets relative to the 6011f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // beginning of the arguments area at %fp+BIAS+128. 602da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen unsigned Offset = VA.getLocMemOffset() + ArgArea; 6031f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen unsigned ValSize = VA.getValVT().getSizeInBits() / 8; 6041f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // Adjust offset for extended arguments, SPARC is big-endian. 6051f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // The caller will have written the full slot with extended bytes, but we 6061f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen // prefer our own extending loads. 6071f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen if (VA.isExtInLoc()) 6081f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen Offset += 8 - ValSize; 6091f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true); 6101f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, 6111f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen DAG.getFrameIndex(FI, getPointerTy()), 6121f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen MachinePointerInfo::getFixedStack(FI), 6131f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen false, false, false, 0)); 614f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen } 615da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 616da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen if (!IsVarArg) 617da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen return Chain; 618da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 619da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // This function takes variable arguments, some of which may have been passed 620da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // in registers %i0-%i5. Variable floating point arguments are never passed 621da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // in floating point registers. They go on %i0-%i5 or on the stack like 622da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // integer arguments. 623da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // 624da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // The va_start intrinsic needs to know the offset to the first variable 625da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // argument. 626da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen unsigned ArgOffset = CCInfo.getNextStackOffset(); 627da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 628da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Skip the 128 bytes of register save area. 629da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgArea + 630da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen Subtarget->getStackPointerBias()); 631da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 632da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Save the variable arguments that were passed in registers. 633da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // The caller is required to reserve stack space for 6 arguments regardless 634da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // of how many arguments were actually passed. 635da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SmallVector<SDValue, 8> OutChains; 636da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen for (; ArgOffset < 6*8; ArgOffset += 8) { 637da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen unsigned VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass); 638da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64); 639da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen int FI = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset + ArgArea, true); 640da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen OutChains.push_back(DAG.getStore(Chain, DL, VArg, 641da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getFrameIndex(FI, getPointerTy()), 642da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen MachinePointerInfo::getFixedStack(FI), 643da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen false, false, 0)); 644da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen } 645da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 646da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen if (!OutChains.empty()) 647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); 648da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen 649f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen return Chain; 650f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen} 651f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen 65298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 653d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiSparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 654d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 65518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (Subtarget->is64Bit()) 65618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen return LowerCall_64(CLI, InVals); 65718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen return LowerCall_32(CLI, InVals); 65818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen} 65918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 6601b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindarajustatic bool hasReturnsTwiceAttr(SelectionDAG &DAG, SDValue Callee, 6611b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju ImmutableCallSite *CS) { 6621b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju if (CS) 6631b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju return CS->hasFnAttr(Attribute::ReturnsTwice); 6641b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju 665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const Function *CalleeFn = nullptr; 6661b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 6671b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju CalleeFn = dyn_cast<Function>(G->getGlobal()); 6681b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju } else if (ExternalSymbolSDNode *E = 6691b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju dyn_cast<ExternalSymbolSDNode>(Callee)) { 6701b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const Function *Fn = DAG.getMachineFunction().getFunction(); 6711b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const Module *M = Fn->getParent(); 6721b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const char *CalleeName = E->getSymbol(); 6731b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju CalleeFn = M->getFunction(CalleeName); 6741b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju } 6751b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju 6761b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju if (!CalleeFn) 6771b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju return false; 6781b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju return CalleeFn->hasFnAttribute(Attribute::ReturnsTwice); 6791b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju} 6801b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju 68118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen// Lower a call for the 32-bit ABI. 68218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSDValue 68318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, 68418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 685d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 686ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &dl = CLI.DL; 687a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 688a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 689a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 690d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 691d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 692d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 693d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 694d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 695d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 6960c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // Sparc target does not yet support tail call optimization. 6970c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 69898949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner 699315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Analyze operands of the call, assigning locations to each operand. 700315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner SmallVector<CCValAssign, 16> ArgLocs; 701471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 70256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling DAG.getTarget(), ArgLocs, *DAG.getContext()); 70398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32); 70453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 705315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Get the size of the outgoing arguments stack space requirement. 706315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner unsigned ArgsSize = CCInfo.getNextStackOffset(); 70753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 708d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Keep stack frames 8-byte aligned. 709d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ArgsSize = (ArgsSize+7) & ~7; 710d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 71146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 71246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 7131e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Create local copies for byval args. 71446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SmallVector<SDValue, 8> ByValArgs; 71546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 71646713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju ISD::ArgFlagsTy Flags = Outs[i].Flags; 71746713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju if (!Flags.isByVal()) 71846713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju continue; 71946713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 72046713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SDValue Arg = OutVals[i]; 72146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju unsigned Size = Flags.getByValSize(); 72246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju unsigned Align = Flags.getByValAlign(); 72346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 72446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju int FI = MFI->CreateStackObject(Size, Align, false); 72546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 72646713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju SDValue SizeNode = DAG.getConstant(Size, MVT::i32); 72746713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 72846713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Align, 7291e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju false, // isVolatile, 7301e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju (Size <= 32), // AlwaysInline if size <= 32 73146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju MachinePointerInfo(), MachinePointerInfo()); 73246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju ByValArgs.push_back(FIPtr); 73346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju } 73446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 7356e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true), 7366e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick dl); 73753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 738475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 739475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> MemOpChains; 74053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 741687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju const unsigned StackOffset = 92; 74258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju bool hasStructRetAttr = false; 743315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Walk the register/memloc assignments, inserting copies/loads. 74446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size(); 745687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju i != e; 746687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju ++i, ++realArgIdx) { 747315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner CCValAssign &VA = ArgLocs[i]; 748687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue Arg = OutVals[realArgIdx]; 749315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner 75046713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags; 75146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 7521e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Use local copy if it is a byval arg. 75346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju if (Flags.isByVal()) 75446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju Arg = ByValArgs[byvalArgIdx++]; 75546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju 756315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // Promote the value if needed. 757315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner switch (VA.getLocInfo()) { 758c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 759315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::Full: break; 760315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::SExt: 761687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 762315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner break; 763315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::ZExt: 764687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 765315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner break; 766315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner case CCValAssign::AExt: 767687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 768687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju break; 769687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju case CCValAssign::BCvt: 770687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg); 771315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner break; 772315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner } 77353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 7748184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju if (Flags.isSRet()) { 7758184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju assert(VA.needsCustom()); 7768184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju // store SRet argument in %sp+64 7778184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 7788184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(64); 7798184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 7808184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 7818184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju MachinePointerInfo(), 7828184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju false, false, 0)); 78358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju hasStructRetAttr = true; 7848184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju continue; 7858184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju } 7868184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju 787687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.needsCustom()) { 788687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.getLocVT() == MVT::f64); 789687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 790687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isMemLoc()) { 791687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = VA.getLocMemOffset() + StackOffset; 7921e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // if it is double-word aligned, just store. 793687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (Offset % 8 == 0) { 794687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 795687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(Offset); 796687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 797687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 798687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 799687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 800687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 80112db7b68b683371a6ae464e76b4c850fa0199eebVenkatraman Govindaraju } 8028c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 803687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 804825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32); 805bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, 806687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg, StackPtr, MachinePointerInfo(), 80754a7aa84294e31140a023e0c721703a647fe227bDavid Greene false, false, 0); 8088c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands // Sparc is big-endian, so the high part comes first. 809d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, 810d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 8118c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands // Increment the pointer to the other half. 81233c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 8138c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands DAG.getIntPtrConstant(4)); 8148c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands // Load the low part. 815d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, 816d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 8178c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands 818687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isRegLoc()) { 819687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(VA.getLocReg(), Hi)); 820687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(i+1 != e); 821687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju CCValAssign &NextVA = ArgLocs[++i]; 822687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (NextVA.isRegLoc()) { 823687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Lo)); 824687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } else { 8251e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Store the low part in stack. 826687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = NextVA.getLocMemOffset() + StackOffset; 827687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 828687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(Offset); 829687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 830687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff, 831687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 832687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 833687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju } 8348c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } else { 835687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju unsigned Offset = VA.getLocMemOffset() + StackOffset; 836687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Store the high part. 837687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 838687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(Offset); 839687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 840687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Hi, PtrOff, 841687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 842687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 843687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Store the low part. 844687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getIntPtrConstant(Offset+4); 845687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 846687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff, 847687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 848687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 8498c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 850687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 8518c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 85253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 853687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Arguments that can be passed on register must be kept at 854687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // RegsToPass vector 855687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.isRegLoc()) { 856687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju if (VA.getLocVT() != MVT::f32) { 857687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 858687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 859d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 860687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg); 861687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 862687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju continue; 8638c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands } 86453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 865687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju assert(VA.isMemLoc()); 866687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 867687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju // Create a store off the stack pointer for this argument. 868687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); 869687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+StackOffset); 870687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff); 871687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 872687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju MachinePointerInfo(), 873687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju false, false, 0)); 874d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 875687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju 87653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 877d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Emit all stores, make sure the occur before any copies into physregs. 878315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner if (!MemOpChains.empty()) 879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 88053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 88153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token 882315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // chain and flag operands which copy the outgoing args into registers. 8837a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // The InFlag in necessary since all emitted instructions must be 884315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner // stuck together. 885475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InFlag; 886315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 8871b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen unsigned Reg = toCallerWindow(RegsToPass[i].first); 88833c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen Chain = DAG.getCopyToReg(Chain, dl, Reg, RegsToPass[i].second, InFlag); 889d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner InFlag = Chain.getValue(1); 890d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 891d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 89258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju unsigned SRetArgSize = (hasStructRetAttr)? getSRetArgSize(DAG, Callee):0; 8931b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CS); 89458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 895d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // If the callee is a GlobalAddress node (quite common, every direct call is) 896d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 897056292fd738924f3f7703725d8f630983794b5a5Bill Wendling // Likewise ExternalSymbol -> TargetExternalSymbol. 89836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_) 89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? SparcMCExpr::VK_Sparc_WPLT30 : 0); 900d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0, TF); 902056292fd738924f3f7703725d8f630983794b5a5Bill Wendling else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32, TF); 904d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 9057d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju // Returns a chain & a flag for retval copy to use 9067d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 9077d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju SmallVector<SDValue, 8> Ops; 9087d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Ops.push_back(Chain); 9097d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Ops.push_back(Callee); 91058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (hasStructRetAttr) 91158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju Ops.push_back(DAG.getTargetConstant(SRetArgSize, MVT::i32)); 9121b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 9131b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen Ops.push_back(DAG.getRegister(toCallerWindow(RegsToPass[i].first), 9141b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen RegsToPass[i].second.getValueType())); 915b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen 916b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen // Add a register mask operand representing the call-preserved registers. 9171b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const SparcRegisterInfo *TRI = 9181b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju ((const SparcTargetMachine&)getTargetMachine()).getRegisterInfo(); 9191b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const uint32_t *Mask = ((hasReturnsTwice) 9201b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju ? TRI->getRTCallPreservedMask(CallConv) 9211b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju : TRI->getCallPreservedMask(CallConv)); 922b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen assert(Mask && "Missing call preserved mask for calling convention"); 923b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen Ops.push_back(DAG.getRegisterMask(Mask)); 924b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen 9257d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju if (InFlag.getNode()) 9267d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju Ops.push_back(InFlag); 9277d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju 928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops); 929d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner InFlag = Chain.getValue(1); 93053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 931e563bbc312f8b11ecfe12b8187176f667df1dff3Chris Lattner Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), 9326e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick DAG.getIntPtrConstant(0, true), InFlag, dl); 93398949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner InFlag = Chain.getValue(1); 93453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 93598949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner // Assign locations to each value returned by this call. 93698949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner SmallVector<CCValAssign, 16> RVLocs; 937471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(), 93856cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling DAG.getTarget(), RVLocs, *DAG.getContext()); 93953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 94098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32); 94153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 94298949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner // Copy all of the result registers out of their specified physreg. 94398949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner for (unsigned i = 0; i != RVLocs.size(); ++i) { 9441b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen Chain = DAG.getCopyFromReg(Chain, dl, toCallerWindow(RVLocs[i].getLocReg()), 94598949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner RVLocs[i].getValVT(), InFlag).getValue(1); 94698949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner InFlag = Chain.getValue(2); 94798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 948d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 94953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 95098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 951d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 952d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 95375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju// This functions returns true if CalleeName is a ABI function that returns 95475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju// a long double (fp128). 95575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic bool isFP128ABICall(const char *CalleeName) 95675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju{ 95775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju static const char *const ABICalls[] = 95875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju { "_Q_add", "_Q_sub", "_Q_mul", "_Q_div", 95975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju "_Q_sqrt", "_Q_neg", 96075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju "_Q_itoq", "_Q_stoq", "_Q_dtoq", "_Q_utoq", 961fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju "_Q_lltoq", "_Q_ulltoq", 962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines nullptr 96375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju }; 964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const char * const *I = ABICalls; *I != nullptr; ++I) 96575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (strcmp(CalleeName, *I) == 0) 96675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return true; 96775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return false; 96875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 96975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 97058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindarajuunsigned 97158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman GovindarajuSparcTargetLowering::getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const 97258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju{ 973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const Function *CalleeFn = nullptr; 97458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 97558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju CalleeFn = dyn_cast<Function>(G->getGlobal()); 97658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju } else if (ExternalSymbolSDNode *E = 97758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju dyn_cast<ExternalSymbolSDNode>(Callee)) { 97858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju const Function *Fn = DAG.getMachineFunction().getFunction(); 97958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju const Module *M = Fn->getParent(); 98075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const char *CalleeName = E->getSymbol(); 98175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju CalleeFn = M->getFunction(CalleeName); 98275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (!CalleeFn && isFP128ABICall(CalleeName)) 98375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return 16; // Return sizeof(fp128) 98458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju } 98558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 98658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (!CalleeFn) 98758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju return 0; 9885a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 98958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju assert(CalleeFn->hasStructRetAttr() && 99058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju "Callee does not have the StructRet attribute."); 99158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 992db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner PointerType *Ty = cast<PointerType>(CalleeFn->arg_begin()->getType()); 993db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ElementTy = Ty->getElementType(); 9943574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow return getDataLayout()->getTypeAllocSize(ElementTy); 99558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju} 9965a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 997ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 998ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// Fixup floating point arguments in the ... part of a varargs call. 999ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// 1000ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// The SPARC v9 ABI requires that floating point arguments are treated the same 1001ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// as integers when calling a varargs function. This does not apply to the 1002ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// fixed arguments that are part of the function's prototype. 1003ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// 1004ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// This function post-processes a CCValAssign array created by 1005ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// AnalyzeCallOperands(). 1006ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesenstatic void fixupVariableFloatArgs(SmallVectorImpl<CCValAssign> &ArgLocs, 1007ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen ArrayRef<ISD::OutputArg> Outs) { 1008ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1009ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen const CCValAssign &VA = ArgLocs[i]; 101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MVT ValTy = VA.getLocVT(); 1011ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // FIXME: What about f32 arguments? C promotes them to f64 when calling 1012ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // varargs functions. 101336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!VA.isRegLoc() || (ValTy != MVT::f64 && ValTy != MVT::f128)) 1014ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen continue; 1015ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // The fixed arguments to a varargs function still go in FP registers. 1016ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (Outs[VA.getValNo()].IsFixed) 1017ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen continue; 1018ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 1019ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // This floating point argument should be reassigned. 1020ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen CCValAssign NewVA; 1021ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 1022ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // Determine the offset into the argument array. 102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned firstReg = (ValTy == MVT::f64) ? SP::D0 : SP::Q0; 102436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned argSize = (ValTy == MVT::f64) ? 8 : 16; 102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = argSize * (VA.getLocReg() - firstReg); 1026ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen assert(Offset < 16*8 && "Offset out of range, bad register enum?"); 1027ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 1028ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (Offset < 6*8) { 1029ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // This argument should go in %i0-%i5. 1030ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen unsigned IReg = SP::I0 + Offset/8; 103136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ValTy == MVT::f64) 103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Full register, just bitconvert into i64. 103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), 103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IReg, MVT::i64, CCValAssign::BCvt); 103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else { 103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(ValTy == MVT::f128 && "Unexpected type!"); 103736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Full register, just bitconvert into i128 -- We will lower this into 103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // two i64s in LowerCall_64. 103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NewVA = CCValAssign::getCustomReg(VA.getValNo(), VA.getValVT(), 104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IReg, MVT::i128, CCValAssign::BCvt); 104136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1042ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen } else { 1043ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // This needs to go to memory, we're out of integer registers. 1044ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen NewVA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(), 1045ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen Offset, VA.getLocVT(), VA.getLocInfo()); 1046ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen } 1047ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen ArgLocs[i] = NewVA; 1048ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen } 1049ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen} 1050ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 105118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen// Lower a call for the 64-bit ABI. 105218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSDValue 105318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, 105418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVectorImpl<SDValue> &InVals) const { 105518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SelectionDAG &DAG = CLI.DAG; 1056ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL = CLI.DL; 105718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue Chain = CLI.Chain; 105818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 10593b73dea538d9c53e205d38bfbcf99dd64306874bVenkatraman Govindaraju // Sparc target does not yet support tail call optimization. 10603b73dea538d9c53e205d38bfbcf99dd64306874bVenkatraman Govindaraju CLI.IsTailCall = false; 10613b73dea538d9c53e205d38bfbcf99dd64306874bVenkatraman Govindaraju 106218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Analyze operands of the call, assigning locations to each operand. 106318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<CCValAssign, 16> ArgLocs; 106418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 106518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getTarget(), ArgLocs, *DAG.getContext()); 106618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64); 106718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 106818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Get the size of the outgoing arguments stack space requirement. 106918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The stack offset computed by CC_Sparc64 includes all arguments. 10706ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen // Called functions expect 6 argument words to exist in the stack frame, used 10716ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen // or not. 10726ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen unsigned ArgsSize = std::max(6*8u, CCInfo.getNextStackOffset()); 107318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 107418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Keep stack frames 16-byte aligned. 107518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen ArgsSize = RoundUpToAlignment(ArgsSize, 16); 107618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 1077ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen // Varargs calls require special treatment. 1078ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen if (CLI.IsVarArg) 1079ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen fixupVariableFloatArgs(ArgLocs, CLI.Outs); 1080ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen 108118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Adjust the stack pointer to make room for the arguments. 108218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls 108318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // with more than 6 arguments. 10846e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true), 10856e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick DL); 108618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 108718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Collect the set of registers to pass to the function and their values. 108818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // This will be emitted as a sequence of CopyToReg nodes glued to the call 108918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // instruction. 109018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 109118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 109218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Collect chains from all the memory opeations that copy arguments to the 109318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // stack. They must follow the stack pointer adjustment above and precede the 109418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // call instruction itself. 109518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<SDValue, 8> MemOpChains; 109618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 109718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 109818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen const CCValAssign &VA = ArgLocs[i]; 109918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue Arg = CLI.OutVals[i]; 110018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 110118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Promote the value if needed. 110218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen switch (VA.getLocInfo()) { 110318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen default: 110418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen llvm_unreachable("Unknown location info!"); 110518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::Full: 110618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 110718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::SExt: 110818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg); 110918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 111018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::ZExt: 111118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg); 111218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 111318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::AExt: 111418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); 111518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 111618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::BCvt: 111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // fixupVariableFloatArgs() may create bitcasts from f128 to i128. But 111836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // SPARC does not support i128 natively. Lower it into two i64, see below. 111936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!VA.needsCustom() || VA.getValVT() != MVT::f128 112036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines || VA.getLocVT() != MVT::i128) 112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg); 112218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 112318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 112418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 112518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.isRegLoc()) { 112636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (VA.needsCustom() && VA.getValVT() == MVT::f128 112736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines && VA.getLocVT() == MVT::i128) { 112836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Store and reload into the interger register reg and reg+1. 112936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = 8 * (VA.getLocReg() - SP::I0); 113036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128; 113136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy()); 113236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue HiPtrOff = DAG.getIntPtrConstant(StackOffset); 113336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines HiPtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, 113436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines HiPtrOff); 113536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue LoPtrOff = DAG.getIntPtrConstant(StackOffset + 8); 113636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoPtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, 113736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoPtrOff); 113836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 113936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Store to %sp+BIAS+128+Offset 114036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Store = DAG.getStore(Chain, DL, Arg, HiPtrOff, 114136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachinePointerInfo(), 114236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false, 0); 114336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Load into Reg and Reg+1 114436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Hi64 = DAG.getLoad(MVT::i64, DL, Store, HiPtrOff, 114536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachinePointerInfo(), 114636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false, false, 0); 114736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Lo64 = DAG.getLoad(MVT::i64, DL, Store, LoPtrOff, 114836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachinePointerInfo(), 114936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false, false, 0); 115036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()), 115136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Hi64)); 115236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()+1), 115336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Lo64)); 115436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 115536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 115636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 115718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The custom bit on an i32 return value indicates that it should be 115818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // passed in the high bits of the register. 115918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) { 116018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::SHL, DL, MVT::i64, Arg, 116118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 116218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 116318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The next value may go in the low bits of the same register. 116418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Handle both at once. 116518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (i+1 < ArgLocs.size() && ArgLocs[i+1].isRegLoc() && 116618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen ArgLocs[i+1].getLocReg() == VA.getLocReg()) { 116718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, 116818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CLI.OutVals[i+1]); 116918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Arg = DAG.getNode(ISD::OR, DL, MVT::i64, Arg, NV); 117018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Skip the next value, it's already done. 117118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen ++i; 117218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 117318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 11741b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()), Arg)); 117518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen continue; 117618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 117718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 117818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen assert(VA.isMemLoc()); 117918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 118018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Create a store off the stack pointer for this argument. 118118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy()); 118218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The argument area starts at %fp+BIAS+128 in the callee frame, 118318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // %sp+BIAS+128 in ours. 118418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() + 118518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Subtarget->getStackPointerBias() + 118618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 128); 118718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, PtrOff); 118818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen MemOpChains.push_back(DAG.getStore(Chain, DL, Arg, PtrOff, 118918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen MachinePointerInfo(), 119018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen false, false, 0)); 119118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 119218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 119318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Emit all stores, make sure they occur before the call. 119418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (!MemOpChains.empty()) 1195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); 119618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 119718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Build a sequence of CopyToReg nodes glued together with token chain and 119818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // glue operands which copy the outgoing args into registers. The InGlue is 119918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // necessary since all emitted instructions must be stuck together in order 120018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // to pass the live physical registers. 120118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue InGlue; 120218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 120318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = DAG.getCopyToReg(Chain, DL, 120418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RegsToPass[i].first, RegsToPass[i].second, InGlue); 120518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(1); 120618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 120718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 120818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // If the callee is a GlobalAddress node (quite common, every direct call is) 120918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 121018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Likewise ExternalSymbol -> TargetExternalSymbol. 121118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue Callee = CLI.Callee; 12121b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CS); 121336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_) 121436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? SparcMCExpr::VK_Sparc_WPLT30 : 0); 121518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 121636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0, 121736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TF); 121818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 121936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy(), TF); 122018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 122118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Build the operands for the call instruction itself. 122218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<SDValue, 8> Ops; 122318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(Chain); 122418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(Callee); 122518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 122618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(DAG.getRegister(RegsToPass[i].first, 122718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RegsToPass[i].second.getValueType())); 122818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 1229b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen // Add a register mask operand representing the call-preserved registers. 12301b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const SparcRegisterInfo *TRI = 12311b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju ((const SparcTargetMachine&)getTargetMachine()).getRegisterInfo(); 12321b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju const uint32_t *Mask = ((hasReturnsTwice) 12331b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju ? TRI->getRTCallPreservedMask(CLI.CallConv) 12341b41835f02f77c04a93323f722cf158cc566acaeVenkatraman Govindaraju : TRI->getCallPreservedMask(CLI.CallConv)); 1235b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen assert(Mask && "Missing call preserved mask for calling convention"); 1236b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen Ops.push_back(DAG.getRegisterMask(Mask)); 1237b58126124081a9bf8da1368441b00070ed2db232Jakob Stoklund Olesen 123818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Make sure the CopyToReg nodes are glued to the call instruction which 123918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // consumes the registers. 124018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (InGlue.getNode()) 124118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Ops.push_back(InGlue); 124218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 124318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Now the call itself. 124418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 1245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, Ops); 124618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(1); 124718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 124818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Revert the stack pointer immediately after the call. 124918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), 12506e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick DAG.getIntPtrConstant(0, true), InGlue, DL); 125118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(1); 125218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 125318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Now extract the return values. This is more or less the same as 125418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // LowerFormalArguments_64. 125518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 125618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Assign locations to each value returned by this call. 125718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SmallVector<CCValAssign, 16> RVLocs; 125818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 125918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getTarget(), RVLocs, *DAG.getContext()); 126036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 126136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Set inreg flag manually for codegen generated library calls that 126236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // return float. 1263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == nullptr) 126436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CLI.Ins[0].Flags.setInReg(); 126536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 126636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64); 126718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 126818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Copy all of the result registers out of their specified physreg. 126918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen for (unsigned i = 0; i != RVLocs.size(); ++i) { 127018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen CCValAssign &VA = RVLocs[i]; 12711b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen unsigned Reg = toCallerWindow(VA.getLocReg()); 127218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 127318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can 127418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // reside in the same register in the high and low bits. Reuse the 127518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // CopyFromReg previous node to avoid duplicate copies. 127618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen SDValue RV; 127718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1))) 127818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg) 127918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = Chain.getValue(0); 128018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 128118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // But usually we'll create a new CopyFromReg for a different register. 128218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (!RV.getNode()) { 128318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue); 128418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen Chain = RV.getValue(1); 128518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InGlue = Chain.getValue(2); 128618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 128718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 128818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Get the high bits for i32 struct elements. 128918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 129018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV, 129118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getConstant(32, MVT::i32)); 129218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 129318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // The callee promoted the return value, so insert an Assert?ext SDNode so 129418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // we won't promote the value again in this function. 129518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen switch (VA.getLocInfo()) { 129618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::SExt: 129718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV, 129818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 129918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 130018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen case CCValAssign::ZExt: 130118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV, 130218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen DAG.getValueType(VA.getValVT())); 130318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 130418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen default: 130518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen break; 130618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 130718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 130818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen // Truncate the register down to the return value type. 130918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen if (VA.isExtInLoc()) 131018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV); 131118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 131218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen InVals.push_back(RV); 131318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen } 131418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 131518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen return Chain; 131618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen} 131718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen 13185a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner//===----------------------------------------------------------------------===// 13195a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner// TargetLowering Implementation 13205a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner//===----------------------------------------------------------------------===// 13215a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13225a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC 13235a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// condition. 13245a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerstatic SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { 13255a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (CC) { 1326c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown integer condition code!"); 13275a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETEQ: return SPCC::ICC_E; 13285a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETNE: return SPCC::ICC_NE; 13295a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLT: return SPCC::ICC_L; 13305a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGT: return SPCC::ICC_G; 13315a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLE: return SPCC::ICC_LE; 13325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGE: return SPCC::ICC_GE; 13335a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULT: return SPCC::ICC_CS; 13345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULE: return SPCC::ICC_LEU; 13355a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGT: return SPCC::ICC_GU; 13365a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGE: return SPCC::ICC_CC; 13375a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 13385a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 13395a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13405a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC 13415a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// FCC condition. 13425a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerstatic SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { 13435a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (CC) { 1344c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown fp condition code!"); 13455a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETEQ: 13465a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOEQ: return SPCC::FCC_E; 13475a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETNE: 13485a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUNE: return SPCC::FCC_NE; 13495a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLT: 13505a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOLT: return SPCC::FCC_L; 13515a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGT: 13525a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOGT: return SPCC::FCC_G; 13535a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETLE: 13545a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOLE: return SPCC::FCC_LE; 13555a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETGE: 13565a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETOGE: return SPCC::FCC_GE; 13575a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULT: return SPCC::FCC_UL; 13585a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETULE: return SPCC::FCC_ULE; 13595a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGT: return SPCC::FCC_UG; 13605a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUGE: return SPCC::FCC_UGE; 13615a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUO: return SPCC::FCC_U; 13625a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETO: return SPCC::FCC_O; 13635a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETONE: return SPCC::FCC_LG; 13645a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case ISD::SETUEQ: return SPCC::FCC_UE; 13655a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 13665a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 13675a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13685a65b928302494ad2b3051980ce956e8f9e95023Chris LattnerSparcTargetLowering::SparcTargetLowering(TargetMachine &TM) 136936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : TargetLowering(TM, new SparcELFTargetObjectFile()) { 1370fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen Subtarget = &TM.getSubtarget<SparcSubtarget>(); 137153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 13725a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Set up the register classes. 1373c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper addRegisterClass(MVT::i32, &SP::IntRegsRegClass); 1374c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper addRegisterClass(MVT::f32, &SP::FPRegsRegClass); 1375c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper addRegisterClass(MVT::f64, &SP::DFPRegsRegClass); 13762f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju addRegisterClass(MVT::f128, &SP::QFPRegsRegClass); 1377fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen if (Subtarget->is64Bit()) 1378fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen addRegisterClass(MVT::i64, &SP::I64RegsRegClass); 13795a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13805a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Turn FP extload into load/fextend 1381825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 13822f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand); 13832f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 13845a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc doesn't have i1 sign extending load 1385825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 13862f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 13875a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Turn FP truncstore into trunc + store. 1388825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::f64, MVT::f32, Expand); 13892f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setTruncStoreAction(MVT::f128, MVT::f32, Expand); 13902f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setTruncStoreAction(MVT::f128, MVT::f64, Expand); 13915a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 13925a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Custom legalize GlobalAddress nodes into LO/HI parts. 139341d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen setOperationAction(ISD::GlobalAddress, getPointerTy(), Custom); 139441d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen setOperationAction(ISD::GlobalTLSAddress, getPointerTy(), Custom); 139541d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen setOperationAction(ISD::ConstantPool, getPointerTy(), Custom); 1396e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju setOperationAction(ISD::BlockAddress, getPointerTy(), Custom); 139753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 13985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc doesn't have sext_inreg, replace them with shl/sra 1399825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 1400825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); 1401825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); 14025a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 14035a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc has no REM or DIVREM operations. 1404825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i32, Expand); 1405825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i32, Expand); 1406825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i32, Expand); 1407825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i32, Expand); 1408fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 14091d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky // ... nor does SparcV9. 14101d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky if (Subtarget->is64Bit()) { 14111d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky setOperationAction(ISD::UREM, MVT::i64, Expand); 14121d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky setOperationAction(ISD::SREM, MVT::i64, Expand); 14131d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky setOperationAction(ISD::SDIVREM, MVT::i64, Expand); 14141d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky setOperationAction(ISD::UDIVREM, MVT::i64, Expand); 14151d6d49fbb104781cc3e9da9dcc3e36b6cbcd38b6Roman Divacky } 14165a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 14175a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Custom expand fp<->sint 1418825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 1419825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 1420fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 1421fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 14225a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 14235e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju // Custom Expand fp<->uint 14245e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); 14255e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); 1426fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom); 1427fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom); 142853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1429bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck setOperationAction(ISD::BITCAST, MVT::f32, Expand); 1430bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck setOperationAction(ISD::BITCAST, MVT::i32, Expand); 143153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 14325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc has no select or setcc: expand to SELECT_CC. 1433825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i32, Expand); 1434825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::f32, Expand); 1435825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::f64, Expand); 14362f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::SELECT, MVT::f128, Expand); 14372f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 1438825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i32, Expand); 1439825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::f32, Expand); 1440825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::f64, Expand); 14412f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::SETCC, MVT::f128, Expand); 144253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 14435a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Sparc doesn't have BRCOND either, it has BR_CC. 1444825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1445825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRIND, MVT::Other, Expand); 1446825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 1447825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i32, Custom); 1448825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::f32, Custom); 1449825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::f64, Custom); 14502f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::BR_CC, MVT::f128, Custom); 145153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1452825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 1453825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 1454825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 14552f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::SELECT_CC, MVT::f128, Custom); 145653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 14578534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen if (Subtarget->is64Bit()) { 145820b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju setOperationAction(ISD::ADDC, MVT::i64, Custom); 145920b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju setOperationAction(ISD::ADDE, MVT::i64, Custom); 146020b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju setOperationAction(ISD::SUBC, MVT::i64, Custom); 146120b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju setOperationAction(ISD::SUBE, MVT::i64, Custom); 146289f530ebbfa91d1583a72d86dc6ca2804f4f450dJakob Stoklund Olesen setOperationAction(ISD::BITCAST, MVT::f64, Expand); 146389f530ebbfa91d1583a72d86dc6ca2804f4f450dJakob Stoklund Olesen setOperationAction(ISD::BITCAST, MVT::i64, Expand); 1464900622e099054da4a213074581d8501ac27e7ea7Jakob Stoklund Olesen setOperationAction(ISD::SELECT, MVT::i64, Expand); 1465900622e099054da4a213074581d8501ac27e7ea7Jakob Stoklund Olesen setOperationAction(ISD::SETCC, MVT::i64, Expand); 14668534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen setOperationAction(ISD::BR_CC, MVT::i64, Custom); 14670e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); 146811cecbe1a070d461bb213a6037712f25e59a920aVenkatraman Govindaraju 146936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::CTPOP, MVT::i64, 147036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Subtarget->usePopc() ? Legal : Expand); 147111cecbe1a070d461bb213a6037712f25e59a920aVenkatraman Govindaraju setOperationAction(ISD::CTTZ , MVT::i64, Expand); 147211cecbe1a070d461bb213a6037712f25e59a920aVenkatraman Govindaraju setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand); 147311cecbe1a070d461bb213a6037712f25e59a920aVenkatraman Govindaraju setOperationAction(ISD::CTLZ , MVT::i64, Expand); 147411cecbe1a070d461bb213a6037712f25e59a920aVenkatraman Govindaraju setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Expand); 147511cecbe1a070d461bb213a6037712f25e59a920aVenkatraman Govindaraju setOperationAction(ISD::BSWAP, MVT::i64, Expand); 14763e94418e857d5e17b5d16dbc5abc8b5a8b4efac6Roman Divacky setOperationAction(ISD::ROTL , MVT::i64, Expand); 14773e94418e857d5e17b5d16dbc5abc8b5a8b4efac6Roman Divacky setOperationAction(ISD::ROTR , MVT::i64, Expand); 1478f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom); 14798534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen } 14808534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen 148136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // ATOMICs. 148236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: We insert fences for each atomics and generate sub-optimal code 148336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // for PSO/TSO. Also, implement other atomicrmw operations. 148436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 148536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setInsertFencesForAtomic(true); 148636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 148736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Legal); 148836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, 148936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (Subtarget->isV9() ? Legal: Expand)); 149036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 149136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 149236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Legal); 149336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 149436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Custom Lower Atomic LOAD/STORE 149536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Custom); 149636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Custom); 149736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 149836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->is64Bit()) { 149936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Legal); 150036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Legal); 150136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Custom); 150236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom); 150336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1504825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 15051799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju if (!Subtarget->isV9()) { 15061799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // SparcV8 does not have FNEGD and FABSD. 15071799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju setOperationAction(ISD::FNEG, MVT::f64, Custom); 15081799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju setOperationAction(ISD::FABS, MVT::f64, Custom); 15091799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju } 15101799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 15112f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FSIN , MVT::f128, Expand); 15122f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FCOS , MVT::f128, Expand); 15132f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FSINCOS, MVT::f128, Expand); 15142f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FREM , MVT::f128, Expand); 15152f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FMA , MVT::f128, Expand); 1516825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FSIN , MVT::f64, Expand); 1517825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOS , MVT::f64, Expand); 15188688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng setOperationAction(ISD::FSINCOS, MVT::f64, Expand); 1519825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FREM , MVT::f64, Expand); 152033390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich setOperationAction(ISD::FMA , MVT::f64, Expand); 1521825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FSIN , MVT::f32, Expand); 1522825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOS , MVT::f32, Expand); 15238688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng setOperationAction(ISD::FSINCOS, MVT::f32, Expand); 1524825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FREM , MVT::f32, Expand); 152533390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich setOperationAction(ISD::FMA , MVT::f32, Expand); 1526825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ , MVT::i32, Expand); 152763974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand); 1528825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ , MVT::i32, Expand); 152963974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand); 1530825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL , MVT::i32, Expand); 1531825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR , MVT::i32, Expand); 1532825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BSWAP, MVT::i32, Expand); 15332f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FCOPYSIGN, MVT::f128, Expand); 1534825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); 1535825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); 15362f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FPOW , MVT::f128, Expand); 1537825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FPOW , MVT::f64, Expand); 1538825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::FPOW , MVT::f32, Expand); 1539825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1540825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 1541825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 1542825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 15435a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 15445a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // FIXME: Sparc provides these multiplies, but we don't have them yet. 1545825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); 1546825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 154753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 1548f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling if (Subtarget->is64Bit()) { 1549f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); 1550f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); 1551f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling setOperationAction(ISD::MULHU, MVT::i64, Expand); 1552f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling setOperationAction(ISD::MULHS, MVT::i64, Expand); 155336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 155436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::UMULO, MVT::i64, Custom); 155536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::SMULO, MVT::i64, Custom); 155636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 155736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); 155836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); 155936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand); 1560f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling } 1561f9a98aeb5b5129c9eeb95978c7cf925e4a88e224Bill Wendling 15625a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // VASTART needs to be custom lowered to use the VarArgsFrameIndex. 1563825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VASTART , MVT::Other, Custom); 15645a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // VAARG needs to be lowered to not do unaligned accesses for doubles. 1565825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VAARG , MVT::Other, Custom); 156653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 156736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::TRAP , MVT::Other, Legal); 156836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15695a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Use the default implementation. 1570825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VACOPY , MVT::Other, Expand); 1571825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::VAEND , MVT::Other, Expand); 1572825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); 1573825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); 1574825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom); 15755a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 157630ec8a3658b1f06bb94d392c55feb7f107517bf8Venkatraman Govindaraju setExceptionPointerRegister(SP::I0); 157730ec8a3658b1f06bb94d392c55feb7f107517bf8Venkatraman Govindaraju setExceptionSelectorRegister(SP::I1); 157853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 15795a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner setStackPointerRegisterToSaveRestore(SP::O6); 15805a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 158136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setOperationAction(ISD::CTPOP, MVT::i32, 158236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Subtarget->usePopc() ? Legal : Expand); 158353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 15842f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju if (Subtarget->isV9() && Subtarget->hasHardQuad()) { 15852f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::LOAD, MVT::f128, Legal); 15862f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::STORE, MVT::f128, Legal); 15872f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju } else { 15882f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::LOAD, MVT::f128, Custom); 15892f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::STORE, MVT::f128, Custom); 15902f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju } 15912f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 15922f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju if (Subtarget->hasHardQuad()) { 15932f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FADD, MVT::f128, Legal); 15942f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FSUB, MVT::f128, Legal); 15952f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FMUL, MVT::f128, Legal); 15962f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FDIV, MVT::f128, Legal); 15972f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FSQRT, MVT::f128, Legal); 15982f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FP_EXTEND, MVT::f128, Legal); 15992f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FP_ROUND, MVT::f64, Legal); 16002f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju if (Subtarget->isV9()) { 16012f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FNEG, MVT::f128, Legal); 16022f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FABS, MVT::f128, Legal); 16032f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju } else { 16042f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FNEG, MVT::f128, Custom); 16052f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju setOperationAction(ISD::FABS, MVT::f128, Custom); 16062f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju } 1607fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 1608fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (!Subtarget->is64Bit()) { 1609fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll"); 1610fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull"); 1611fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq"); 1612fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq"); 1613fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju } 1614fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 161575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } else { 161675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // Custom legalize f128 operations. 161775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 161875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FADD, MVT::f128, Custom); 161975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FSUB, MVT::f128, Custom); 162075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FMUL, MVT::f128, Custom); 162175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FDIV, MVT::f128, Custom); 162275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FSQRT, MVT::f128, Custom); 162375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FNEG, MVT::f128, Custom); 162475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FABS, MVT::f128, Custom); 162575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 162675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FP_EXTEND, MVT::f128, Custom); 162775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FP_ROUND, MVT::f64, Custom); 162875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setOperationAction(ISD::FP_ROUND, MVT::f32, Custom); 162975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 163075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // Setup Runtime library names. 163175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Subtarget->is64Bit()) { 163275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::ADD_F128, "_Qp_add"); 163375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::SUB_F128, "_Qp_sub"); 163475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::MUL_F128, "_Qp_mul"); 163575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::DIV_F128, "_Qp_div"); 163675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::SQRT_F128, "_Qp_sqrt"); 163775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPTOSINT_F128_I32, "_Qp_qtoi"); 16385e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Qp_qtoui"); 163975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Qp_itoq"); 16405e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Qp_uitoq"); 1641fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Qp_qtox"); 1642fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Qp_qtoux"); 1643fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Qp_xtoq"); 1644fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Qp_uxtoq"); 164575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPEXT_F32_F128, "_Qp_stoq"); 164675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPEXT_F64_F128, "_Qp_dtoq"); 164775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPROUND_F128_F32, "_Qp_qtos"); 164875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPROUND_F128_F64, "_Qp_qtod"); 164975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } else { 165075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::ADD_F128, "_Q_add"); 165175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::SUB_F128, "_Q_sub"); 165275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::MUL_F128, "_Q_mul"); 165375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::DIV_F128, "_Q_div"); 165475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::SQRT_F128, "_Q_sqrt"); 165575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPTOSINT_F128_I32, "_Q_qtoi"); 16565e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Q_qtou"); 165775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Q_itoq"); 16585e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Q_utoq"); 1659fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll"); 1660fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull"); 1661fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq"); 1662fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq"); 166375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPEXT_F32_F128, "_Q_stoq"); 166475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPEXT_F64_F128, "_Q_dtoq"); 166575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPROUND_F128_F32, "_Q_qtos"); 166675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju setLibcallName(RTLIB::FPROUND_F128_F64, "_Q_qtod"); 166775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 16682f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju } 16692f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 1670fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(2); 1671fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 16725a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner computeRegisterProperties(); 16735a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 16745a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 16755a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerconst char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const { 16765a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (Opcode) { 1677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: return nullptr; 16785a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::CMPICC: return "SPISD::CMPICC"; 16795a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::CMPFCC: return "SPISD::CMPFCC"; 16805a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::BRICC: return "SPISD::BRICC"; 16818534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen case SPISD::BRXCC: return "SPISD::BRXCC"; 16825a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::BRFCC: return "SPISD::BRFCC"; 16835a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC"; 16840e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC"; 16855a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC"; 16865a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::Hi: return "SPISD::Hi"; 16875a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::Lo: return "SPISD::Lo"; 16885a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::FTOI: return "SPISD::FTOI"; 16895a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::ITOF: return "SPISD::ITOF"; 1690fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju case SPISD::FTOX: return "SPISD::FTOX"; 1691fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju case SPISD::XTOF: return "SPISD::XTOF"; 16925a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::CALL: return "SPISD::CALL"; 16935a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::RET_FLAG: return "SPISD::RET_FLAG"; 1694860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG"; 1695fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju case SPISD::FLUSHW: return "SPISD::FLUSHW"; 16967d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju case SPISD::TLS_ADD: return "SPISD::TLS_ADD"; 16977d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju case SPISD::TLS_LD: return "SPISD::TLS_LD"; 16987d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju case SPISD::TLS_CALL: return "SPISD::TLS_CALL"; 16995a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 17005a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 17015a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 17027d9c02dc620ea5f5cdf2dc0bd0f03d9370f845d3Bill WendlingEVT SparcTargetLowering::getSetCCResultType(LLVMContext &, EVT VT) const { 17037d9c02dc620ea5f5cdf2dc0bd0f03d9370f845d3Bill Wendling if (!VT.isVector()) 17047d9c02dc620ea5f5cdf2dc0bd0f03d9370f845d3Bill Wendling return MVT::i32; 17057d9c02dc620ea5f5cdf2dc0bd0f03d9370f845d3Bill Wendling return VT.changeVectorElementTypeToInteger(); 17067d9c02dc620ea5f5cdf2dc0bd0f03d9370f845d3Bill Wendling} 17077d9c02dc620ea5f5cdf2dc0bd0f03d9370f845d3Bill Wendling 17085a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to 17095a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// be zero. Op is expected to be a target specific node. Used by DAG 17105a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// combiner. 1711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid SparcTargetLowering::computeKnownBitsForTargetNode 17121e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju (const SDValue Op, 17131e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju APInt &KnownZero, 17141e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju APInt &KnownOne, 17151e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju const SelectionDAG &DAG, 17161e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju unsigned Depth) const { 17175a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner APInt KnownZero2, KnownOne2; 171826c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0); 171953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 17205a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner switch (Op.getOpcode()) { 17215a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner default: break; 17225a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_ICC: 17230e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen case SPISD::SELECT_XCC: 17245a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner case SPISD::SELECT_FCC: 1725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DAG.computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); 1726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DAG.computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); 172753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 17285a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner // Only known if known in both the LHS and RHS. 17295a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner KnownOne &= KnownOne2; 17305a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner KnownZero &= KnownZero2; 17315a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner break; 17325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner } 17335a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner} 17345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner 1735d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so 1736d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition. 1737475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic void LookThroughSetCC(SDValue &LHS, SDValue &RHS, 1738d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ISD::CondCode CC, unsigned &SPCC) { 1739f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman if (isa<ConstantSDNode>(RHS) && 1740e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman cast<ConstantSDNode>(RHS)->isNullValue() && 174153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov CC == ISD::SETNE && 17420e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen (((LHS.getOpcode() == SPISD::SELECT_ICC || 17430e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen LHS.getOpcode() == SPISD::SELECT_XCC) && 1744d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LHS.getOperand(3).getOpcode() == SPISD::CMPICC) || 1745d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner (LHS.getOpcode() == SPISD::SELECT_FCC && 1746d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) && 1747d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner isa<ConstantSDNode>(LHS.getOperand(0)) && 1748d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner isa<ConstantSDNode>(LHS.getOperand(1)) && 1749e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman cast<ConstantSDNode>(LHS.getOperand(0))->isOne() && 1750e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) { 1751475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CMPCC = LHS.getOperand(3); 1752f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue(); 1753d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LHS = CMPCC.getOperand(0); 1754d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner RHS = CMPCC.getOperand(1); 1755d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 1756d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1757d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 17580ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Convert to a target node and set target flags. 17590ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund OlesenSDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF, 17600ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SelectionDAG &DAG) const { 17610ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) 17620ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen return DAG.getTargetGlobalAddress(GA->getGlobal(), 1763ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc(GA), 17640ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen GA->getValueType(0), 17650ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen GA->getOffset(), TF); 176626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 176726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) 176826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return DAG.getTargetConstantPool(CP->getConstVal(), 176926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen CP->getValueType(0), 177026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen CP->getAlignment(), 177126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen CP->getOffset(), TF); 177226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 1773e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) 1774e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju return DAG.getTargetBlockAddress(BA->getBlockAddress(), 1775e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju Op.getValueType(), 1776e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju 0, 1777e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju TF); 1778e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju 177926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) 178026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return DAG.getTargetExternalSymbol(ES->getSymbol(), 178126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen ES->getValueType(0), TF); 178226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 17830ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen llvm_unreachable("Unhandled address SDNode"); 17840ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen} 17850ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen 17860ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Split Op into high and low parts according to HiTF and LoTF. 17870ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Return an ADD node combining the parts. 17880ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund OlesenSDValue SparcTargetLowering::makeHiLoPair(SDValue Op, 17890ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen unsigned HiTF, unsigned LoTF, 17900ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SelectionDAG &DAG) const { 1791ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 17920ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen EVT VT = Op.getValueType(); 17930ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG)); 17940ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG)); 17950ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 17960ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen} 17970ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen 179826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen// Build SDNodes for producing an address from a GlobalAddress, ConstantPool, 179926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen// or ExternalSymbol SDNode. 180026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund OlesenSDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { 1801ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 180287ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen EVT VT = getPointerTy(); 180387ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen 180426932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen // Handle PIC mode first. 180526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { 180626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen // This is the pic32 code model, the GOT is known to be smaller than 4GB. 180736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22, 180836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_GOT10, DAG); 180926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT); 181026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); 1811ecd4965c133d16fc9e5a6ac393c5194b67cd53abVenkatraman Govindaraju // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this 1812ecd4965c133d16fc9e5a6ac393c5194b67cd53abVenkatraman Govindaraju // function has calls. 1813ecd4965c133d16fc9e5a6ac393c5194b67cd53abVenkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 1814ecd4965c133d16fc9e5a6ac393c5194b67cd53abVenkatraman Govindaraju MFI->setHasCalls(true); 181526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr, 181626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen MachinePointerInfo::getGOT(), false, false, false, 0); 181726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen } 181826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 181926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen // This is one of the absolute code models. 182087ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen switch(getTargetMachine().getCodeModel()) { 182187ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen default: 182287ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen llvm_unreachable("Unsupported absolute code model"); 182387ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen case CodeModel::Small: 1824618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen // abs32. 182536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI, 182636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_LO, DAG); 182787ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen case CodeModel::Medium: { 1828618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen // abs44. 182936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue H44 = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_H44, 183036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_M44, DAG); 1831d9f88da7b329c54ccb0d2ebd3b3a4b0e4b1e2b06Jakob Stoklund Olesen H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getConstant(12, MVT::i32)); 183236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue L44 = withTargetFlags(Op, SparcMCExpr::VK_Sparc_L44, DAG); 183387ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen L44 = DAG.getNode(SPISD::Lo, DL, VT, L44); 183487ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen return DAG.getNode(ISD::ADD, DL, VT, H44, L44); 183587ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen } 1836618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen case CodeModel::Large: { 1837618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen // abs64. 183836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Hi = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HH, 183936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_HM, DAG); 1840d9f88da7b329c54ccb0d2ebd3b3a4b0e4b1e2b06Jakob Stoklund Olesen Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(32, MVT::i32)); 184136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Lo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI, 184236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_LO, DAG); 1843618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 1844618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen } 184587ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen } 184626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen} 184726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen 1848bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op, 1849d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 185026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return makeAddress(Op, DAG); 1851d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1852d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1853db486a6d5311944f61b92db9f6074944dbbdb242Chris LattnerSDValue SparcTargetLowering::LowerConstantPool(SDValue Op, 1854d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 185526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen return makeAddress(Op, DAG); 1856d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 1857d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 1858e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman GovindarajuSDValue SparcTargetLowering::LowerBlockAddress(SDValue Op, 1859e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju SelectionDAG &DAG) const { 1860e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju return makeAddress(Op, DAG); 1861e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju} 1862e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju 18637d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman GovindarajuSDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op, 18647d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SelectionDAG &DAG) const { 18657d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 18667d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op); 18677d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDLoc DL(GA); 18687d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju const GlobalValue *GV = GA->getGlobal(); 18697d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju EVT PtrVT = getPointerTy(); 18707d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 18717d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju TLSModel::Model model = getTargetMachine().getTLSModel(GV); 18727d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 18737d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) { 187436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned HiTF = ((model == TLSModel::GeneralDynamic) 187536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? SparcMCExpr::VK_Sparc_TLS_GD_HI22 187636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : SparcMCExpr::VK_Sparc_TLS_LDM_HI22); 187736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned LoTF = ((model == TLSModel::GeneralDynamic) 187836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? SparcMCExpr::VK_Sparc_TLS_GD_LO10 187936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : SparcMCExpr::VK_Sparc_TLS_LDM_LO10); 188036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned addTF = ((model == TLSModel::GeneralDynamic) 188136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? SparcMCExpr::VK_Sparc_TLS_GD_ADD 188236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : SparcMCExpr::VK_Sparc_TLS_LDM_ADD); 188336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned callTF = ((model == TLSModel::GeneralDynamic) 188436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? SparcMCExpr::VK_Sparc_TLS_GD_CALL 188536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : SparcMCExpr::VK_Sparc_TLS_LDM_CALL); 18867d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 18877d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue HiLo = makeHiLoPair(Op, HiTF, LoTF, DAG); 18887d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT); 18897d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Argument = DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Base, HiLo, 18907d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju withTargetFlags(Op, addTF, DAG)); 18917d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 18927d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Chain = DAG.getEntryNode(); 18937d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue InFlag; 18947d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 18957d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(1, true), DL); 18967d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Chain = DAG.getCopyToReg(Chain, DL, SP::O0, Argument, InFlag); 18977d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju InFlag = Chain.getValue(1); 18987d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Callee = DAG.getTargetExternalSymbol("__tls_get_addr", PtrVT); 18997d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Symbol = withTargetFlags(Op, callTF, DAG); 19007d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19017d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 19027d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SmallVector<SDValue, 4> Ops; 19037d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Ops.push_back(Chain); 19047d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Ops.push_back(Callee); 19057d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Ops.push_back(Symbol); 19067d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Ops.push_back(DAG.getRegister(SP::O0, PtrVT)); 19077d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju const uint32_t *Mask = getTargetMachine() 19087d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju .getRegisterInfo()->getCallPreservedMask(CallingConv::C); 19097d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju assert(Mask && "Missing call preserved mask for calling convention"); 19107d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Ops.push_back(DAG.getRegisterMask(Mask)); 19117d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Ops.push_back(InFlag); 1912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(SPISD::TLS_CALL, DL, NodeTys, Ops); 19137d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju InFlag = Chain.getValue(1); 19147d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(1, true), 19157d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju DAG.getIntPtrConstant(0, true), InFlag, DL); 19167d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju InFlag = Chain.getValue(1); 19177d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Ret = DAG.getCopyFromReg(Chain, DL, SP::O0, PtrVT, InFlag); 19187d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19197d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju if (model != TLSModel::LocalDynamic) 19207d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju return Ret; 19217d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19227d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT, 192336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_HIX22, DAG)); 19247d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT, 192536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_LOX10, DAG)); 19267d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju HiLo = DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo); 19277d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Ret, HiLo, 192836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_ADD, DAG)); 19297d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju } 19307d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19317d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju if (model == TLSModel::InitialExec) { 193236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ldTF = ((PtrVT == MVT::i64)? SparcMCExpr::VK_Sparc_TLS_IE_LDX 193336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : SparcMCExpr::VK_Sparc_TLS_IE_LD); 19347d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19357d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT); 19367d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19377d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this 19387d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju // function has calls. 19397d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 19407d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju MFI->setHasCalls(true); 19417d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19427d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue TGA = makeHiLoPair(Op, 194336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_TLS_IE_HI22, 194436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_TLS_IE_LO10, DAG); 19457d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Base, TGA); 19467d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Offset = DAG.getNode(SPISD::TLS_LD, 19477d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju DL, PtrVT, Ptr, 19487d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju withTargetFlags(Op, ldTF, DAG)); 19497d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, 19507d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju DAG.getRegister(SP::G7, PtrVT), Offset, 195136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines withTargetFlags(Op, 195236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SparcMCExpr::VK_Sparc_TLS_IE_ADD, DAG)); 19537d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju } 19547d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19557d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju assert(model == TLSModel::LocalExec); 19567d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT, 195736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LE_HIX22, DAG)); 19587d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT, 195936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LE_LOX10, DAG)); 19607d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju SDValue Offset = DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo); 19617d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 19627d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju return DAG.getNode(ISD::ADD, DL, PtrVT, 19637d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju DAG.getRegister(SP::G7, PtrVT), Offset); 19647d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju} 19657d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju 196675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuSDValue 196775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuSparcTargetLowering::LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, 196875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Arg, SDLoc DL, 196975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SelectionDAG &DAG) const { 197075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 197175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju EVT ArgVT = Arg.getValueType(); 197275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 197375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 197475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju ArgListEntry Entry; 197575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Node = Arg; 197675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Ty = ArgTy; 197775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 197875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (ArgTy->isFP128Ty()) { 197975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // Create a stack object and pass the pointer to the library function. 198075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju int FI = MFI->CreateStackObject(16, 8, false); 198175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); 198275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Chain = DAG.getStore(Chain, 198375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju DL, 198475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Node, 198575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju FIPtr, 198675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju MachinePointerInfo(), 198775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju false, 198875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju false, 198975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 8); 199075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 199175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Node = FIPtr; 199275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Ty = PointerType::getUnqual(ArgTy); 199375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 199475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Args.push_back(Entry); 199575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return Chain; 199675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 199775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 199875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuSDValue 199975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuSparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG, 200075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const char *LibFuncName, 200175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju unsigned numArgs) const { 200275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 200375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju ArgListTy Args; 200475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 200575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 200675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 200775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Callee = DAG.getExternalSymbol(LibFuncName, getPointerTy()); 200875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Type *RetTy = Op.getValueType().getTypeForEVT(*DAG.getContext()); 200975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Type *RetTyABI = RetTy; 201075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Chain = DAG.getEntryNode(); 201175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RetPtr; 201275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 201375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (RetTy->isFP128Ty()) { 201475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // Create a Stack Object to receive the return value of type f128. 201575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju ArgListEntry Entry; 201675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju int RetFI = MFI->CreateStackObject(16, 8, false); 201775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju RetPtr = DAG.getFrameIndex(RetFI, getPointerTy()); 201875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Node = RetPtr; 201975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.Ty = PointerType::getUnqual(RetTy); 202075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (!Subtarget->is64Bit()) 202175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.isSRet = true; 202275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Entry.isReturned = false; 202375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Args.push_back(Entry); 202475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju RetTyABI = Type::getVoidTy(*DAG.getContext()); 202575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 202675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 202775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju assert(Op->getNumOperands() >= numArgs && "Not enough operands!"); 202875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju for (unsigned i = 0, e = numArgs; i != e; ++i) { 202975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Chain = LowerF128_LibCallArg(Chain, Args, Op.getOperand(i), SDLoc(Op), DAG); 203075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 2031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TargetLowering::CallLoweringInfo CLI(DAG); 2032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CLI.setDebugLoc(SDLoc(Op)).setChain(Chain) 2033cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setCallee(CallingConv::C, RetTyABI, Callee, std::move(Args), 0); 2034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 203575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI); 203675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 203775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // chain is in second result. 203875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (RetTyABI == RetTy) 203975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return CallInfo.first; 204075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 204175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju assert (RetTy->isFP128Ty() && "Unexpected return type!"); 204275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 204375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Chain = CallInfo.second; 204475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 204575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // Load RetPtr to get the return value. 204675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getLoad(Op.getValueType(), 204775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDLoc(Op), 204875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Chain, 204975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju RetPtr, 205075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju MachinePointerInfo(), 205175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju false, false, false, 8); 205275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 205375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 205475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuSDValue 205575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuSparcTargetLowering::LowerF128Compare(SDValue LHS, SDValue RHS, 205675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju unsigned &SPCC, 205775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDLoc DL, 205875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SelectionDAG &DAG) const { 205975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 2060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *LibCall = nullptr; 206175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool is64Bit = Subtarget->is64Bit(); 206275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju switch(SPCC) { 206375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju default: llvm_unreachable("Unhandled conditional code!"); 206475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_E : LibCall = is64Bit? "_Qp_feq" : "_Q_feq"; break; 206575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_NE : LibCall = is64Bit? "_Qp_fne" : "_Q_fne"; break; 206675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_L : LibCall = is64Bit? "_Qp_flt" : "_Q_flt"; break; 206775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_G : LibCall = is64Bit? "_Qp_fgt" : "_Q_fgt"; break; 206875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_LE : LibCall = is64Bit? "_Qp_fle" : "_Q_fle"; break; 206975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_GE : LibCall = is64Bit? "_Qp_fge" : "_Q_fge"; break; 207075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UL : 207175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_ULE: 207275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UG : 207375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UGE: 207475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_U : 207575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_O : 207675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_LG : 207775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UE : LibCall = is64Bit? "_Qp_cmp" : "_Q_cmp"; break; 207875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 207975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 208075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Callee = DAG.getExternalSymbol(LibCall, getPointerTy()); 208175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Type *RetTy = Type::getInt32Ty(*DAG.getContext()); 208275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju ArgListTy Args; 208375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Chain = DAG.getEntryNode(); 208475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Chain = LowerF128_LibCallArg(Chain, Args, LHS, DL, DAG); 208575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Chain = LowerF128_LibCallArg(Chain, Args, RHS, DL, DAG); 208675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 2087dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TargetLowering::CallLoweringInfo CLI(DAG); 2088dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CLI.setDebugLoc(DL).setChain(Chain) 2089cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setCallee(CallingConv::C, RetTy, Callee, std::move(Args), 0); 209075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 209175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI); 209275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 209375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // result is in first, and chain is in second result. 209475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Result = CallInfo.first; 209575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 209675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju switch(SPCC) { 209775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju default: { 209875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(0, Result.getValueType()); 209975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_NE; 210075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 210175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 210275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UL : { 210375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Mask = DAG.getTargetConstant(1, Result.getValueType()); 210475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask); 210575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(0, Result.getValueType()); 210675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_NE; 210775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 210875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 210975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_ULE: { 2110bf34f346420dbcdb3f9376967bde701682471a79Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(2, Result.getValueType()); 211175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_NE; 211275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 211375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 211475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UG : { 211575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(1, Result.getValueType()); 211675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_G; 211775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 211875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 211975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UGE: { 212075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(1, Result.getValueType()); 212175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_NE; 212275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 212375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 212475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 212575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_U : { 212675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(3, Result.getValueType()); 212775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_E; 212875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 212975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 213075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_O : { 213175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(3, Result.getValueType()); 213275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_NE; 213375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 213475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 213575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_LG : { 213675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Mask = DAG.getTargetConstant(3, Result.getValueType()); 213775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask); 213875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(0, Result.getValueType()); 213975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_NE; 214075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 214175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 214275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SPCC::FCC_UE : { 214375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Mask = DAG.getTargetConstant(3, Result.getValueType()); 214475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask); 214575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue RHS = DAG.getTargetConstant(0, Result.getValueType()); 214675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SPCC = SPCC::ICC_E; 214775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS); 214875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 214975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 215075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 215175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 215275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic SDValue 215375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuLowerF128_FPEXTEND(SDValue Op, SelectionDAG &DAG, 215475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const SparcTargetLowering &TLI) { 215575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 215675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getOperand(0).getValueType() == MVT::f64) 215775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, 215875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju TLI.getLibcallName(RTLIB::FPEXT_F64_F128), 1); 215975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 216075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getOperand(0).getValueType() == MVT::f32) 216175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, 216275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju TLI.getLibcallName(RTLIB::FPEXT_F32_F128), 1); 216375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 216475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju llvm_unreachable("fpextend with non-float operand!"); 2165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SDValue(); 216675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 216775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 216875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic SDValue 216975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman GovindarajuLowerF128_FPROUND(SDValue Op, SelectionDAG &DAG, 217075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const SparcTargetLowering &TLI) { 217175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju // FP_ROUND on f64 and f32 are legal. 217275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getOperand(0).getValueType() != MVT::f128) 217375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return Op; 217475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 217575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getValueType() == MVT::f64) 217675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, 217775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju TLI.getLibcallName(RTLIB::FPROUND_F128_F64), 1); 217875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getValueType() == MVT::f32) 217975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, 218075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju TLI.getLibcallName(RTLIB::FPROUND_F128_F32), 1); 218175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 218275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju llvm_unreachable("fpround to non-float!"); 2183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SDValue(); 218475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 218575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 218675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG, 218775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const SparcTargetLowering &TLI, 218875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool hasHardQuad) { 2189ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2190fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju EVT VT = Op.getValueType(); 2191fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju assert(VT == MVT::i32 || VT == MVT::i64); 2192fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 2193fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Expand f128 operations to fp128 abi calls. 2194fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (Op.getOperand(0).getValueType() == MVT::f128 2195fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju && (!hasHardQuad || !TLI.isTypeLegal(VT))) { 2196fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju const char *libName = TLI.getLibcallName(VT == MVT::i32 2197fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju ? RTLIB::FPTOSINT_F128_I32 2198fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju : RTLIB::FPTOSINT_F128_I64); 2199fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, libName, 1); 2200fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju } 220175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 2202fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Expand if the resulting type is illegal. 2203fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (!TLI.isTypeLegal(VT)) 2204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SDValue(); 220575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 2206fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Otherwise, Convert the fp value to integer in an FP register. 2207fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (VT == MVT::i32) 2208fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0)); 2209fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju else 2210fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju Op = DAG.getNode(SPISD::FTOX, dl, MVT::f64, Op.getOperand(0)); 2211fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 2212fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return DAG.getNode(ISD::BITCAST, dl, VT, Op); 2213d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2214d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 221575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG, 221675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const SparcTargetLowering &TLI, 221775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool hasHardQuad) { 2218ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2219fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju EVT OpVT = Op.getOperand(0).getValueType(); 2220fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju assert(OpVT == MVT::i32 || (OpVT == MVT::i64)); 2221fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 2222fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju EVT floatVT = (OpVT == MVT::i32) ? MVT::f32 : MVT::f64; 2223fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 2224fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Expand f128 operations to fp128 ABI calls. 2225fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (Op.getValueType() == MVT::f128 2226fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju && (!hasHardQuad || !TLI.isTypeLegal(OpVT))) { 2227fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju const char *libName = TLI.getLibcallName(OpVT == MVT::i32 2228fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju ? RTLIB::SINTTOFP_I32_F128 2229fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju : RTLIB::SINTTOFP_I64_F128); 2230fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, libName, 1); 2231fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju } 2232fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 2233fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Expand if the operand type is illegal. 2234fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (!TLI.isTypeLegal(OpVT)) 2235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SDValue(); 2236fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 2237fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Otherwise, Convert the int value to FP in an FP register. 2238fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, floatVT, Op.getOperand(0)); 2239fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju unsigned opcode = (OpVT == MVT::i32)? SPISD::ITOF : SPISD::XTOF; 2240fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return DAG.getNode(opcode, dl, Op.getValueType(), Tmp); 2241d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2242d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 22435e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindarajustatic SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG, 22445e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju const SparcTargetLowering &TLI, 22455e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju bool hasHardQuad) { 2246fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju SDLoc dl(Op); 2247fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju EVT VT = Op.getValueType(); 2248fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 22495e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju // Expand if it does not involve f128 or the target has support for 2250fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // quad floating point instructions and the resulting type is legal. 2251fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (Op.getOperand(0).getValueType() != MVT::f128 || 2252fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju (hasHardQuad && TLI.isTypeLegal(VT))) 2253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SDValue(); 22545e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju 2255fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju assert(VT == MVT::i32 || VT == MVT::i64); 22565e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju 22575e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, 2258fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju TLI.getLibcallName(VT == MVT::i32 2259fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju ? RTLIB::FPTOUINT_F128_I32 2260fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju : RTLIB::FPTOUINT_F128_I64), 2261fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 1); 22625e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju} 22635e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju 22645e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindarajustatic SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG, 22655e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju const SparcTargetLowering &TLI, 22665e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju bool hasHardQuad) { 2267fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju SDLoc dl(Op); 2268fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju EVT OpVT = Op.getOperand(0).getValueType(); 2269fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju assert(OpVT == MVT::i32 || OpVT == MVT::i64); 2270fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 22715e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju // Expand if it does not involve f128 or the target has support for 2272fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // quad floating point instructions and the operand type is legal. 2273fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (Op.getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(OpVT))) 2274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SDValue(); 22755e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju 22765e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju return TLI.LowerF128Op(Op, DAG, 2277fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju TLI.getLibcallName(OpVT == MVT::i32 2278fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju ? RTLIB::UINTTOFP_I32_F128 2279fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju : RTLIB::UINTTOFP_I64_F128), 2280fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 1); 22815e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju} 22825e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju 228375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG, 228475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const SparcTargetLowering &TLI, 228575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool hasHardQuad) { 2286475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = Op.getOperand(0); 2287d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 2288475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LHS = Op.getOperand(2); 2289475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue RHS = Op.getOperand(3); 2290475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Dest = Op.getOperand(4); 2291ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2292d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned Opc, SPCC = ~0U; 229353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2294d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // If this is a br_cc of a "setcc", and if the setcc got lowered into 2295d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. 2296d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LookThroughSetCC(LHS, RHS, CC, SPCC); 229753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2298d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Get the condition flag. 2299475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CompareFlag; 23008534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen if (LHS.getValueType().isInteger()) { 230101021a8b93989a3c9e17dea540fe66809bf25403Venkatraman Govindaraju CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS); 2302d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); 23038534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen // 32-bit compares use the icc flags, 64-bit uses the xcc flags. 23048534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC; 2305d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } else { 230675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (!hasHardQuad && LHS.getValueType() == MVT::f128) { 230775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); 230875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG); 230975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Opc = SPISD::BRICC; 231075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } else { 231175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS); 231275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); 231375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Opc = SPISD::BRFCC; 231475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 2315d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 2316825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest, 2317825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getConstant(SPCC, MVT::i32), CompareFlag); 2318d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2319d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 232075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindarajustatic SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG, 232175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju const SparcTargetLowering &TLI, 232275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool hasHardQuad) { 2323475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LHS = Op.getOperand(0); 2324475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue RHS = Op.getOperand(1); 2325d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 2326475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue TrueVal = Op.getOperand(2); 2327475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FalseVal = Op.getOperand(3); 2328ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2329d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned Opc, SPCC = ~0U; 233053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2331d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // If this is a select_cc of a "setcc", and if the setcc got lowered into 2332d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. 2333d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner LookThroughSetCC(LHS, RHS, CC, SPCC); 233453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2335475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CompareFlag; 23360e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen if (LHS.getValueType().isInteger()) { 233701021a8b93989a3c9e17dea540fe66809bf25403Venkatraman Govindaraju CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS); 23380e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen Opc = LHS.getValueType() == MVT::i32 ? 23390e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen SPISD::SELECT_ICC : SPISD::SELECT_XCC; 2340d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); 2341d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } else { 234275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (!hasHardQuad && LHS.getValueType() == MVT::f128) { 234375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); 234475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG); 234575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Opc = SPISD::SELECT_ICC; 234675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } else { 234775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS); 234875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Opc = SPISD::SELECT_FCC; 234975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); 235075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju } 2351d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 23523484c09e0da3c05c8a78946e090c7610208d937bDale Johannesen return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal, 2353825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson DAG.getConstant(SPCC, MVT::i32), CompareFlag); 2354d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2355d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2356475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, 2357d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const SparcTargetLowering &TLI) { 23581e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman MachineFunction &MF = DAG.getMachineFunction(); 23591e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 23601e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman 23611e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Need frame address to find the address of VarArgsFrameIndex. 2362a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju MF.getFrameInfo()->setFrameAddressIsTaken(true); 2363a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju 2364d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // vastart just stores the address of the VarArgsFrameIndex slot into the 2365d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // memory location argument. 2366ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 23671e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SDValue Offset = 2368da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getNode(ISD::ADD, DL, TLI.getPointerTy(), 2369da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getRegister(SP::I6, TLI.getPointerTy()), 2370da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset())); 2371d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 2372da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1), 23736229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(SV), false, false, 0); 2374d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2375d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2376475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) { 2377ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *Node = Op.getNode(); 2378e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 2379475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InChain = Node->getOperand(0); 2380475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue VAListPtr = Node->getOperand(1); 2381da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen EVT PtrVT = VAListPtr.getValueType(); 2382d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 2383ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 2384da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SDValue VAList = DAG.getLoad(PtrVT, DL, InChain, VAListPtr, 2385d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(SV), false, false, false, 0); 2386da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Increment the pointer, VAList, to the next vaarg. 2387da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen SDValue NextPtr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 2388da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen DAG.getIntPtrConstant(VT.getSizeInBits()/8)); 2389da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Store the incremented VAList to the legalized pointer. 2390da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen InChain = DAG.getStore(VAList.getValue(1), DL, NextPtr, 23916229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner VAListPtr, MachinePointerInfo(SV), false, false, 0); 2392da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // Load the actual argument out of the pointer VAList. 2393da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen // We can't count on greater alignment than the word size. 2394da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen return DAG.getLoad(VT, DL, InChain, VAList, MachinePointerInfo(), 2395da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen false, false, false, 2396da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen std::min(PtrVT.getSizeInBits(), VT.getSizeInBits())/8); 2397d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2398d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2399f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendlingstatic SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, 2400571a02f291b051b22d804f90257e2623cbacd7ecBill Wendling const SparcSubtarget *Subtarget) { 2401475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = Op.getOperand(0); // Legalize the chain. 2402475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Size = Op.getOperand(1); // Legalize the size. 2403f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling EVT VT = Size->getValueType(0); 2404ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 240553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2406d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner unsigned SPReg = SP::O6; 2407f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); 2408f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value 2409a05dca4f9e051fad19fe9b5f6cce2715c1e5d505Dale Johannesen Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP); // Output chain 241053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2411d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // The resultant pointer is actually 16 words from the bottom of the stack, 2412d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // to provide a register spill area. 2413571a02f291b051b22d804f90257e2623cbacd7ecBill Wendling unsigned regSpillArea = Subtarget->is64Bit() ? 128 : 96; 2414571a02f291b051b22d804f90257e2623cbacd7ecBill Wendling regSpillArea += Subtarget->getStackPointerBias(); 2415571a02f291b051b22d804f90257e2623cbacd7ecBill Wendling 2416f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP, 2417f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling DAG.getConstant(regSpillArea, VT)); 2418475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[2] = { NewVal, Chain }; 2419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getMergeValues(Ops, dl); 2420d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2421d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2422d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2423fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindarajustatic SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) { 2424ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2425fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju SDValue Chain = DAG.getNode(SPISD::FLUSHW, 2426860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju dl, MVT::Other, DAG.getEntryNode()); 2427860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju return Chain; 2428860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju} 2429860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 243036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, 243136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SparcSubtarget *Subtarget) { 2432860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 2433860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju MFI->setFrameAddressIsTaken(true); 2434860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 2435860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju EVT VT = Op.getValueType(); 2436ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2437860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju unsigned FrameReg = SP::I6; 243836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned stackBias = Subtarget->getStackPointerBias(); 2439860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 2440860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju SDValue FrameAddr; 244136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 244236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (depth == 0) { 2443860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 244436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->is64Bit()) 244536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 244636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DAG.getIntPtrConstant(stackBias)); 244736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return FrameAddr; 2448860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju } 244936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 245036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // flush first to make sure the windowed registers' values are in stack 245136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Chain = getFLUSHW(Op, DAG); 245236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); 245336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 245436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56; 245536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 245636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (depth--) { 245736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 245836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DAG.getIntPtrConstant(Offset)); 245936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(), 246036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false, false, 0); 246136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 246236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->is64Bit()) 246336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 246436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DAG.getIntPtrConstant(stackBias)); 2465860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju return FrameAddr; 2466860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju} 2467860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 246836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 246936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, 247036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SparcSubtarget *Subtarget) { 247136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 247236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t depth = Op.getConstantOperandVal(0); 247336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 247436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getFRAMEADDR(depth, Op, DAG, Subtarget); 247536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 247636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 247736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24788717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindarajustatic SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, 247936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SparcTargetLowering &TLI, 248036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SparcSubtarget *Subtarget) { 24818717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju MachineFunction &MF = DAG.getMachineFunction(); 24828717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju MachineFrameInfo *MFI = MF.getFrameInfo(); 2483860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju MFI->setReturnAddressIsTaken(true); 2484860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 248536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TLI.verifyReturnAddressArgumentIsConstant(Op, DAG)) 248636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SDValue(); 248736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2488860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju EVT VT = Op.getValueType(); 2489ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 2490860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju uint64_t depth = Op.getConstantOperandVal(0); 2491860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 2492860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju SDValue RetAddr; 24938717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju if (depth == 0) { 24948717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju unsigned RetReg = MF.addLiveIn(SP::I7, 24958717679c449db5555ec0ce2873bbbe53106f4c88Venkatraman Govindaraju TLI.getRegClassFor(TLI.getPointerTy())); 2496860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT); 249736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RetAddr; 2498860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju } 249936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 250036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Need frame address to find return address of the caller. 250136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget); 250236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 250336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60; 250436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Ptr = DAG.getNode(ISD::ADD, 250536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dl, VT, 250636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameAddr, 250736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DAG.getIntPtrConstant(Offset)); 250836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr, 250936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachinePointerInfo(), false, false, false, 0); 251036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2511860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju return RetAddr; 2512860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju} 2513860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju 251420b5879e0ec5c926c3b636ad36d5b6cfb278f736Venkatraman Govindarajustatic SDValue LowerF64Op(SDValue Op, SelectionDAG &DAG, unsigned opcode) 25151799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju{ 25161799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDLoc dl(Op); 25171799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 25181799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju assert(Op.getValueType() == MVT::f64 && "LowerF64Op called on non-double!"); 251920b5879e0ec5c926c3b636ad36d5b6cfb278f736Venkatraman Govindaraju assert(opcode == ISD::FNEG || opcode == ISD::FABS); 25201799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 25211799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // Lower fneg/fabs on f64 to fneg/fabs on f32. 25221799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // fneg f64 => fneg f32:sub_even, fmov f32:sub_odd. 25231799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju // fabs f64 => fabs f32:sub_even, fmov f32:sub_odd. 25241799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 25251799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue SrcReg64 = Op.getOperand(0); 25261799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue Hi32 = DAG.getTargetExtractSubreg(SP::sub_even, dl, MVT::f32, 25271799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SrcReg64); 25281799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue Lo32 = DAG.getTargetExtractSubreg(SP::sub_odd, dl, MVT::f32, 25291799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SrcReg64); 25301799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 253120b5879e0ec5c926c3b636ad36d5b6cfb278f736Venkatraman Govindaraju Hi32 = DAG.getNode(opcode, dl, MVT::f32, Hi32); 25321799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 25331799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju SDValue DstReg64 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, 25341799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju dl, MVT::f64), 0); 25351799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64 = DAG.getTargetInsertSubreg(SP::sub_even, dl, MVT::f64, 25361799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64, Hi32); 25371799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64 = DAG.getTargetInsertSubreg(SP::sub_odd, dl, MVT::f64, 25381799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju DstReg64, Lo32); 25391799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju return DstReg64; 25401799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju} 25411799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 25422f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju// Lower a f128 load into two f64 loads. 25432f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindarajustatic SDValue LowerF128Load(SDValue Op, SelectionDAG &DAG) 25442f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju{ 25452f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDLoc dl(Op); 25462f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode()); 25472f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju assert(LdNode && LdNode->getOffset().getOpcode() == ISD::UNDEF 25482f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju && "Unexpected node type"); 25492f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 2550a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju unsigned alignment = LdNode->getAlignment(); 2551a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju if (alignment > 8) 2552a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju alignment = 8; 2553a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju 25542f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue Hi64 = DAG.getLoad(MVT::f64, 25552f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, 25562f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LdNode->getChain(), 25572f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LdNode->getBasePtr(), 25582f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LdNode->getPointerInfo(), 2559a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju false, false, false, alignment); 25602f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju EVT addrVT = LdNode->getBasePtr().getValueType(); 25612f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT, 25622f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LdNode->getBasePtr(), 25632f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju DAG.getConstant(8, addrVT)); 25642f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue Lo64 = DAG.getLoad(MVT::f64, 25652f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, 25662f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LdNode->getChain(), 25672f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LoPtr, 25682f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LdNode->getPointerInfo(), 2569a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju false, false, false, alignment); 25702f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 25712f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, MVT::i32); 25722f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue SubRegOdd = DAG.getTargetConstant(SP::sub_odd64, MVT::i32); 25732f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 25742f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDNode *InFP128 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, 25752f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, MVT::f128); 25762f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, dl, 25772f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju MVT::f128, 25782f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue(InFP128, 0), 25792f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju Hi64, 25802f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SubRegEven); 25812f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, dl, 25822f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju MVT::f128, 25832f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue(InFP128, 0), 25842f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju Lo64, 25852f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SubRegOdd); 25862f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue OutChains[2] = { SDValue(Hi64.getNode(), 1), 25872f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue(Lo64.getNode(), 1) }; 2588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SDValue OutChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); 25892f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue Ops[2] = {SDValue(InFP128,0), OutChain}; 2590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getMergeValues(Ops, dl); 25912f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju} 25922f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 25932f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju// Lower a f128 store into two f64 stores. 25942f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindarajustatic SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG) { 25952f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDLoc dl(Op); 25962f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode()); 25972f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju assert(StNode && StNode->getOffset().getOpcode() == ISD::UNDEF 25982f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju && "Unexpected node type"); 25992f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, MVT::i32); 26002f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue SubRegOdd = DAG.getTargetConstant(SP::sub_odd64, MVT::i32); 26012f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 26022f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, 26032f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, 26042f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju MVT::f64, 26052f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju StNode->getValue(), 26062f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SubRegEven); 26072f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, 26082f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, 26092f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju MVT::f64, 26102f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju StNode->getValue(), 26112f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SubRegOdd); 2612a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju 2613a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju unsigned alignment = StNode->getAlignment(); 2614a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju if (alignment > 8) 2615a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju alignment = 8; 2616a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju 26172f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue OutChains[2]; 26182f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju OutChains[0] = DAG.getStore(StNode->getChain(), 26192f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, 26202f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue(Hi64, 0), 26212f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju StNode->getBasePtr(), 26222f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju MachinePointerInfo(), 2623a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju false, false, alignment); 26242f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju EVT addrVT = StNode->getBasePtr().getValueType(); 26252f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT, 26262f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju StNode->getBasePtr(), 26272f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju DAG.getConstant(8, addrVT)); 26282f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju OutChains[1] = DAG.getStore(StNode->getChain(), 26292f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju dl, 26302f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju SDValue(Lo64, 0), 26312f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju LoPtr, 26322f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju MachinePointerInfo(), 2633a8147756d681f100e58e88aae842aebf4f51693dVenkatraman Govindaraju false, false, alignment); 2634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); 26352f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju} 26362f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 263736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) { 263836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) 263936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines && "invalid opcode"); 264075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 264175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getValueType() == MVT::f64) 264236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return LowerF64Op(Op, DAG, Op.getOpcode()); 264375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (Op.getValueType() != MVT::f128) 264475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return Op; 264575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 264636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Lower fabs/fneg on f128 to fabs/fneg on f64 264736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64 264875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 264975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDLoc dl(Op); 265075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue SrcReg128 = Op.getOperand(0); 265175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Hi64 = DAG.getTargetExtractSubreg(SP::sub_even64, dl, MVT::f64, 265275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SrcReg128); 265375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue Lo64 = DAG.getTargetExtractSubreg(SP::sub_odd64, dl, MVT::f64, 265475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SrcReg128); 265575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju if (isV9) 265675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64); 265775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju else 265836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Hi64 = LowerF64Op(Hi64, DAG, Op.getOpcode()); 265975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 266075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, 266175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju dl, MVT::f128), 0); 266275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju DstReg128 = DAG.getTargetInsertSubreg(SP::sub_even64, dl, MVT::f128, 266375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju DstReg128, Hi64); 266475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju DstReg128 = DAG.getTargetInsertSubreg(SP::sub_odd64, dl, MVT::f128, 266575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju DstReg128, Lo64); 266675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju return DstReg128; 266775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju} 266875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 266920b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindarajustatic SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) { 267075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 267120b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju if (Op.getValueType() != MVT::i64) 267220b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju return Op; 267320b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju 267420b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDLoc dl(Op); 267520b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Src1 = Op.getOperand(0); 267620b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Src1Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src1); 267720b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Src1Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Src1, 267820b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju DAG.getConstant(32, MVT::i64)); 267920b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Src1Hi = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src1Hi); 268020b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju 268120b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Src2 = Op.getOperand(1); 268220b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Src2Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src2); 268320b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Src2Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Src2, 268420b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju DAG.getConstant(32, MVT::i64)); 268520b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Src2Hi = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src2Hi); 268620b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju 268720b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju 268820b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju bool hasChain = false; 268920b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju unsigned hiOpc = Op.getOpcode(); 269020b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju switch (Op.getOpcode()) { 269120b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju default: llvm_unreachable("Invalid opcode"); 269220b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::ADDC: hiOpc = ISD::ADDE; break; 269320b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::ADDE: hasChain = true; break; 269420b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::SUBC: hiOpc = ISD::SUBE; break; 269520b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::SUBE: hasChain = true; break; 269620b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju } 269720b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Lo; 269820b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Glue); 269920b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju if (hasChain) { 270020b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Lo = DAG.getNode(Op.getOpcode(), dl, VTs, Src1Lo, Src2Lo, 270120b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Op.getOperand(2)); 270220b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju } else { 270320b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Lo = DAG.getNode(Op.getOpcode(), dl, VTs, Src1Lo, Src2Lo); 270420b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju } 270520b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Hi = DAG.getNode(hiOpc, dl, VTs, Src1Hi, Src2Hi, Lo.getValue(1)); 270620b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Carry = Hi.getValue(1); 270720b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju 270820b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Lo); 270920b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Hi = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Hi); 271020b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju Hi = DAG.getNode(ISD::SHL, dl, MVT::i64, Hi, 271120b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju DAG.getConstant(32, MVT::i64)); 271220b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju 271320b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Dst = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, Lo); 271420b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju SDValue Ops[2] = { Dst, Carry }; 2715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getMergeValues(Ops, dl); 271620b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju} 271775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 271836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode() 271936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// in LegalizeDAG.cpp except the order of arguments to the library function. 272036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG, 272136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SparcTargetLowering &TLI) 272236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{ 272336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned opcode = Op.getOpcode(); 272436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode."); 272536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 272636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isSigned = (opcode == ISD::SMULO); 272736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EVT VT = MVT::i64; 272836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EVT WideVT = MVT::i128; 272936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDLoc dl(Op); 273036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue LHS = Op.getOperand(0); 273136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 273236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LHS.getValueType() != VT) 273336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Op; 273436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 273536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue ShiftAmt = DAG.getConstant(63, VT); 273636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 273736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue RHS = Op.getOperand(1); 273836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt); 273936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt); 274036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Args[] = { HiLHS, LHS, HiRHS, RHS }; 274136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 274236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue MulResult = TLI.makeLibCall(DAG, 274336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RTLIB::MUL_I128, WideVT, 274436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Args, 4, isSigned, dl).first; 274536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, 274636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MulResult, DAG.getIntPtrConstant(0)); 274736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, 274836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MulResult, DAG.getIntPtrConstant(1)); 274936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isSigned) { 275036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt); 275136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE); 275236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 275336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, VT), 275436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ISD::SETNE); 275536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 275636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // MulResult is a node with an illegal type. Because such things are not 275736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // generally permitted during this phase of legalization, delete the 275836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // node. The above EXTRACT_ELEMENT nodes should have been folded. 275936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DAG.DeleteNode(MulResult.getNode()); 276036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 276136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDValue Ops[2] = { BottomHalf, TopHalf } ; 2762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getMergeValues(Ops, dl); 276336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 276436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 276536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) { 276636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Monotonic load/stores are legal. 276736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (cast<AtomicSDNode>(Op)->getOrdering() <= Monotonic) 276836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Op; 276936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 277036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Otherwise, expand with a fence. 277136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SDValue(); 277236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 277336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 277436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2775475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SparcTargetLowering:: 2776d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerOperation(SDValue Op, SelectionDAG &DAG) const { 277775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 277875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool hasHardQuad = Subtarget->hasHardQuad(); 277975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju bool isV9 = Subtarget->isV9(); 278075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju 2781d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner switch (Op.getOpcode()) { 2782c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Should not custom lower this!"); 27831799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju 278436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this, 278536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Subtarget); 278636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG, 278736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Subtarget); 27887d052f272d3f9ad0acdebf6811e29d529f70c1e1Venkatraman Govindaraju case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 2789db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 2790e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 2791db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 279275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG, *this, 279375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju hasHardQuad); 279475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG, *this, 279575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju hasHardQuad); 27965e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju case ISD::FP_TO_UINT: return LowerFP_TO_UINT(Op, DAG, *this, 27975e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju hasHardQuad); 27985e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG, *this, 27995e45051e0ee8917a88e84d799c5c90840d0c465bVenkatraman Govindaraju hasHardQuad); 280075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::BR_CC: return LowerBR_CC(Op, DAG, *this, 280175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju hasHardQuad); 280275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, *this, 280375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju hasHardQuad); 2804d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::VASTART: return LowerVASTART(Op, DAG, *this); 2805d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case ISD::VAARG: return LowerVAARG(Op, DAG); 2806f63e418d2c299a540ac27ddfed69b2c4698bb3c3Bill Wendling case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG, 2807571a02f291b051b22d804f90257e2623cbacd7ecBill Wendling Subtarget); 28082f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju 28092f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju case ISD::LOAD: return LowerF128Load(Op, DAG); 28102f17d0facf6a489a051c86c015453c2b102e5c37Venkatraman Govindaraju case ISD::STORE: return LowerF128Store(Op, DAG); 281175ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FADD: return LowerF128Op(Op, DAG, 281275ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju getLibcallName(RTLIB::ADD_F128), 2); 281375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FSUB: return LowerF128Op(Op, DAG, 281475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju getLibcallName(RTLIB::SUB_F128), 2); 281575ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FMUL: return LowerF128Op(Op, DAG, 281675ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju getLibcallName(RTLIB::MUL_F128), 2); 281775ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FDIV: return LowerF128Op(Op, DAG, 281875ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju getLibcallName(RTLIB::DIV_F128), 2); 281975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FSQRT: return LowerF128Op(Op, DAG, 282075ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju getLibcallName(RTLIB::SQRT_F128),1); 282136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::FABS: 282236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::FNEG: return LowerFNEGorFABS(Op, DAG, isV9); 282375ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FP_EXTEND: return LowerF128_FPEXTEND(Op, DAG, *this); 282475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case ISD::FP_ROUND: return LowerF128_FPROUND(Op, DAG, *this); 282520b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::ADDC: 282620b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::ADDE: 282720b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::SUBC: 282820b10abf4e88ca532810fbf749b029ce582d6793Venkatraman Govindaraju case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG); 282936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::UMULO: 283036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::SMULO: return LowerUMULO_SMULO(Op, DAG, *this); 283136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::ATOMIC_LOAD: 283236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::ATOMIC_STORE: return LowerATOMIC_LOAD_STORE(Op, DAG); 2833d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 2834d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 2835d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 2836d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris LattnerMachineBasicBlock * 2837d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris LattnerSparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 2838af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 2839d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner switch (MI->getOpcode()) { 2840c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown SELECT_CC!"); 2841d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_Int_ICC: 2842d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_FP_ICC: 2843d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_DFP_ICC: 284475ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SP::SELECT_CC_QFP_ICC: 284536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandSelectCC(MI, BB, SP::BCOND); 2846d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_Int_FCC: 2847d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_FP_FCC: 2848d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner case SP::SELECT_CC_DFP_FCC: 284975ddb2bb34f96c2bda48d0e86331fb52b55b8d03Venkatraman Govindaraju case SP::SELECT_CC_QFP_FCC: 285036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandSelectCC(MI, BB, SP::FBCOND); 285136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 285236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_ADD_32: 285336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ADDrr); 285436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_ADD_64: 285536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ADDXrr); 285636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_SUB_32: 285736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::SUBrr); 285836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_SUB_64: 285936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::SUBXrr); 286036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_AND_32: 286136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ANDrr); 286236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_AND_64: 286336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ANDXrr); 286436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_OR_32: 286536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ORrr); 286636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_OR_64: 286736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ORXrr); 286836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_XOR_32: 286936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::XORrr); 287036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_XOR_64: 287136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::XORXrr); 287236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_NAND_32: 287336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ANDrr); 287436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_NAND_64: 287536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::ANDXrr); 287636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 287736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_SWAP_64: 287836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, 0); 287936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 288036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_MAX_32: 288136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_G); 288236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_MAX_64: 288336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_G); 288436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_MIN_32: 288536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_LE); 288636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_MIN_64: 288736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_LE); 288836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_UMAX_32: 288936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_GU); 289036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_UMAX_64: 289136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_GU); 289236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_UMIN_32: 289336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_LEU); 289436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::ATOMIC_LOAD_UMIN_64: 289536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_LEU); 2896d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner } 289736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 2898d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner 289936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMachineBasicBlock* 290036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSparcTargetLowering::expandSelectCC(MachineInstr *MI, 290136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock *BB, 290236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned BROpcode) const { 290336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 290436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DebugLoc dl = MI->getDebugLoc(); 290536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CC = (SPCC::CondCodes)MI->getOperand(3).getImm(); 290653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2907d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 2908d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // control-flow pattern. The incoming instruction knows the destination vreg 2909d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // to set, the condition code register to branch on, the true/false values to 2910d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // select between, and a branch opcode to use. 2911d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner const BasicBlock *LLVM_BB = BB->getBasicBlock(); 29128e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineFunction::iterator It = BB; 2913d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner ++It; 291453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2915d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // thisMBB: 2916d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // ... 2917d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // TrueVal = ... 2918d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // [f]bCC copy1MBB 2919d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // fallthrough --> copy0MBB 2920d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineBasicBlock *thisMBB = BB; 2921d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner MachineFunction *F = BB->getParent(); 29228e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 29238e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 2924f661277a9b26590648aca585c0572f200470290dVenkatraman Govindaraju F->insert(It, copy0MBB); 2925f661277a9b26590648aca585c0572f200470290dVenkatraman Govindaraju F->insert(It, sinkMBB); 292614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 292714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman // Transfer the remainder of BB and its successor edges to sinkMBB. 292814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman sinkMBB->splice(sinkMBB->begin(), BB, 292936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::next(MachineBasicBlock::iterator(MI)), 293014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 293114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 293214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 293314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman // Add the true and fallthrough blocks as its successors. 293414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->addSuccessor(copy0MBB); 293514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->addSuccessor(sinkMBB); 293614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 2937d552eee4a05789e80ef3298df473edb888471302Dale Johannesen BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC); 293853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2939d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // copy0MBB: 2940d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // %FalseValue = ... 2941d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // # fallthrough to sinkMBB 2942d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BB = copy0MBB; 294353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2944d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // Update machine-CFG edges 2945d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BB->addSuccessor(sinkMBB); 294653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 2947d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // sinkMBB: 2948d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 2949d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner // ... 2950d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner BB = sinkMBB; 295114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(SP::PHI), MI->getOperand(0).getReg()) 2952d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 2953d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 295453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov 295514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 2956d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner return BB; 2957d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner} 29580eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 295936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMachineBasicBlock* 296036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSparcTargetLowering::expandAtomicRMW(MachineInstr *MI, 296136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock *MBB, 296236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Opcode, 296336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CondCode) const { 296436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 296536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 296636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DebugLoc DL = MI->getDebugLoc(); 296736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 296836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // MI is an atomic read-modify-write instruction of the form: 296936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 297036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // rd = atomicrmw<op> addr, rs2 297136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 297236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // All three operands are registers. 297336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned DestReg = MI->getOperand(0).getReg(); 297436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned AddrReg = MI->getOperand(1).getReg(); 297536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Rs2Reg = MI->getOperand(2).getReg(); 297636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 297736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // SelectionDAG has already inserted memory barriers before and after MI, so 297836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // we simply have to implement the operatiuon in terms of compare-and-swap. 297936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 298036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // %val0 = load %addr 298136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // loop: 298236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // %val = phi %val0, %dest 298336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // %upd = op %val, %rs2 298436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // %dest = cas %addr, %val, %upd 298536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // cmp %val, %dest 298636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // bne loop 298736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // done: 298836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 298936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool is64Bit = SP::I64RegsRegClass.hasSubClassEq(MRI.getRegClass(DestReg)); 299036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const TargetRegisterClass *ValueRC = 299136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines is64Bit ? &SP::I64RegsRegClass : &SP::IntRegsRegClass; 299236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Val0Reg = MRI.createVirtualRegister(ValueRC); 299336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 299436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(*MBB, MI, DL, TII.get(is64Bit ? SP::LDXri : SP::LDri), Val0Reg) 299536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addReg(AddrReg).addImm(0); 299636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 299736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Split the basic block MBB before MI and insert the loop block in the hole. 299836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFunction::iterator MFI = MBB; 299936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const BasicBlock *LLVM_BB = MBB->getBasicBlock(); 300036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFunction *MF = MBB->getParent(); 300136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock *LoopMBB = MF->CreateMachineBasicBlock(LLVM_BB); 300236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock *DoneMBB = MF->CreateMachineBasicBlock(LLVM_BB); 300336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++MFI; 300436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MF->insert(MFI, LoopMBB); 300536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MF->insert(MFI, DoneMBB); 300636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 300736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Move MI and following instructions to DoneMBB. 300836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DoneMBB->splice(DoneMBB->begin(), MBB, MI, MBB->end()); 300936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DoneMBB->transferSuccessorsAndUpdatePHIs(MBB); 301036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 301136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Connect the CFG again. 301236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MBB->addSuccessor(LoopMBB); 301336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoopMBB->addSuccessor(LoopMBB); 301436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoopMBB->addSuccessor(DoneMBB); 301536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 301636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Build the loop block. 301736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ValReg = MRI.createVirtualRegister(ValueRC); 301836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Opcode == 0 means try to write Rs2Reg directly (ATOMIC_SWAP). 301936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned UpdReg = (Opcode ? MRI.createVirtualRegister(ValueRC) : Rs2Reg); 302036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 302136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(SP::PHI), ValReg) 302236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addReg(Val0Reg).addMBB(MBB) 302336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addReg(DestReg).addMBB(LoopMBB); 302436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 302536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CondCode) { 302636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This is one of the min/max operations. We need a CMPrr followed by a 302736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // MOVXCC/MOVICC. 302836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(Rs2Reg); 302936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg) 303036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addReg(ValReg).addReg(Rs2Reg).addImm(CondCode); 303136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Opcode) { 303236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg) 303336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addReg(ValReg).addReg(Rs2Reg); 303436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 303536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 303636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MI->getOpcode() == SP::ATOMIC_LOAD_NAND_32 || 303736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI->getOpcode() == SP::ATOMIC_LOAD_NAND_64) { 303836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned TmpReg = UpdReg; 303936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines UpdReg = MRI.createVirtualRegister(ValueRC); 304036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(SP::XORri), UpdReg).addReg(TmpReg).addImm(-1); 304136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 304236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 304336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(is64Bit ? SP::CASXrr : SP::CASrr), DestReg) 304436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addReg(AddrReg).addReg(ValReg).addReg(UpdReg) 304536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 304636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(DestReg); 304736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(LoopMBB, DL, TII.get(is64Bit ? SP::BPXCC : SP::BCOND)) 304836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addMBB(LoopMBB).addImm(SPCC::ICC_NE); 304936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 305036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI->eraseFromParent(); 305136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return DoneMBB; 305236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 305336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30540eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//===----------------------------------------------------------------------===// 30550eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov// Sparc Inline Assembly Support 30560eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//===----------------------------------------------------------------------===// 30570eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 30580eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 30590eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov/// constraint it is for this target. 30600eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::ConstraintType 30610eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::getConstraintType(const std::string &Constraint) const { 30620eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov if (Constraint.size() == 1) { 30630eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov switch (Constraint[0]) { 30640eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov default: break; 30650eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov case 'r': return C_RegisterClass; 306636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'I': // SIMM13 306736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return C_Other; 30680eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 30690eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 30700eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 30710eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 30720eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov} 30730eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 307436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTargetLowering::ConstraintWeight SparcTargetLowering:: 307536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesgetSingleConstraintMatchWeight(AsmOperandInfo &info, 307636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *constraint) const { 307736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstraintWeight weight = CW_Invalid; 307836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *CallOperandVal = info.CallOperandVal; 307936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If we don't have a value, we can't do a match, 308036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // but allow it at the lowest weight. 3081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!CallOperandVal) 308236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CW_Default; 308336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 308436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Look at the constraint type. 308536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (*constraint) { 308636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 308736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); 308836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 308936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'I': // SIMM13 309036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) { 309136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isInt<13>(C->getSExtValue())) 309236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines weight = CW_Constant; 309336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 309436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 309536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 309636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return weight; 309736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 309836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 309936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops 310036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// vector. If it is invalid, don't add anything to Ops. 310136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid SparcTargetLowering:: 310236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesLowerAsmOperandForConstraint(SDValue Op, 310336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string &Constraint, 310436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::vector<SDValue> &Ops, 310536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SelectionDAG &DAG) const { 3106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SDValue Result(nullptr, 0); 310736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 310836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Only support length 1 constraints for now. 310936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Constraint.length() > 1) 311036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 311136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 311236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char ConstraintLetter = Constraint[0]; 311336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (ConstraintLetter) { 311436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: break; 311536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'I': 311636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) { 311736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isInt<13>(C->getSExtValue())) { 311836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = DAG.getTargetConstant(C->getSExtValue(), Op.getValueType()); 311936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 312036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 312136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 312236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 312336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 312436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 312536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Result.getNode()) { 312636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ops.push_back(Result); 312736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 312836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 312936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); 313036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 313136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31320eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 31330eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, 31345b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier MVT VT) const { 31350eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov if (Constraint.size() == 1) { 31360eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov switch (Constraint[0]) { 31370eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov case 'r': 3138c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper return std::make_pair(0U, &SP::IntRegsRegClass); 31390eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 314036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (!Constraint.empty() && Constraint.size() <= 5 314136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines && Constraint[0] == '{' && *(Constraint.end()-1) == '}') { 314236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // constraint = '{r<d>}' 314336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Remove the braces from around the name. 314436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef name(Constraint.data()+1, Constraint.size()-2); 314536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Handle register aliases: 314636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // r0-r7 -> g0-g7 314736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // r8-r15 -> o0-o7 314836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // r16-r23 -> l0-l7 314936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // r24-r31 -> i0-i7 315036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t intVal = 0; 315136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (name.substr(0, 1).equals("r") 315236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines && !name.substr(1).getAsInteger(10, intVal) && intVal <= 31) { 315336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char regTypes[] = { 'g', 'o', 'l', 'i' }; 315436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char regType = regTypes[intVal/8]; 315536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char regIdx = '0' + (intVal % 8); 315636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char tmp[] = { '{', regType, regIdx, '}', 0 }; 315736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string newConstraint = std::string(tmp); 315836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TargetLowering::getRegForInlineAsmConstraint(newConstraint, VT); 315936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 31600eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov } 31610eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 31620eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 31630eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov} 31640eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov 31656520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohmanbool 31666520e20e4fb31f2e65e25c38b372b19d33a83df4Dan GohmanSparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { 31676520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman // The Sparc target isn't yet aware of offsets. 31686520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman return false; 31696520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman} 3170fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3171fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindarajuvoid SparcTargetLowering::ReplaceNodeResults(SDNode *N, 3172fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju SmallVectorImpl<SDValue>& Results, 3173fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju SelectionDAG &DAG) const { 3174fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3175fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju SDLoc dl(N); 3176fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3177fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju RTLIB::Libcall libCall = RTLIB::UNKNOWN_LIBCALL; 3178fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3179fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju switch (N->getOpcode()) { 3180fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju default: 3181fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju llvm_unreachable("Do not know how to custom type legalize this operation!"); 3182fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3183fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju case ISD::FP_TO_SINT: 3184fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju case ISD::FP_TO_UINT: 3185fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Custom lower only if it involves f128 or i64. 3186fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (N->getOperand(0).getValueType() != MVT::f128 3187fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju || N->getValueType(0) != MVT::i64) 3188fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return; 3189fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju libCall = ((N->getOpcode() == ISD::FP_TO_SINT) 3190fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju ? RTLIB::FPTOSINT_F128_I64 3191fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju : RTLIB::FPTOUINT_F128_I64); 3192fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3193fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju Results.push_back(LowerF128Op(SDValue(N, 0), 3194fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju DAG, 3195fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju getLibcallName(libCall), 3196fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 1)); 3197fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return; 3198fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3199fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju case ISD::SINT_TO_FP: 3200fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju case ISD::UINT_TO_FP: 3201fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju // Custom lower only if it involves f128 or i64. 3202fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju if (N->getValueType(0) != MVT::f128 3203fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju || N->getOperand(0).getValueType() != MVT::i64) 3204fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return; 3205fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3206fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju libCall = ((N->getOpcode() == ISD::SINT_TO_FP) 3207fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju ? RTLIB::SINTTOFP_I64_F128 3208fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju : RTLIB::UINTTOFP_I64_F128); 3209fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 3210fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju Results.push_back(LowerF128Op(SDValue(N, 0), 3211fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju DAG, 3212fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju getLibcallName(libCall), 3213fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju 1)); 3214fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju return; 3215fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju } 3216fcd5e86396e121fef7ad11d41cc8bc0a541631b2Venkatraman Govindaraju} 3217