xref: /openbsd-src/gnu/llvm/llvm/lib/Target/Sparc/SparcISelLowering.cpp (revision a96b36398fcfb4953e8190127da8bf074c7552f1)
109467b48Spatrick //===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file implements the interfaces that Sparc uses to lower LLVM code into a
1009467b48Spatrick // selection DAG.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick 
1409467b48Spatrick #include "SparcISelLowering.h"
1509467b48Spatrick #include "MCTargetDesc/SparcMCExpr.h"
1609467b48Spatrick #include "SparcMachineFunctionInfo.h"
1709467b48Spatrick #include "SparcRegisterInfo.h"
1809467b48Spatrick #include "SparcTargetMachine.h"
1909467b48Spatrick #include "SparcTargetObjectFile.h"
2009467b48Spatrick #include "llvm/ADT/StringExtras.h"
2109467b48Spatrick #include "llvm/ADT/StringSwitch.h"
2209467b48Spatrick #include "llvm/CodeGen/CallingConvLower.h"
2309467b48Spatrick #include "llvm/CodeGen/MachineFrameInfo.h"
2409467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
2509467b48Spatrick #include "llvm/CodeGen/MachineInstrBuilder.h"
2609467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
2709467b48Spatrick #include "llvm/CodeGen/SelectionDAG.h"
28*a96b3639Srobert #include "llvm/CodeGen/SelectionDAGNodes.h"
2909467b48Spatrick #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
3009467b48Spatrick #include "llvm/IR/DerivedTypes.h"
3109467b48Spatrick #include "llvm/IR/Function.h"
3209467b48Spatrick #include "llvm/IR/Module.h"
3309467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3409467b48Spatrick #include "llvm/Support/KnownBits.h"
3509467b48Spatrick using namespace llvm;
3609467b48Spatrick 
3709467b48Spatrick 
3809467b48Spatrick //===----------------------------------------------------------------------===//
3909467b48Spatrick // Calling Convention Implementation
4009467b48Spatrick //===----------------------------------------------------------------------===//
4109467b48Spatrick 
CC_Sparc_Assign_SRet(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)4209467b48Spatrick static bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT,
4309467b48Spatrick                                  MVT &LocVT, CCValAssign::LocInfo &LocInfo,
4409467b48Spatrick                                  ISD::ArgFlagsTy &ArgFlags, CCState &State)
4509467b48Spatrick {
4609467b48Spatrick   assert (ArgFlags.isSRet());
4709467b48Spatrick 
4809467b48Spatrick   // Assign SRet argument.
4909467b48Spatrick   State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
5009467b48Spatrick                                          0,
5109467b48Spatrick                                          LocVT, LocInfo));
5209467b48Spatrick   return true;
5309467b48Spatrick }
5409467b48Spatrick 
CC_Sparc_Assign_Split_64(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)5509467b48Spatrick static bool CC_Sparc_Assign_Split_64(unsigned &ValNo, MVT &ValVT,
5609467b48Spatrick                                      MVT &LocVT, CCValAssign::LocInfo &LocInfo,
5709467b48Spatrick                                      ISD::ArgFlagsTy &ArgFlags, CCState &State)
5809467b48Spatrick {
5909467b48Spatrick   static const MCPhysReg RegList[] = {
6009467b48Spatrick     SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
6109467b48Spatrick   };
6209467b48Spatrick   // Try to get first reg.
63097a140dSpatrick   if (Register Reg = State.AllocateReg(RegList)) {
6409467b48Spatrick     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
6509467b48Spatrick   } else {
6609467b48Spatrick     // Assign whole thing in stack.
67097a140dSpatrick     State.addLoc(CCValAssign::getCustomMem(
68097a140dSpatrick         ValNo, ValVT, State.AllocateStack(8, Align(4)), LocVT, LocInfo));
6909467b48Spatrick     return true;
7009467b48Spatrick   }
7109467b48Spatrick 
7209467b48Spatrick   // Try to get second reg.
73097a140dSpatrick   if (Register Reg = State.AllocateReg(RegList))
7409467b48Spatrick     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
7509467b48Spatrick   else
76097a140dSpatrick     State.addLoc(CCValAssign::getCustomMem(
77097a140dSpatrick         ValNo, ValVT, State.AllocateStack(4, Align(4)), LocVT, LocInfo));
7809467b48Spatrick   return true;
7909467b48Spatrick }
8009467b48Spatrick 
CC_Sparc_Assign_Ret_Split_64(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)8109467b48Spatrick static bool CC_Sparc_Assign_Ret_Split_64(unsigned &ValNo, MVT &ValVT,
8209467b48Spatrick                                          MVT &LocVT, CCValAssign::LocInfo &LocInfo,
8309467b48Spatrick                                          ISD::ArgFlagsTy &ArgFlags, CCState &State)
8409467b48Spatrick {
8509467b48Spatrick   static const MCPhysReg RegList[] = {
8609467b48Spatrick     SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
8709467b48Spatrick   };
8809467b48Spatrick 
8909467b48Spatrick   // Try to get first reg.
90097a140dSpatrick   if (Register Reg = State.AllocateReg(RegList))
9109467b48Spatrick     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
9209467b48Spatrick   else
9309467b48Spatrick     return false;
9409467b48Spatrick 
9509467b48Spatrick   // Try to get second reg.
96097a140dSpatrick   if (Register Reg = State.AllocateReg(RegList))
9709467b48Spatrick     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
9809467b48Spatrick   else
9909467b48Spatrick     return false;
10009467b48Spatrick 
10109467b48Spatrick   return true;
10209467b48Spatrick }
10309467b48Spatrick 
10409467b48Spatrick // Allocate a full-sized argument for the 64-bit ABI.
Analyze_CC_Sparc64_Full(bool IsReturn,unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)105*a96b3639Srobert static bool Analyze_CC_Sparc64_Full(bool IsReturn, unsigned &ValNo, MVT &ValVT,
10609467b48Spatrick                                     MVT &LocVT, CCValAssign::LocInfo &LocInfo,
10709467b48Spatrick                                     ISD::ArgFlagsTy &ArgFlags, CCState &State) {
10809467b48Spatrick   assert((LocVT == MVT::f32 || LocVT == MVT::f128
10909467b48Spatrick           || LocVT.getSizeInBits() == 64) &&
11009467b48Spatrick          "Can't handle non-64 bits locations");
11109467b48Spatrick 
11209467b48Spatrick   // Stack space is allocated for all arguments starting from [%fp+BIAS+128].
11309467b48Spatrick   unsigned size      = (LocVT == MVT::f128) ? 16 : 8;
114097a140dSpatrick   Align alignment = (LocVT == MVT::f128) ? Align(16) : Align(8);
11509467b48Spatrick   unsigned Offset = State.AllocateStack(size, alignment);
11609467b48Spatrick   unsigned Reg = 0;
11709467b48Spatrick 
11809467b48Spatrick   if (LocVT == MVT::i64 && Offset < 6*8)
11909467b48Spatrick     // Promote integers to %i0-%i5.
12009467b48Spatrick     Reg = SP::I0 + Offset/8;
12109467b48Spatrick   else if (LocVT == MVT::f64 && Offset < 16*8)
12209467b48Spatrick     // Promote doubles to %d0-%d30. (Which LLVM calls D0-D15).
12309467b48Spatrick     Reg = SP::D0 + Offset/8;
12409467b48Spatrick   else if (LocVT == MVT::f32 && Offset < 16*8)
12509467b48Spatrick     // Promote floats to %f1, %f3, ...
12609467b48Spatrick     Reg = SP::F1 + Offset/4;
12709467b48Spatrick   else if (LocVT == MVT::f128 && Offset < 16*8)
12809467b48Spatrick     // Promote long doubles to %q0-%q28. (Which LLVM calls Q0-Q7).
12909467b48Spatrick     Reg = SP::Q0 + Offset/16;
13009467b48Spatrick 
13109467b48Spatrick   // Promote to register when possible, otherwise use the stack slot.
13209467b48Spatrick   if (Reg) {
13309467b48Spatrick     State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
13409467b48Spatrick     return true;
13509467b48Spatrick   }
13609467b48Spatrick 
137*a96b3639Srobert   // Bail out if this is a return CC and we run out of registers to place
138*a96b3639Srobert   // values into.
139*a96b3639Srobert   if (IsReturn)
140*a96b3639Srobert     return false;
141*a96b3639Srobert 
14209467b48Spatrick   // This argument goes on the stack in an 8-byte slot.
14309467b48Spatrick   // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to
14409467b48Spatrick   // the right-aligned float. The first 4 bytes of the stack slot are undefined.
14509467b48Spatrick   if (LocVT == MVT::f32)
14609467b48Spatrick     Offset += 4;
14709467b48Spatrick 
14809467b48Spatrick   State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
14909467b48Spatrick   return true;
15009467b48Spatrick }
15109467b48Spatrick 
15209467b48Spatrick // Allocate a half-sized argument for the 64-bit ABI.
15309467b48Spatrick //
15409467b48Spatrick // This is used when passing { float, int } structs by value in registers.
Analyze_CC_Sparc64_Half(bool IsReturn,unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)155*a96b3639Srobert static bool Analyze_CC_Sparc64_Half(bool IsReturn, unsigned &ValNo, MVT &ValVT,
15609467b48Spatrick                                     MVT &LocVT, CCValAssign::LocInfo &LocInfo,
15709467b48Spatrick                                     ISD::ArgFlagsTy &ArgFlags, CCState &State) {
15809467b48Spatrick   assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations");
159097a140dSpatrick   unsigned Offset = State.AllocateStack(4, Align(4));
16009467b48Spatrick 
16109467b48Spatrick   if (LocVT == MVT::f32 && Offset < 16*8) {
16209467b48Spatrick     // Promote floats to %f0-%f31.
16309467b48Spatrick     State.addLoc(CCValAssign::getReg(ValNo, ValVT, SP::F0 + Offset/4,
16409467b48Spatrick                                      LocVT, LocInfo));
16509467b48Spatrick     return true;
16609467b48Spatrick   }
16709467b48Spatrick 
16809467b48Spatrick   if (LocVT == MVT::i32 && Offset < 6*8) {
16909467b48Spatrick     // Promote integers to %i0-%i5, using half the register.
17009467b48Spatrick     unsigned Reg = SP::I0 + Offset/8;
17109467b48Spatrick     LocVT = MVT::i64;
17209467b48Spatrick     LocInfo = CCValAssign::AExt;
17309467b48Spatrick 
17409467b48Spatrick     // Set the Custom bit if this i32 goes in the high bits of a register.
17509467b48Spatrick     if (Offset % 8 == 0)
17609467b48Spatrick       State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg,
17709467b48Spatrick                                              LocVT, LocInfo));
17809467b48Spatrick     else
17909467b48Spatrick       State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
18009467b48Spatrick     return true;
18109467b48Spatrick   }
18209467b48Spatrick 
183*a96b3639Srobert   // Bail out if this is a return CC and we run out of registers to place
184*a96b3639Srobert   // values into.
185*a96b3639Srobert   if (IsReturn)
186*a96b3639Srobert     return false;
187*a96b3639Srobert 
18809467b48Spatrick   State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
18909467b48Spatrick   return true;
19009467b48Spatrick }
19109467b48Spatrick 
CC_Sparc64_Full(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)192*a96b3639Srobert static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
193*a96b3639Srobert                             CCValAssign::LocInfo &LocInfo,
194*a96b3639Srobert                             ISD::ArgFlagsTy &ArgFlags, CCState &State) {
195*a96b3639Srobert   return Analyze_CC_Sparc64_Full(false, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
196*a96b3639Srobert                                  State);
197*a96b3639Srobert }
198*a96b3639Srobert 
CC_Sparc64_Half(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)199*a96b3639Srobert static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
200*a96b3639Srobert                             CCValAssign::LocInfo &LocInfo,
201*a96b3639Srobert                             ISD::ArgFlagsTy &ArgFlags, CCState &State) {
202*a96b3639Srobert   return Analyze_CC_Sparc64_Half(false, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
203*a96b3639Srobert                                  State);
204*a96b3639Srobert }
205*a96b3639Srobert 
RetCC_Sparc64_Full(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)206*a96b3639Srobert static bool RetCC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
207*a96b3639Srobert                                CCValAssign::LocInfo &LocInfo,
208*a96b3639Srobert                                ISD::ArgFlagsTy &ArgFlags, CCState &State) {
209*a96b3639Srobert   return Analyze_CC_Sparc64_Full(true, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
210*a96b3639Srobert                                  State);
211*a96b3639Srobert }
212*a96b3639Srobert 
RetCC_Sparc64_Half(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)213*a96b3639Srobert static bool RetCC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
214*a96b3639Srobert                                CCValAssign::LocInfo &LocInfo,
215*a96b3639Srobert                                ISD::ArgFlagsTy &ArgFlags, CCState &State) {
216*a96b3639Srobert   return Analyze_CC_Sparc64_Half(true, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
217*a96b3639Srobert                                  State);
218*a96b3639Srobert }
219*a96b3639Srobert 
22009467b48Spatrick #include "SparcGenCallingConv.inc"
22109467b48Spatrick 
22209467b48Spatrick // The calling conventions in SparcCallingConv.td are described in terms of the
22309467b48Spatrick // callee's register window. This function translates registers to the
22409467b48Spatrick // corresponding caller window %o register.
toCallerWindow(unsigned Reg)22509467b48Spatrick static unsigned toCallerWindow(unsigned Reg) {
22609467b48Spatrick   static_assert(SP::I0 + 7 == SP::I7 && SP::O0 + 7 == SP::O7,
22709467b48Spatrick                 "Unexpected enum");
22809467b48Spatrick   if (Reg >= SP::I0 && Reg <= SP::I7)
22909467b48Spatrick     return Reg - SP::I0 + SP::O0;
23009467b48Spatrick   return Reg;
23109467b48Spatrick }
23209467b48Spatrick 
CanLowerReturn(CallingConv::ID CallConv,MachineFunction & MF,bool isVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,LLVMContext & Context) const233*a96b3639Srobert bool SparcTargetLowering::CanLowerReturn(
234*a96b3639Srobert     CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
235*a96b3639Srobert     const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
236*a96b3639Srobert   SmallVector<CCValAssign, 16> RVLocs;
237*a96b3639Srobert   CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
238*a96b3639Srobert   return CCInfo.CheckReturn(Outs, Subtarget->is64Bit() ? RetCC_Sparc64
239*a96b3639Srobert                                                        : RetCC_Sparc32);
240*a96b3639Srobert }
241*a96b3639Srobert 
24209467b48Spatrick SDValue
LowerReturn(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const24309467b48Spatrick SparcTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
24409467b48Spatrick                                  bool IsVarArg,
24509467b48Spatrick                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
24609467b48Spatrick                                  const SmallVectorImpl<SDValue> &OutVals,
24709467b48Spatrick                                  const SDLoc &DL, SelectionDAG &DAG) const {
24809467b48Spatrick   if (Subtarget->is64Bit())
24909467b48Spatrick     return LowerReturn_64(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
25009467b48Spatrick   return LowerReturn_32(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
25109467b48Spatrick }
25209467b48Spatrick 
25309467b48Spatrick SDValue
LowerReturn_32(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const25409467b48Spatrick SparcTargetLowering::LowerReturn_32(SDValue Chain, CallingConv::ID CallConv,
25509467b48Spatrick                                     bool IsVarArg,
25609467b48Spatrick                                     const SmallVectorImpl<ISD::OutputArg> &Outs,
25709467b48Spatrick                                     const SmallVectorImpl<SDValue> &OutVals,
25809467b48Spatrick                                     const SDLoc &DL, SelectionDAG &DAG) const {
25909467b48Spatrick   MachineFunction &MF = DAG.getMachineFunction();
26009467b48Spatrick 
26109467b48Spatrick   // CCValAssign - represent the assignment of the return value to locations.
26209467b48Spatrick   SmallVector<CCValAssign, 16> RVLocs;
26309467b48Spatrick 
26409467b48Spatrick   // CCState - Info about the registers and stack slot.
26509467b48Spatrick   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
26609467b48Spatrick                  *DAG.getContext());
26709467b48Spatrick 
26809467b48Spatrick   // Analyze return values.
26909467b48Spatrick   CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32);
27009467b48Spatrick 
27109467b48Spatrick   SDValue Flag;
27209467b48Spatrick   SmallVector<SDValue, 4> RetOps(1, Chain);
27309467b48Spatrick   // Make room for the return address offset.
27409467b48Spatrick   RetOps.push_back(SDValue());
27509467b48Spatrick 
27609467b48Spatrick   // Copy the result values into the output registers.
27709467b48Spatrick   for (unsigned i = 0, realRVLocIdx = 0;
27809467b48Spatrick        i != RVLocs.size();
27909467b48Spatrick        ++i, ++realRVLocIdx) {
28009467b48Spatrick     CCValAssign &VA = RVLocs[i];
28109467b48Spatrick     assert(VA.isRegLoc() && "Can only return in registers!");
28209467b48Spatrick 
28309467b48Spatrick     SDValue Arg = OutVals[realRVLocIdx];
28409467b48Spatrick 
28509467b48Spatrick     if (VA.needsCustom()) {
28609467b48Spatrick       assert(VA.getLocVT() == MVT::v2i32);
28709467b48Spatrick       // Legalize ret v2i32 -> ret 2 x i32 (Basically: do what would
28809467b48Spatrick       // happen by default if this wasn't a legal type)
28909467b48Spatrick 
29009467b48Spatrick       SDValue Part0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
29109467b48Spatrick                                   Arg,
29209467b48Spatrick                                   DAG.getConstant(0, DL, getVectorIdxTy(DAG.getDataLayout())));
29309467b48Spatrick       SDValue Part1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
29409467b48Spatrick                                   Arg,
29509467b48Spatrick                                   DAG.getConstant(1, DL, getVectorIdxTy(DAG.getDataLayout())));
29609467b48Spatrick 
29709467b48Spatrick       Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Part0, Flag);
29809467b48Spatrick       Flag = Chain.getValue(1);
29909467b48Spatrick       RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
30009467b48Spatrick       VA = RVLocs[++i]; // skip ahead to next loc
30109467b48Spatrick       Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Part1,
30209467b48Spatrick                                Flag);
30309467b48Spatrick     } else
30409467b48Spatrick       Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Arg, Flag);
30509467b48Spatrick 
30609467b48Spatrick     // Guarantee that all emitted copies are stuck together with flags.
30709467b48Spatrick     Flag = Chain.getValue(1);
30809467b48Spatrick     RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
30909467b48Spatrick   }
31009467b48Spatrick 
31109467b48Spatrick   unsigned RetAddrOffset = 8; // Call Inst + Delay Slot
31209467b48Spatrick   // If the function returns a struct, copy the SRetReturnReg to I0
31309467b48Spatrick   if (MF.getFunction().hasStructRetAttr()) {
31409467b48Spatrick     SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>();
315097a140dSpatrick     Register Reg = SFI->getSRetReturnReg();
31609467b48Spatrick     if (!Reg)
31709467b48Spatrick       llvm_unreachable("sret virtual register not created in the entry block");
31809467b48Spatrick     auto PtrVT = getPointerTy(DAG.getDataLayout());
31909467b48Spatrick     SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, PtrVT);
32009467b48Spatrick     Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Flag);
32109467b48Spatrick     Flag = Chain.getValue(1);
32209467b48Spatrick     RetOps.push_back(DAG.getRegister(SP::I0, PtrVT));
32309467b48Spatrick     RetAddrOffset = 12; // CallInst + Delay Slot + Unimp
32409467b48Spatrick   }
32509467b48Spatrick 
32609467b48Spatrick   RetOps[0] = Chain;  // Update chain.
32709467b48Spatrick   RetOps[1] = DAG.getConstant(RetAddrOffset, DL, MVT::i32);
32809467b48Spatrick 
32909467b48Spatrick   // Add the flag if we have it.
33009467b48Spatrick   if (Flag.getNode())
33109467b48Spatrick     RetOps.push_back(Flag);
33209467b48Spatrick 
33309467b48Spatrick   return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, RetOps);
33409467b48Spatrick }
33509467b48Spatrick 
33609467b48Spatrick // Lower return values for the 64-bit ABI.
33709467b48Spatrick // Return values are passed the exactly the same way as function arguments.
33809467b48Spatrick SDValue
LowerReturn_64(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const33909467b48Spatrick SparcTargetLowering::LowerReturn_64(SDValue Chain, CallingConv::ID CallConv,
34009467b48Spatrick                                     bool IsVarArg,
34109467b48Spatrick                                     const SmallVectorImpl<ISD::OutputArg> &Outs,
34209467b48Spatrick                                     const SmallVectorImpl<SDValue> &OutVals,
34309467b48Spatrick                                     const SDLoc &DL, SelectionDAG &DAG) const {
34409467b48Spatrick   // CCValAssign - represent the assignment of the return value to locations.
34509467b48Spatrick   SmallVector<CCValAssign, 16> RVLocs;
34609467b48Spatrick 
34709467b48Spatrick   // CCState - Info about the registers and stack slot.
34809467b48Spatrick   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
34909467b48Spatrick                  *DAG.getContext());
35009467b48Spatrick 
35109467b48Spatrick   // Analyze return values.
35209467b48Spatrick   CCInfo.AnalyzeReturn(Outs, RetCC_Sparc64);
35309467b48Spatrick 
35409467b48Spatrick   SDValue Flag;
35509467b48Spatrick   SmallVector<SDValue, 4> RetOps(1, Chain);
35609467b48Spatrick 
35709467b48Spatrick   // The second operand on the return instruction is the return address offset.
35809467b48Spatrick   // The return address is always %i7+8 with the 64-bit ABI.
35909467b48Spatrick   RetOps.push_back(DAG.getConstant(8, DL, MVT::i32));
36009467b48Spatrick 
36109467b48Spatrick   // Copy the result values into the output registers.
36209467b48Spatrick   for (unsigned i = 0; i != RVLocs.size(); ++i) {
36309467b48Spatrick     CCValAssign &VA = RVLocs[i];
36409467b48Spatrick     assert(VA.isRegLoc() && "Can only return in registers!");
36509467b48Spatrick     SDValue OutVal = OutVals[i];
36609467b48Spatrick 
36709467b48Spatrick     // Integer return values must be sign or zero extended by the callee.
36809467b48Spatrick     switch (VA.getLocInfo()) {
36909467b48Spatrick     case CCValAssign::Full: break;
37009467b48Spatrick     case CCValAssign::SExt:
37109467b48Spatrick       OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
37209467b48Spatrick       break;
37309467b48Spatrick     case CCValAssign::ZExt:
37409467b48Spatrick       OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
37509467b48Spatrick       break;
37609467b48Spatrick     case CCValAssign::AExt:
37709467b48Spatrick       OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
37809467b48Spatrick       break;
37909467b48Spatrick     default:
38009467b48Spatrick       llvm_unreachable("Unknown loc info!");
38109467b48Spatrick     }
38209467b48Spatrick 
38309467b48Spatrick     // The custom bit on an i32 return value indicates that it should be passed
38409467b48Spatrick     // in the high bits of the register.
38509467b48Spatrick     if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
38609467b48Spatrick       OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal,
38709467b48Spatrick                            DAG.getConstant(32, DL, MVT::i32));
38809467b48Spatrick 
38909467b48Spatrick       // The next value may go in the low bits of the same register.
39009467b48Spatrick       // Handle both at once.
39109467b48Spatrick       if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) {
39209467b48Spatrick         SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]);
39309467b48Spatrick         OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV);
39409467b48Spatrick         // Skip the next value, it's already done.
39509467b48Spatrick         ++i;
39609467b48Spatrick       }
39709467b48Spatrick     }
39809467b48Spatrick 
39909467b48Spatrick     Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag);
40009467b48Spatrick 
40109467b48Spatrick     // Guarantee that all emitted copies are stuck together with flags.
40209467b48Spatrick     Flag = Chain.getValue(1);
40309467b48Spatrick     RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
40409467b48Spatrick   }
40509467b48Spatrick 
40609467b48Spatrick   RetOps[0] = Chain;  // Update chain.
40709467b48Spatrick 
40809467b48Spatrick   // Add the flag if we have it.
40909467b48Spatrick   if (Flag.getNode())
41009467b48Spatrick     RetOps.push_back(Flag);
41109467b48Spatrick 
41209467b48Spatrick   return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, RetOps);
41309467b48Spatrick }
41409467b48Spatrick 
LowerFormalArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const41509467b48Spatrick SDValue SparcTargetLowering::LowerFormalArguments(
41609467b48Spatrick     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
41709467b48Spatrick     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
41809467b48Spatrick     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
41909467b48Spatrick   if (Subtarget->is64Bit())
42009467b48Spatrick     return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins,
42109467b48Spatrick                                    DL, DAG, InVals);
42209467b48Spatrick   return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins,
42309467b48Spatrick                                  DL, DAG, InVals);
42409467b48Spatrick }
42509467b48Spatrick 
42609467b48Spatrick /// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are
42709467b48Spatrick /// passed in either one or two GPRs, including FP values.  TODO: we should
42809467b48Spatrick /// pass FP values in FP registers for fastcc functions.
LowerFormalArguments_32(SDValue Chain,CallingConv::ID CallConv,bool isVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & dl,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const42909467b48Spatrick SDValue SparcTargetLowering::LowerFormalArguments_32(
43009467b48Spatrick     SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
43109467b48Spatrick     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
43209467b48Spatrick     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
43309467b48Spatrick   MachineFunction &MF = DAG.getMachineFunction();
43409467b48Spatrick   MachineRegisterInfo &RegInfo = MF.getRegInfo();
43509467b48Spatrick   SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
43609467b48Spatrick 
43709467b48Spatrick   // Assign locations to all of the incoming arguments.
43809467b48Spatrick   SmallVector<CCValAssign, 16> ArgLocs;
43909467b48Spatrick   CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
44009467b48Spatrick                  *DAG.getContext());
44109467b48Spatrick   CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32);
44209467b48Spatrick 
44309467b48Spatrick   const unsigned StackOffset = 92;
44409467b48Spatrick   bool IsLittleEndian = DAG.getDataLayout().isLittleEndian();
44509467b48Spatrick 
44609467b48Spatrick   unsigned InIdx = 0;
44709467b48Spatrick   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i, ++InIdx) {
44809467b48Spatrick     CCValAssign &VA = ArgLocs[i];
44909467b48Spatrick 
45009467b48Spatrick     if (Ins[InIdx].Flags.isSRet()) {
45109467b48Spatrick       if (InIdx != 0)
45209467b48Spatrick         report_fatal_error("sparc only supports sret on the first parameter");
45309467b48Spatrick       // Get SRet from [%fp+64].
45409467b48Spatrick       int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, 64, true);
45509467b48Spatrick       SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
45609467b48Spatrick       SDValue Arg =
45709467b48Spatrick           DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo());
45809467b48Spatrick       InVals.push_back(Arg);
45909467b48Spatrick       continue;
46009467b48Spatrick     }
46109467b48Spatrick 
46209467b48Spatrick     if (VA.isRegLoc()) {
46309467b48Spatrick       if (VA.needsCustom()) {
46409467b48Spatrick         assert(VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2i32);
46509467b48Spatrick 
46609467b48Spatrick         Register VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
46709467b48Spatrick         MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi);
46809467b48Spatrick         SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32);
46909467b48Spatrick 
47009467b48Spatrick         assert(i+1 < e);
47109467b48Spatrick         CCValAssign &NextVA = ArgLocs[++i];
47209467b48Spatrick 
47309467b48Spatrick         SDValue LoVal;
47409467b48Spatrick         if (NextVA.isMemLoc()) {
47509467b48Spatrick           int FrameIdx = MF.getFrameInfo().
47609467b48Spatrick             CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true);
47709467b48Spatrick           SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
47809467b48Spatrick           LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo());
47909467b48Spatrick         } else {
480097a140dSpatrick           Register loReg = MF.addLiveIn(NextVA.getLocReg(),
48109467b48Spatrick                                         &SP::IntRegsRegClass);
48209467b48Spatrick           LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32);
48309467b48Spatrick         }
48409467b48Spatrick 
48509467b48Spatrick         if (IsLittleEndian)
48609467b48Spatrick           std::swap(LoVal, HiVal);
48709467b48Spatrick 
48809467b48Spatrick         SDValue WholeValue =
48909467b48Spatrick           DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
49009467b48Spatrick         WholeValue = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), WholeValue);
49109467b48Spatrick         InVals.push_back(WholeValue);
49209467b48Spatrick         continue;
49309467b48Spatrick       }
49409467b48Spatrick       Register VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
49509467b48Spatrick       MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg);
49609467b48Spatrick       SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
49709467b48Spatrick       if (VA.getLocVT() == MVT::f32)
49809467b48Spatrick         Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg);
49909467b48Spatrick       else if (VA.getLocVT() != MVT::i32) {
50009467b48Spatrick         Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg,
50109467b48Spatrick                           DAG.getValueType(VA.getLocVT()));
50209467b48Spatrick         Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg);
50309467b48Spatrick       }
50409467b48Spatrick       InVals.push_back(Arg);
50509467b48Spatrick       continue;
50609467b48Spatrick     }
50709467b48Spatrick 
50809467b48Spatrick     assert(VA.isMemLoc());
50909467b48Spatrick 
51009467b48Spatrick     unsigned Offset = VA.getLocMemOffset()+StackOffset;
51109467b48Spatrick     auto PtrVT = getPointerTy(DAG.getDataLayout());
51209467b48Spatrick 
51309467b48Spatrick     if (VA.needsCustom()) {
51409467b48Spatrick       assert(VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::v2i32);
51509467b48Spatrick       // If it is double-word aligned, just load.
51609467b48Spatrick       if (Offset % 8 == 0) {
51709467b48Spatrick         int FI = MF.getFrameInfo().CreateFixedObject(8,
51809467b48Spatrick                                                      Offset,
51909467b48Spatrick                                                      true);
52009467b48Spatrick         SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
52109467b48Spatrick         SDValue Load =
52209467b48Spatrick             DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
52309467b48Spatrick         InVals.push_back(Load);
52409467b48Spatrick         continue;
52509467b48Spatrick       }
52609467b48Spatrick 
52709467b48Spatrick       int FI = MF.getFrameInfo().CreateFixedObject(4,
52809467b48Spatrick                                                    Offset,
52909467b48Spatrick                                                    true);
53009467b48Spatrick       SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
53109467b48Spatrick       SDValue HiVal =
53209467b48Spatrick           DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo());
53309467b48Spatrick       int FI2 = MF.getFrameInfo().CreateFixedObject(4,
53409467b48Spatrick                                                     Offset+4,
53509467b48Spatrick                                                     true);
53609467b48Spatrick       SDValue FIPtr2 = DAG.getFrameIndex(FI2, PtrVT);
53709467b48Spatrick 
53809467b48Spatrick       SDValue LoVal =
53909467b48Spatrick           DAG.getLoad(MVT::i32, dl, Chain, FIPtr2, MachinePointerInfo());
54009467b48Spatrick 
54109467b48Spatrick       if (IsLittleEndian)
54209467b48Spatrick         std::swap(LoVal, HiVal);
54309467b48Spatrick 
54409467b48Spatrick       SDValue WholeValue =
54509467b48Spatrick         DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
54609467b48Spatrick       WholeValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), WholeValue);
54709467b48Spatrick       InVals.push_back(WholeValue);
54809467b48Spatrick       continue;
54909467b48Spatrick     }
55009467b48Spatrick 
55109467b48Spatrick     int FI = MF.getFrameInfo().CreateFixedObject(4,
55209467b48Spatrick                                                  Offset,
55309467b48Spatrick                                                  true);
55409467b48Spatrick     SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
55509467b48Spatrick     SDValue Load ;
55609467b48Spatrick     if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) {
55709467b48Spatrick       Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
55809467b48Spatrick     } else if (VA.getValVT() == MVT::f128) {
55909467b48Spatrick       report_fatal_error("SPARCv8 does not handle f128 in calls; "
56009467b48Spatrick                          "pass indirectly");
56109467b48Spatrick     } else {
56209467b48Spatrick       // We shouldn't see any other value types here.
56309467b48Spatrick       llvm_unreachable("Unexpected ValVT encountered in frame lowering.");
56409467b48Spatrick     }
56509467b48Spatrick     InVals.push_back(Load);
56609467b48Spatrick   }
56709467b48Spatrick 
56809467b48Spatrick   if (MF.getFunction().hasStructRetAttr()) {
56909467b48Spatrick     // Copy the SRet Argument to SRetReturnReg.
57009467b48Spatrick     SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>();
571097a140dSpatrick     Register Reg = SFI->getSRetReturnReg();
57209467b48Spatrick     if (!Reg) {
57309467b48Spatrick       Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass);
57409467b48Spatrick       SFI->setSRetReturnReg(Reg);
57509467b48Spatrick     }
57609467b48Spatrick     SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]);
57709467b48Spatrick     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
57809467b48Spatrick   }
57909467b48Spatrick 
58009467b48Spatrick   // Store remaining ArgRegs to the stack if this is a varargs function.
58109467b48Spatrick   if (isVarArg) {
58209467b48Spatrick     static const MCPhysReg ArgRegs[] = {
58309467b48Spatrick       SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
58409467b48Spatrick     };
58509467b48Spatrick     unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs);
58609467b48Spatrick     const MCPhysReg *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6;
58709467b48Spatrick     unsigned ArgOffset = CCInfo.getNextStackOffset();
58809467b48Spatrick     if (NumAllocated == 6)
58909467b48Spatrick       ArgOffset += StackOffset;
59009467b48Spatrick     else {
59109467b48Spatrick       assert(!ArgOffset);
59209467b48Spatrick       ArgOffset = 68+4*NumAllocated;
59309467b48Spatrick     }
59409467b48Spatrick 
59509467b48Spatrick     // Remember the vararg offset for the va_start implementation.
59609467b48Spatrick     FuncInfo->setVarArgsFrameOffset(ArgOffset);
59709467b48Spatrick 
59809467b48Spatrick     std::vector<SDValue> OutChains;
59909467b48Spatrick 
60009467b48Spatrick     for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
60109467b48Spatrick       Register VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
60209467b48Spatrick       MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
60309467b48Spatrick       SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32);
60409467b48Spatrick 
60509467b48Spatrick       int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, ArgOffset,
60609467b48Spatrick                                                          true);
60709467b48Spatrick       SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
60809467b48Spatrick 
60909467b48Spatrick       OutChains.push_back(
61009467b48Spatrick           DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, MachinePointerInfo()));
61109467b48Spatrick       ArgOffset += 4;
61209467b48Spatrick     }
61309467b48Spatrick 
61409467b48Spatrick     if (!OutChains.empty()) {
61509467b48Spatrick       OutChains.push_back(Chain);
61609467b48Spatrick       Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
61709467b48Spatrick     }
61809467b48Spatrick   }
61909467b48Spatrick 
62009467b48Spatrick   return Chain;
62109467b48Spatrick }
62209467b48Spatrick 
62309467b48Spatrick // Lower formal arguments for the 64 bit ABI.
LowerFormalArguments_64(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const62409467b48Spatrick SDValue SparcTargetLowering::LowerFormalArguments_64(
62509467b48Spatrick     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
62609467b48Spatrick     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
62709467b48Spatrick     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
62809467b48Spatrick   MachineFunction &MF = DAG.getMachineFunction();
62909467b48Spatrick 
63009467b48Spatrick   // Analyze arguments according to CC_Sparc64.
63109467b48Spatrick   SmallVector<CCValAssign, 16> ArgLocs;
63209467b48Spatrick   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
63309467b48Spatrick                  *DAG.getContext());
63409467b48Spatrick   CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64);
63509467b48Spatrick 
63609467b48Spatrick   // The argument array begins at %fp+BIAS+128, after the register save area.
63709467b48Spatrick   const unsigned ArgArea = 128;
63809467b48Spatrick 
63909467b48Spatrick   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
64009467b48Spatrick     CCValAssign &VA = ArgLocs[i];
64109467b48Spatrick     if (VA.isRegLoc()) {
64209467b48Spatrick       // This argument is passed in a register.
64309467b48Spatrick       // All integer register arguments are promoted by the caller to i64.
64409467b48Spatrick 
64509467b48Spatrick       // Create a virtual register for the promoted live-in value.
646097a140dSpatrick       Register VReg = MF.addLiveIn(VA.getLocReg(),
64709467b48Spatrick                                    getRegClassFor(VA.getLocVT()));
64809467b48Spatrick       SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
64909467b48Spatrick 
65009467b48Spatrick       // Get the high bits for i32 struct elements.
65109467b48Spatrick       if (VA.getValVT() == MVT::i32 && VA.needsCustom())
65209467b48Spatrick         Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg,
65309467b48Spatrick                           DAG.getConstant(32, DL, MVT::i32));
65409467b48Spatrick 
65509467b48Spatrick       // The caller promoted the argument, so insert an Assert?ext SDNode so we
65609467b48Spatrick       // won't promote the value again in this function.
65709467b48Spatrick       switch (VA.getLocInfo()) {
65809467b48Spatrick       case CCValAssign::SExt:
65909467b48Spatrick         Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
66009467b48Spatrick                           DAG.getValueType(VA.getValVT()));
66109467b48Spatrick         break;
66209467b48Spatrick       case CCValAssign::ZExt:
66309467b48Spatrick         Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
66409467b48Spatrick                           DAG.getValueType(VA.getValVT()));
66509467b48Spatrick         break;
66609467b48Spatrick       default:
66709467b48Spatrick         break;
66809467b48Spatrick       }
66909467b48Spatrick 
67009467b48Spatrick       // Truncate the register down to the argument type.
67109467b48Spatrick       if (VA.isExtInLoc())
67209467b48Spatrick         Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
67309467b48Spatrick 
67409467b48Spatrick       InVals.push_back(Arg);
67509467b48Spatrick       continue;
67609467b48Spatrick     }
67709467b48Spatrick 
67809467b48Spatrick     // The registers are exhausted. This argument was passed on the stack.
67909467b48Spatrick     assert(VA.isMemLoc());
68009467b48Spatrick     // The CC_Sparc64_Full/Half functions compute stack offsets relative to the
68109467b48Spatrick     // beginning of the arguments area at %fp+BIAS+128.
68209467b48Spatrick     unsigned Offset = VA.getLocMemOffset() + ArgArea;
68309467b48Spatrick     unsigned ValSize = VA.getValVT().getSizeInBits() / 8;
68409467b48Spatrick     // Adjust offset for extended arguments, SPARC is big-endian.
68509467b48Spatrick     // The caller will have written the full slot with extended bytes, but we
68609467b48Spatrick     // prefer our own extending loads.
68709467b48Spatrick     if (VA.isExtInLoc())
68809467b48Spatrick       Offset += 8 - ValSize;
68909467b48Spatrick     int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true);
69009467b48Spatrick     InVals.push_back(
69109467b48Spatrick         DAG.getLoad(VA.getValVT(), DL, Chain,
69209467b48Spatrick                     DAG.getFrameIndex(FI, getPointerTy(MF.getDataLayout())),
69309467b48Spatrick                     MachinePointerInfo::getFixedStack(MF, FI)));
69409467b48Spatrick   }
69509467b48Spatrick 
69609467b48Spatrick   if (!IsVarArg)
69709467b48Spatrick     return Chain;
69809467b48Spatrick 
69909467b48Spatrick   // This function takes variable arguments, some of which may have been passed
70009467b48Spatrick   // in registers %i0-%i5. Variable floating point arguments are never passed
70109467b48Spatrick   // in floating point registers. They go on %i0-%i5 or on the stack like
70209467b48Spatrick   // integer arguments.
70309467b48Spatrick   //
70409467b48Spatrick   // The va_start intrinsic needs to know the offset to the first variable
70509467b48Spatrick   // argument.
70609467b48Spatrick   unsigned ArgOffset = CCInfo.getNextStackOffset();
70709467b48Spatrick   SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
70809467b48Spatrick   // Skip the 128 bytes of register save area.
70909467b48Spatrick   FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgArea +
71009467b48Spatrick                                   Subtarget->getStackPointerBias());
71109467b48Spatrick 
71209467b48Spatrick   // Save the variable arguments that were passed in registers.
71309467b48Spatrick   // The caller is required to reserve stack space for 6 arguments regardless
71409467b48Spatrick   // of how many arguments were actually passed.
71509467b48Spatrick   SmallVector<SDValue, 8> OutChains;
71609467b48Spatrick   for (; ArgOffset < 6*8; ArgOffset += 8) {
717097a140dSpatrick     Register VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass);
71809467b48Spatrick     SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64);
71909467b48Spatrick     int FI = MF.getFrameInfo().CreateFixedObject(8, ArgOffset + ArgArea, true);
72009467b48Spatrick     auto PtrVT = getPointerTy(MF.getDataLayout());
72109467b48Spatrick     OutChains.push_back(
72209467b48Spatrick         DAG.getStore(Chain, DL, VArg, DAG.getFrameIndex(FI, PtrVT),
72309467b48Spatrick                      MachinePointerInfo::getFixedStack(MF, FI)));
72409467b48Spatrick   }
72509467b48Spatrick 
72609467b48Spatrick   if (!OutChains.empty())
72709467b48Spatrick     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
72809467b48Spatrick 
72909467b48Spatrick   return Chain;
73009467b48Spatrick }
73109467b48Spatrick 
73209467b48Spatrick SDValue
LowerCall(TargetLowering::CallLoweringInfo & CLI,SmallVectorImpl<SDValue> & InVals) const73309467b48Spatrick SparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
73409467b48Spatrick                                SmallVectorImpl<SDValue> &InVals) const {
73509467b48Spatrick   if (Subtarget->is64Bit())
73609467b48Spatrick     return LowerCall_64(CLI, InVals);
73709467b48Spatrick   return LowerCall_32(CLI, InVals);
73809467b48Spatrick }
73909467b48Spatrick 
hasReturnsTwiceAttr(SelectionDAG & DAG,SDValue Callee,const CallBase * Call)74009467b48Spatrick static bool hasReturnsTwiceAttr(SelectionDAG &DAG, SDValue Callee,
741097a140dSpatrick                                 const CallBase *Call) {
742097a140dSpatrick   if (Call)
743097a140dSpatrick     return Call->hasFnAttr(Attribute::ReturnsTwice);
74409467b48Spatrick 
74509467b48Spatrick   const Function *CalleeFn = nullptr;
74609467b48Spatrick   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
74709467b48Spatrick     CalleeFn = dyn_cast<Function>(G->getGlobal());
74809467b48Spatrick   } else if (ExternalSymbolSDNode *E =
74909467b48Spatrick              dyn_cast<ExternalSymbolSDNode>(Callee)) {
75009467b48Spatrick     const Function &Fn = DAG.getMachineFunction().getFunction();
75109467b48Spatrick     const Module *M = Fn.getParent();
75209467b48Spatrick     const char *CalleeName = E->getSymbol();
75309467b48Spatrick     CalleeFn = M->getFunction(CalleeName);
75409467b48Spatrick   }
75509467b48Spatrick 
75609467b48Spatrick   if (!CalleeFn)
75709467b48Spatrick     return false;
75809467b48Spatrick   return CalleeFn->hasFnAttribute(Attribute::ReturnsTwice);
75909467b48Spatrick }
76009467b48Spatrick 
761*a96b3639Srobert /// IsEligibleForTailCallOptimization - Check whether the call is eligible
762*a96b3639Srobert /// for tail call optimization.
IsEligibleForTailCallOptimization(CCState & CCInfo,CallLoweringInfo & CLI,MachineFunction & MF) const763*a96b3639Srobert bool SparcTargetLowering::IsEligibleForTailCallOptimization(
764*a96b3639Srobert     CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF) const {
765*a96b3639Srobert 
766*a96b3639Srobert   auto &Outs = CLI.Outs;
767*a96b3639Srobert   auto &Caller = MF.getFunction();
768*a96b3639Srobert 
769*a96b3639Srobert   // Do not tail call opt functions with "disable-tail-calls" attribute.
770*a96b3639Srobert   if (Caller.getFnAttribute("disable-tail-calls").getValueAsString() == "true")
771*a96b3639Srobert     return false;
772*a96b3639Srobert 
773*a96b3639Srobert   // Do not tail call opt if the stack is used to pass parameters.
774*a96b3639Srobert   // 64-bit targets have a slightly higher limit since the ABI requires
775*a96b3639Srobert   // to allocate some space even when all the parameters fit inside registers.
776*a96b3639Srobert   unsigned StackOffsetLimit = Subtarget->is64Bit() ? 48 : 0;
777*a96b3639Srobert   if (CCInfo.getNextStackOffset() > StackOffsetLimit)
778*a96b3639Srobert     return false;
779*a96b3639Srobert 
780*a96b3639Srobert   // Do not tail call opt if either the callee or caller returns
781*a96b3639Srobert   // a struct and the other does not.
782*a96b3639Srobert   if (!Outs.empty() && Caller.hasStructRetAttr() != Outs[0].Flags.isSRet())
783*a96b3639Srobert     return false;
784*a96b3639Srobert 
785*a96b3639Srobert   // Byval parameters hand the function a pointer directly into the stack area
786*a96b3639Srobert   // we want to reuse during a tail call.
787*a96b3639Srobert   for (auto &Arg : Outs)
788*a96b3639Srobert     if (Arg.Flags.isByVal())
789*a96b3639Srobert       return false;
790*a96b3639Srobert 
791*a96b3639Srobert   return true;
792*a96b3639Srobert }
793*a96b3639Srobert 
79409467b48Spatrick // Lower a call for the 32-bit ABI.
79509467b48Spatrick SDValue
LowerCall_32(TargetLowering::CallLoweringInfo & CLI,SmallVectorImpl<SDValue> & InVals) const79609467b48Spatrick SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
79709467b48Spatrick                                   SmallVectorImpl<SDValue> &InVals) const {
79809467b48Spatrick   SelectionDAG &DAG                     = CLI.DAG;
79909467b48Spatrick   SDLoc &dl                             = CLI.DL;
80009467b48Spatrick   SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
80109467b48Spatrick   SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
80209467b48Spatrick   SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
80309467b48Spatrick   SDValue Chain                         = CLI.Chain;
80409467b48Spatrick   SDValue Callee                        = CLI.Callee;
80509467b48Spatrick   bool &isTailCall                      = CLI.IsTailCall;
80609467b48Spatrick   CallingConv::ID CallConv              = CLI.CallConv;
80709467b48Spatrick   bool isVarArg                         = CLI.IsVarArg;
80809467b48Spatrick 
80909467b48Spatrick   // Analyze operands of the call, assigning locations to each operand.
81009467b48Spatrick   SmallVector<CCValAssign, 16> ArgLocs;
81109467b48Spatrick   CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
81209467b48Spatrick                  *DAG.getContext());
81309467b48Spatrick   CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32);
81409467b48Spatrick 
815*a96b3639Srobert   isTailCall = isTailCall && IsEligibleForTailCallOptimization(
816*a96b3639Srobert                                  CCInfo, CLI, DAG.getMachineFunction());
817*a96b3639Srobert 
81809467b48Spatrick   // Get the size of the outgoing arguments stack space requirement.
81909467b48Spatrick   unsigned ArgsSize = CCInfo.getNextStackOffset();
82009467b48Spatrick 
82109467b48Spatrick   // Keep stack frames 8-byte aligned.
82209467b48Spatrick   ArgsSize = (ArgsSize+7) & ~7;
82309467b48Spatrick 
82409467b48Spatrick   MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
82509467b48Spatrick 
82609467b48Spatrick   // Create local copies for byval args.
82709467b48Spatrick   SmallVector<SDValue, 8> ByValArgs;
82809467b48Spatrick   for (unsigned i = 0,  e = Outs.size(); i != e; ++i) {
82909467b48Spatrick     ISD::ArgFlagsTy Flags = Outs[i].Flags;
83009467b48Spatrick     if (!Flags.isByVal())
83109467b48Spatrick       continue;
83209467b48Spatrick 
83309467b48Spatrick     SDValue Arg = OutVals[i];
83409467b48Spatrick     unsigned Size = Flags.getByValSize();
835097a140dSpatrick     Align Alignment = Flags.getNonZeroByValAlign();
83609467b48Spatrick 
83709467b48Spatrick     if (Size > 0U) {
838097a140dSpatrick       int FI = MFI.CreateStackObject(Size, Alignment, false);
83909467b48Spatrick       SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
84009467b48Spatrick       SDValue SizeNode = DAG.getConstant(Size, dl, MVT::i32);
84109467b48Spatrick 
842097a140dSpatrick       Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Alignment,
84309467b48Spatrick                             false,        // isVolatile,
84409467b48Spatrick                             (Size <= 32), // AlwaysInline if size <= 32,
84509467b48Spatrick                             false,        // isTailCall
84609467b48Spatrick                             MachinePointerInfo(), MachinePointerInfo());
84709467b48Spatrick       ByValArgs.push_back(FIPtr);
84809467b48Spatrick     }
84909467b48Spatrick     else {
85009467b48Spatrick       SDValue nullVal;
85109467b48Spatrick       ByValArgs.push_back(nullVal);
85209467b48Spatrick     }
85309467b48Spatrick   }
85409467b48Spatrick 
855*a96b3639Srobert   assert(!isTailCall || ArgsSize == 0);
856*a96b3639Srobert 
857*a96b3639Srobert   if (!isTailCall)
85809467b48Spatrick     Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, dl);
85909467b48Spatrick 
86009467b48Spatrick   SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
86109467b48Spatrick   SmallVector<SDValue, 8> MemOpChains;
86209467b48Spatrick 
86309467b48Spatrick   const unsigned StackOffset = 92;
86409467b48Spatrick   bool hasStructRetAttr = false;
86509467b48Spatrick   unsigned SRetArgSize = 0;
86609467b48Spatrick   // Walk the register/memloc assignments, inserting copies/loads.
86709467b48Spatrick   for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size();
86809467b48Spatrick        i != e;
86909467b48Spatrick        ++i, ++realArgIdx) {
87009467b48Spatrick     CCValAssign &VA = ArgLocs[i];
87109467b48Spatrick     SDValue Arg = OutVals[realArgIdx];
87209467b48Spatrick 
87309467b48Spatrick     ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
87409467b48Spatrick 
87509467b48Spatrick     // Use local copy if it is a byval arg.
87609467b48Spatrick     if (Flags.isByVal()) {
87709467b48Spatrick       Arg = ByValArgs[byvalArgIdx++];
87809467b48Spatrick       if (!Arg) {
87909467b48Spatrick         continue;
88009467b48Spatrick       }
88109467b48Spatrick     }
88209467b48Spatrick 
88309467b48Spatrick     // Promote the value if needed.
88409467b48Spatrick     switch (VA.getLocInfo()) {
88509467b48Spatrick     default: llvm_unreachable("Unknown loc info!");
88609467b48Spatrick     case CCValAssign::Full: break;
88709467b48Spatrick     case CCValAssign::SExt:
88809467b48Spatrick       Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
88909467b48Spatrick       break;
89009467b48Spatrick     case CCValAssign::ZExt:
89109467b48Spatrick       Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
89209467b48Spatrick       break;
89309467b48Spatrick     case CCValAssign::AExt:
89409467b48Spatrick       Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
89509467b48Spatrick       break;
89609467b48Spatrick     case CCValAssign::BCvt:
89709467b48Spatrick       Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
89809467b48Spatrick       break;
89909467b48Spatrick     }
90009467b48Spatrick 
90109467b48Spatrick     if (Flags.isSRet()) {
90209467b48Spatrick       assert(VA.needsCustom());
903*a96b3639Srobert 
904*a96b3639Srobert       if (isTailCall)
905*a96b3639Srobert         continue;
906*a96b3639Srobert 
90709467b48Spatrick       // store SRet argument in %sp+64
90809467b48Spatrick       SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
90909467b48Spatrick       SDValue PtrOff = DAG.getIntPtrConstant(64, dl);
91009467b48Spatrick       PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
91109467b48Spatrick       MemOpChains.push_back(
91209467b48Spatrick           DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
91309467b48Spatrick       hasStructRetAttr = true;
91409467b48Spatrick       // sret only allowed on first argument
91509467b48Spatrick       assert(Outs[realArgIdx].OrigArgIndex == 0);
916*a96b3639Srobert       SRetArgSize =
917*a96b3639Srobert           DAG.getDataLayout().getTypeAllocSize(CLI.getArgs()[0].IndirectType);
91809467b48Spatrick       continue;
91909467b48Spatrick     }
92009467b48Spatrick 
92109467b48Spatrick     if (VA.needsCustom()) {
92209467b48Spatrick       assert(VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2i32);
92309467b48Spatrick 
92409467b48Spatrick       if (VA.isMemLoc()) {
92509467b48Spatrick         unsigned Offset = VA.getLocMemOffset() + StackOffset;
92609467b48Spatrick         // if it is double-word aligned, just store.
92709467b48Spatrick         if (Offset % 8 == 0) {
92809467b48Spatrick           SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
92909467b48Spatrick           SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
93009467b48Spatrick           PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
93109467b48Spatrick           MemOpChains.push_back(
93209467b48Spatrick               DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
93309467b48Spatrick           continue;
93409467b48Spatrick         }
93509467b48Spatrick       }
93609467b48Spatrick 
93709467b48Spatrick       if (VA.getLocVT() == MVT::f64) {
93809467b48Spatrick         // Move from the float value from float registers into the
93909467b48Spatrick         // integer registers.
94009467b48Spatrick         if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Arg))
94109467b48Spatrick           Arg = bitcastConstantFPToInt(C, dl, DAG);
94209467b48Spatrick         else
94309467b48Spatrick           Arg = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, Arg);
94409467b48Spatrick       }
94509467b48Spatrick 
94609467b48Spatrick       SDValue Part0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
94709467b48Spatrick                                   Arg,
94809467b48Spatrick                                   DAG.getConstant(0, dl, getVectorIdxTy(DAG.getDataLayout())));
94909467b48Spatrick       SDValue Part1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
95009467b48Spatrick                                   Arg,
95109467b48Spatrick                                   DAG.getConstant(1, dl, getVectorIdxTy(DAG.getDataLayout())));
95209467b48Spatrick 
95309467b48Spatrick       if (VA.isRegLoc()) {
95409467b48Spatrick         RegsToPass.push_back(std::make_pair(VA.getLocReg(), Part0));
95509467b48Spatrick         assert(i+1 != e);
95609467b48Spatrick         CCValAssign &NextVA = ArgLocs[++i];
95709467b48Spatrick         if (NextVA.isRegLoc()) {
95809467b48Spatrick           RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Part1));
95909467b48Spatrick         } else {
96009467b48Spatrick           // Store the second part in stack.
96109467b48Spatrick           unsigned Offset = NextVA.getLocMemOffset() + StackOffset;
96209467b48Spatrick           SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
96309467b48Spatrick           SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
96409467b48Spatrick           PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
96509467b48Spatrick           MemOpChains.push_back(
96609467b48Spatrick               DAG.getStore(Chain, dl, Part1, PtrOff, MachinePointerInfo()));
96709467b48Spatrick         }
96809467b48Spatrick       } else {
96909467b48Spatrick         unsigned Offset = VA.getLocMemOffset() + StackOffset;
97009467b48Spatrick         // Store the first part.
97109467b48Spatrick         SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
97209467b48Spatrick         SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
97309467b48Spatrick         PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
97409467b48Spatrick         MemOpChains.push_back(
97509467b48Spatrick             DAG.getStore(Chain, dl, Part0, PtrOff, MachinePointerInfo()));
97609467b48Spatrick         // Store the second part.
97709467b48Spatrick         PtrOff = DAG.getIntPtrConstant(Offset + 4, dl);
97809467b48Spatrick         PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
97909467b48Spatrick         MemOpChains.push_back(
98009467b48Spatrick             DAG.getStore(Chain, dl, Part1, PtrOff, MachinePointerInfo()));
98109467b48Spatrick       }
98209467b48Spatrick       continue;
98309467b48Spatrick     }
98409467b48Spatrick 
98509467b48Spatrick     // Arguments that can be passed on register must be kept at
98609467b48Spatrick     // RegsToPass vector
98709467b48Spatrick     if (VA.isRegLoc()) {
98809467b48Spatrick       if (VA.getLocVT() != MVT::f32) {
98909467b48Spatrick         RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
99009467b48Spatrick         continue;
99109467b48Spatrick       }
99209467b48Spatrick       Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
99309467b48Spatrick       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
99409467b48Spatrick       continue;
99509467b48Spatrick     }
99609467b48Spatrick 
99709467b48Spatrick     assert(VA.isMemLoc());
99809467b48Spatrick 
99909467b48Spatrick     // Create a store off the stack pointer for this argument.
100009467b48Spatrick     SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
100109467b48Spatrick     SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() + StackOffset,
100209467b48Spatrick                                            dl);
100309467b48Spatrick     PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
100409467b48Spatrick     MemOpChains.push_back(
100509467b48Spatrick         DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
100609467b48Spatrick   }
100709467b48Spatrick 
100809467b48Spatrick 
100909467b48Spatrick   // Emit all stores, make sure the occur before any copies into physregs.
101009467b48Spatrick   if (!MemOpChains.empty())
101109467b48Spatrick     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
101209467b48Spatrick 
101309467b48Spatrick   // Build a sequence of copy-to-reg nodes chained together with token
101409467b48Spatrick   // chain and flag operands which copy the outgoing args into registers.
101509467b48Spatrick   // The InFlag in necessary since all emitted instructions must be
101609467b48Spatrick   // stuck together.
101709467b48Spatrick   SDValue InFlag;
101809467b48Spatrick   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1019*a96b3639Srobert     Register Reg = RegsToPass[i].first;
1020*a96b3639Srobert     if (!isTailCall)
1021*a96b3639Srobert       Reg = toCallerWindow(Reg);
102209467b48Spatrick     Chain = DAG.getCopyToReg(Chain, dl, Reg, RegsToPass[i].second, InFlag);
102309467b48Spatrick     InFlag = Chain.getValue(1);
102409467b48Spatrick   }
102509467b48Spatrick 
1026097a140dSpatrick   bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CB);
102709467b48Spatrick 
102809467b48Spatrick   // If the callee is a GlobalAddress node (quite common, every direct call is)
102909467b48Spatrick   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
103009467b48Spatrick   // Likewise ExternalSymbol -> TargetExternalSymbol.
1031a0747c9fSpatrick   unsigned TF = isPositionIndependent() ? SparcMCExpr::VK_Sparc_WPLT30
1032a0747c9fSpatrick                                         : SparcMCExpr::VK_Sparc_WDISP30;
103309467b48Spatrick   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
103409467b48Spatrick     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0, TF);
103509467b48Spatrick   else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
103609467b48Spatrick     Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32, TF);
103709467b48Spatrick 
103809467b48Spatrick   // Returns a chain & a flag for retval copy to use
103909467b48Spatrick   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
104009467b48Spatrick   SmallVector<SDValue, 8> Ops;
104109467b48Spatrick   Ops.push_back(Chain);
104209467b48Spatrick   Ops.push_back(Callee);
104309467b48Spatrick   if (hasStructRetAttr)
104409467b48Spatrick     Ops.push_back(DAG.getTargetConstant(SRetArgSize, dl, MVT::i32));
1045*a96b3639Srobert   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1046*a96b3639Srobert     Register Reg = RegsToPass[i].first;
1047*a96b3639Srobert     if (!isTailCall)
1048*a96b3639Srobert       Reg = toCallerWindow(Reg);
1049*a96b3639Srobert     Ops.push_back(DAG.getRegister(Reg, RegsToPass[i].second.getValueType()));
1050*a96b3639Srobert   }
105109467b48Spatrick 
105209467b48Spatrick   // Add a register mask operand representing the call-preserved registers.
105309467b48Spatrick   const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo();
105409467b48Spatrick   const uint32_t *Mask =
105509467b48Spatrick       ((hasReturnsTwice)
105609467b48Spatrick            ? TRI->getRTCallPreservedMask(CallConv)
105709467b48Spatrick            : TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv));
105809467b48Spatrick   assert(Mask && "Missing call preserved mask for calling convention");
105909467b48Spatrick   Ops.push_back(DAG.getRegisterMask(Mask));
106009467b48Spatrick 
106109467b48Spatrick   if (InFlag.getNode())
106209467b48Spatrick     Ops.push_back(InFlag);
106309467b48Spatrick 
1064*a96b3639Srobert   if (isTailCall) {
1065*a96b3639Srobert     DAG.getMachineFunction().getFrameInfo().setHasTailCall();
1066*a96b3639Srobert     return DAG.getNode(SPISD::TAIL_CALL, dl, MVT::Other, Ops);
1067*a96b3639Srobert   }
1068*a96b3639Srobert 
106909467b48Spatrick   Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops);
107009467b48Spatrick   InFlag = Chain.getValue(1);
107109467b48Spatrick 
1072*a96b3639Srobert   Chain = DAG.getCALLSEQ_END(Chain, ArgsSize, 0, InFlag, dl);
107309467b48Spatrick   InFlag = Chain.getValue(1);
107409467b48Spatrick 
107509467b48Spatrick   // Assign locations to each value returned by this call.
107609467b48Spatrick   SmallVector<CCValAssign, 16> RVLocs;
107709467b48Spatrick   CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
107809467b48Spatrick                  *DAG.getContext());
107909467b48Spatrick 
108009467b48Spatrick   RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32);
108109467b48Spatrick 
108209467b48Spatrick   // Copy all of the result registers out of their specified physreg.
108309467b48Spatrick   for (unsigned i = 0; i != RVLocs.size(); ++i) {
1084*a96b3639Srobert     assert(RVLocs[i].isRegLoc() && "Can only return in registers!");
108509467b48Spatrick     if (RVLocs[i].getLocVT() == MVT::v2i32) {
108609467b48Spatrick       SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2i32);
108709467b48Spatrick       SDValue Lo = DAG.getCopyFromReg(
108809467b48Spatrick           Chain, dl, toCallerWindow(RVLocs[i++].getLocReg()), MVT::i32, InFlag);
108909467b48Spatrick       Chain = Lo.getValue(1);
109009467b48Spatrick       InFlag = Lo.getValue(2);
109109467b48Spatrick       Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2i32, Vec, Lo,
109209467b48Spatrick                         DAG.getConstant(0, dl, MVT::i32));
109309467b48Spatrick       SDValue Hi = DAG.getCopyFromReg(
109409467b48Spatrick           Chain, dl, toCallerWindow(RVLocs[i].getLocReg()), MVT::i32, InFlag);
109509467b48Spatrick       Chain = Hi.getValue(1);
109609467b48Spatrick       InFlag = Hi.getValue(2);
109709467b48Spatrick       Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2i32, Vec, Hi,
109809467b48Spatrick                         DAG.getConstant(1, dl, MVT::i32));
109909467b48Spatrick       InVals.push_back(Vec);
110009467b48Spatrick     } else {
110109467b48Spatrick       Chain =
110209467b48Spatrick           DAG.getCopyFromReg(Chain, dl, toCallerWindow(RVLocs[i].getLocReg()),
110309467b48Spatrick                              RVLocs[i].getValVT(), InFlag)
110409467b48Spatrick               .getValue(1);
110509467b48Spatrick       InFlag = Chain.getValue(2);
110609467b48Spatrick       InVals.push_back(Chain.getValue(0));
110709467b48Spatrick     }
110809467b48Spatrick   }
110909467b48Spatrick 
111009467b48Spatrick   return Chain;
111109467b48Spatrick }
111209467b48Spatrick 
111309467b48Spatrick // FIXME? Maybe this could be a TableGen attribute on some registers and
111409467b48Spatrick // this table could be generated automatically from RegInfo.
getRegisterByName(const char * RegName,LLT VT,const MachineFunction & MF) const111509467b48Spatrick Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT,
111609467b48Spatrick                                                 const MachineFunction &MF) const {
1117097a140dSpatrick   Register Reg = StringSwitch<Register>(RegName)
111809467b48Spatrick     .Case("i0", SP::I0).Case("i1", SP::I1).Case("i2", SP::I2).Case("i3", SP::I3)
111909467b48Spatrick     .Case("i4", SP::I4).Case("i5", SP::I5).Case("i6", SP::I6).Case("i7", SP::I7)
112009467b48Spatrick     .Case("o0", SP::O0).Case("o1", SP::O1).Case("o2", SP::O2).Case("o3", SP::O3)
112109467b48Spatrick     .Case("o4", SP::O4).Case("o5", SP::O5).Case("o6", SP::O6).Case("o7", SP::O7)
112209467b48Spatrick     .Case("l0", SP::L0).Case("l1", SP::L1).Case("l2", SP::L2).Case("l3", SP::L3)
112309467b48Spatrick     .Case("l4", SP::L4).Case("l5", SP::L5).Case("l6", SP::L6).Case("l7", SP::L7)
112409467b48Spatrick     .Case("g0", SP::G0).Case("g1", SP::G1).Case("g2", SP::G2).Case("g3", SP::G3)
112509467b48Spatrick     .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7)
112609467b48Spatrick     .Default(0);
112709467b48Spatrick 
112809467b48Spatrick   if (Reg)
112909467b48Spatrick     return Reg;
113009467b48Spatrick 
113109467b48Spatrick   report_fatal_error("Invalid register name global variable");
113209467b48Spatrick }
113309467b48Spatrick 
113409467b48Spatrick // Fixup floating point arguments in the ... part of a varargs call.
113509467b48Spatrick //
113609467b48Spatrick // The SPARC v9 ABI requires that floating point arguments are treated the same
113709467b48Spatrick // as integers when calling a varargs function. This does not apply to the
113809467b48Spatrick // fixed arguments that are part of the function's prototype.
113909467b48Spatrick //
114009467b48Spatrick // This function post-processes a CCValAssign array created by
114109467b48Spatrick // AnalyzeCallOperands().
fixupVariableFloatArgs(SmallVectorImpl<CCValAssign> & ArgLocs,ArrayRef<ISD::OutputArg> Outs)114209467b48Spatrick static void fixupVariableFloatArgs(SmallVectorImpl<CCValAssign> &ArgLocs,
114309467b48Spatrick                                    ArrayRef<ISD::OutputArg> Outs) {
114409467b48Spatrick   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1145*a96b3639Srobert     CCValAssign &VA = ArgLocs[i];
114609467b48Spatrick     MVT ValTy = VA.getLocVT();
114709467b48Spatrick     // FIXME: What about f32 arguments? C promotes them to f64 when calling
114809467b48Spatrick     // varargs functions.
114909467b48Spatrick     if (!VA.isRegLoc() || (ValTy != MVT::f64 && ValTy != MVT::f128))
115009467b48Spatrick       continue;
115109467b48Spatrick     // The fixed arguments to a varargs function still go in FP registers.
115209467b48Spatrick     if (Outs[VA.getValNo()].IsFixed)
115309467b48Spatrick       continue;
115409467b48Spatrick 
115509467b48Spatrick     // This floating point argument should be reassigned.
115609467b48Spatrick     // Determine the offset into the argument array.
1157097a140dSpatrick     Register firstReg = (ValTy == MVT::f64) ? SP::D0 : SP::Q0;
115809467b48Spatrick     unsigned argSize  = (ValTy == MVT::f64) ? 8 : 16;
115909467b48Spatrick     unsigned Offset = argSize * (VA.getLocReg() - firstReg);
116009467b48Spatrick     assert(Offset < 16*8 && "Offset out of range, bad register enum?");
116109467b48Spatrick 
116209467b48Spatrick     if (Offset < 6*8) {
116309467b48Spatrick       // This argument should go in %i0-%i5.
116409467b48Spatrick       unsigned IReg = SP::I0 + Offset/8;
116509467b48Spatrick       if (ValTy == MVT::f64)
116609467b48Spatrick         // Full register, just bitconvert into i64.
1167*a96b3639Srobert         VA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), IReg, MVT::i64,
1168*a96b3639Srobert                                  CCValAssign::BCvt);
116909467b48Spatrick       else {
117009467b48Spatrick         assert(ValTy == MVT::f128 && "Unexpected type!");
117109467b48Spatrick         // Full register, just bitconvert into i128 -- We will lower this into
117209467b48Spatrick         // two i64s in LowerCall_64.
1173*a96b3639Srobert         VA = CCValAssign::getCustomReg(VA.getValNo(), VA.getValVT(), IReg,
1174*a96b3639Srobert                                        MVT::i128, CCValAssign::BCvt);
117509467b48Spatrick       }
117609467b48Spatrick     } else {
117709467b48Spatrick       // This needs to go to memory, we're out of integer registers.
1178*a96b3639Srobert       VA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(), Offset,
1179*a96b3639Srobert                                VA.getLocVT(), VA.getLocInfo());
118009467b48Spatrick     }
118109467b48Spatrick   }
118209467b48Spatrick }
118309467b48Spatrick 
118409467b48Spatrick // Lower a call for the 64-bit ABI.
118509467b48Spatrick SDValue
LowerCall_64(TargetLowering::CallLoweringInfo & CLI,SmallVectorImpl<SDValue> & InVals) const118609467b48Spatrick SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
118709467b48Spatrick                                   SmallVectorImpl<SDValue> &InVals) const {
118809467b48Spatrick   SelectionDAG &DAG = CLI.DAG;
118909467b48Spatrick   SDLoc DL = CLI.DL;
119009467b48Spatrick   SDValue Chain = CLI.Chain;
119109467b48Spatrick   auto PtrVT = getPointerTy(DAG.getDataLayout());
119209467b48Spatrick 
119309467b48Spatrick   // Analyze operands of the call, assigning locations to each operand.
119409467b48Spatrick   SmallVector<CCValAssign, 16> ArgLocs;
119509467b48Spatrick   CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs,
119609467b48Spatrick                  *DAG.getContext());
119709467b48Spatrick   CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64);
119809467b48Spatrick 
1199*a96b3639Srobert   CLI.IsTailCall = CLI.IsTailCall && IsEligibleForTailCallOptimization(
1200*a96b3639Srobert                                          CCInfo, CLI, DAG.getMachineFunction());
1201*a96b3639Srobert 
120209467b48Spatrick   // Get the size of the outgoing arguments stack space requirement.
120309467b48Spatrick   // The stack offset computed by CC_Sparc64 includes all arguments.
120409467b48Spatrick   // Called functions expect 6 argument words to exist in the stack frame, used
120509467b48Spatrick   // or not.
1206*a96b3639Srobert   unsigned StackReserved = 6 * 8u;
1207*a96b3639Srobert   unsigned ArgsSize = std::max(StackReserved, CCInfo.getNextStackOffset());
120809467b48Spatrick 
120909467b48Spatrick   // Keep stack frames 16-byte aligned.
121009467b48Spatrick   ArgsSize = alignTo(ArgsSize, 16);
121109467b48Spatrick 
121209467b48Spatrick   // Varargs calls require special treatment.
121309467b48Spatrick   if (CLI.IsVarArg)
121409467b48Spatrick     fixupVariableFloatArgs(ArgLocs, CLI.Outs);
121509467b48Spatrick 
1216*a96b3639Srobert   assert(!CLI.IsTailCall || ArgsSize == StackReserved);
1217*a96b3639Srobert 
121809467b48Spatrick   // Adjust the stack pointer to make room for the arguments.
121909467b48Spatrick   // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
122009467b48Spatrick   // with more than 6 arguments.
1221*a96b3639Srobert   if (!CLI.IsTailCall)
122209467b48Spatrick     Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL);
122309467b48Spatrick 
122409467b48Spatrick   // Collect the set of registers to pass to the function and their values.
122509467b48Spatrick   // This will be emitted as a sequence of CopyToReg nodes glued to the call
122609467b48Spatrick   // instruction.
1227097a140dSpatrick   SmallVector<std::pair<Register, SDValue>, 8> RegsToPass;
122809467b48Spatrick 
122909467b48Spatrick   // Collect chains from all the memory opeations that copy arguments to the
123009467b48Spatrick   // stack. They must follow the stack pointer adjustment above and precede the
123109467b48Spatrick   // call instruction itself.
123209467b48Spatrick   SmallVector<SDValue, 8> MemOpChains;
123309467b48Spatrick 
123409467b48Spatrick   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
123509467b48Spatrick     const CCValAssign &VA = ArgLocs[i];
123609467b48Spatrick     SDValue Arg = CLI.OutVals[i];
123709467b48Spatrick 
123809467b48Spatrick     // Promote the value if needed.
123909467b48Spatrick     switch (VA.getLocInfo()) {
124009467b48Spatrick     default:
124109467b48Spatrick       llvm_unreachable("Unknown location info!");
124209467b48Spatrick     case CCValAssign::Full:
124309467b48Spatrick       break;
124409467b48Spatrick     case CCValAssign::SExt:
124509467b48Spatrick       Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
124609467b48Spatrick       break;
124709467b48Spatrick     case CCValAssign::ZExt:
124809467b48Spatrick       Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
124909467b48Spatrick       break;
125009467b48Spatrick     case CCValAssign::AExt:
125109467b48Spatrick       Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
125209467b48Spatrick       break;
125309467b48Spatrick     case CCValAssign::BCvt:
125409467b48Spatrick       // fixupVariableFloatArgs() may create bitcasts from f128 to i128. But
125509467b48Spatrick       // SPARC does not support i128 natively. Lower it into two i64, see below.
125609467b48Spatrick       if (!VA.needsCustom() || VA.getValVT() != MVT::f128
125709467b48Spatrick           || VA.getLocVT() != MVT::i128)
125809467b48Spatrick         Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
125909467b48Spatrick       break;
126009467b48Spatrick     }
126109467b48Spatrick 
126209467b48Spatrick     if (VA.isRegLoc()) {
126309467b48Spatrick       if (VA.needsCustom() && VA.getValVT() == MVT::f128
126409467b48Spatrick           && VA.getLocVT() == MVT::i128) {
126509467b48Spatrick         // Store and reload into the integer register reg and reg+1.
126609467b48Spatrick         unsigned Offset = 8 * (VA.getLocReg() - SP::I0);
126709467b48Spatrick         unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128;
126809467b48Spatrick         SDValue StackPtr = DAG.getRegister(SP::O6, PtrVT);
126909467b48Spatrick         SDValue HiPtrOff = DAG.getIntPtrConstant(StackOffset, DL);
127009467b48Spatrick         HiPtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, HiPtrOff);
127109467b48Spatrick         SDValue LoPtrOff = DAG.getIntPtrConstant(StackOffset + 8, DL);
127209467b48Spatrick         LoPtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, LoPtrOff);
127309467b48Spatrick 
127409467b48Spatrick         // Store to %sp+BIAS+128+Offset
127509467b48Spatrick         SDValue Store =
127609467b48Spatrick             DAG.getStore(Chain, DL, Arg, HiPtrOff, MachinePointerInfo());
127709467b48Spatrick         // Load into Reg and Reg+1
127809467b48Spatrick         SDValue Hi64 =
127909467b48Spatrick             DAG.getLoad(MVT::i64, DL, Store, HiPtrOff, MachinePointerInfo());
128009467b48Spatrick         SDValue Lo64 =
128109467b48Spatrick             DAG.getLoad(MVT::i64, DL, Store, LoPtrOff, MachinePointerInfo());
1282*a96b3639Srobert 
1283*a96b3639Srobert         Register HiReg = VA.getLocReg();
1284*a96b3639Srobert         Register LoReg = VA.getLocReg() + 1;
1285*a96b3639Srobert         if (!CLI.IsTailCall) {
1286*a96b3639Srobert           HiReg = toCallerWindow(HiReg);
1287*a96b3639Srobert           LoReg = toCallerWindow(LoReg);
1288*a96b3639Srobert         }
1289*a96b3639Srobert 
1290*a96b3639Srobert         RegsToPass.push_back(std::make_pair(HiReg, Hi64));
1291*a96b3639Srobert         RegsToPass.push_back(std::make_pair(LoReg, Lo64));
129209467b48Spatrick         continue;
129309467b48Spatrick       }
129409467b48Spatrick 
129509467b48Spatrick       // The custom bit on an i32 return value indicates that it should be
129609467b48Spatrick       // passed in the high bits of the register.
129709467b48Spatrick       if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
129809467b48Spatrick         Arg = DAG.getNode(ISD::SHL, DL, MVT::i64, Arg,
129909467b48Spatrick                           DAG.getConstant(32, DL, MVT::i32));
130009467b48Spatrick 
130109467b48Spatrick         // The next value may go in the low bits of the same register.
130209467b48Spatrick         // Handle both at once.
130309467b48Spatrick         if (i+1 < ArgLocs.size() && ArgLocs[i+1].isRegLoc() &&
130409467b48Spatrick             ArgLocs[i+1].getLocReg() == VA.getLocReg()) {
130509467b48Spatrick           SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64,
130609467b48Spatrick                                    CLI.OutVals[i+1]);
130709467b48Spatrick           Arg = DAG.getNode(ISD::OR, DL, MVT::i64, Arg, NV);
130809467b48Spatrick           // Skip the next value, it's already done.
130909467b48Spatrick           ++i;
131009467b48Spatrick         }
131109467b48Spatrick       }
1312*a96b3639Srobert 
1313*a96b3639Srobert       Register Reg = VA.getLocReg();
1314*a96b3639Srobert       if (!CLI.IsTailCall)
1315*a96b3639Srobert         Reg = toCallerWindow(Reg);
1316*a96b3639Srobert       RegsToPass.push_back(std::make_pair(Reg, Arg));
131709467b48Spatrick       continue;
131809467b48Spatrick     }
131909467b48Spatrick 
132009467b48Spatrick     assert(VA.isMemLoc());
132109467b48Spatrick 
132209467b48Spatrick     // Create a store off the stack pointer for this argument.
132309467b48Spatrick     SDValue StackPtr = DAG.getRegister(SP::O6, PtrVT);
132409467b48Spatrick     // The argument area starts at %fp+BIAS+128 in the callee frame,
132509467b48Spatrick     // %sp+BIAS+128 in ours.
132609467b48Spatrick     SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() +
132709467b48Spatrick                                            Subtarget->getStackPointerBias() +
132809467b48Spatrick                                            128, DL);
132909467b48Spatrick     PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff);
133009467b48Spatrick     MemOpChains.push_back(
133109467b48Spatrick         DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
133209467b48Spatrick   }
133309467b48Spatrick 
133409467b48Spatrick   // Emit all stores, make sure they occur before the call.
133509467b48Spatrick   if (!MemOpChains.empty())
133609467b48Spatrick     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
133709467b48Spatrick 
133809467b48Spatrick   // Build a sequence of CopyToReg nodes glued together with token chain and
133909467b48Spatrick   // glue operands which copy the outgoing args into registers. The InGlue is
134009467b48Spatrick   // necessary since all emitted instructions must be stuck together in order
134109467b48Spatrick   // to pass the live physical registers.
134209467b48Spatrick   SDValue InGlue;
134309467b48Spatrick   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
134409467b48Spatrick     Chain = DAG.getCopyToReg(Chain, DL,
134509467b48Spatrick                              RegsToPass[i].first, RegsToPass[i].second, InGlue);
134609467b48Spatrick     InGlue = Chain.getValue(1);
134709467b48Spatrick   }
134809467b48Spatrick 
134909467b48Spatrick   // If the callee is a GlobalAddress node (quite common, every direct call is)
135009467b48Spatrick   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
135109467b48Spatrick   // Likewise ExternalSymbol -> TargetExternalSymbol.
135209467b48Spatrick   SDValue Callee = CLI.Callee;
1353097a140dSpatrick   bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CB);
1354a0747c9fSpatrick   unsigned TF = isPositionIndependent() ? SparcMCExpr::VK_Sparc_WPLT30
1355a0747c9fSpatrick                                         : SparcMCExpr::VK_Sparc_WDISP30;
135609467b48Spatrick   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
135709467b48Spatrick     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT, 0, TF);
135809467b48Spatrick   else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
135909467b48Spatrick     Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
136009467b48Spatrick 
136109467b48Spatrick   // Build the operands for the call instruction itself.
136209467b48Spatrick   SmallVector<SDValue, 8> Ops;
136309467b48Spatrick   Ops.push_back(Chain);
136409467b48Spatrick   Ops.push_back(Callee);
136509467b48Spatrick   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
136609467b48Spatrick     Ops.push_back(DAG.getRegister(RegsToPass[i].first,
136709467b48Spatrick                                   RegsToPass[i].second.getValueType()));
136809467b48Spatrick 
136909467b48Spatrick   // Add a register mask operand representing the call-preserved registers.
137009467b48Spatrick   const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo();
137109467b48Spatrick   const uint32_t *Mask =
137209467b48Spatrick       ((hasReturnsTwice) ? TRI->getRTCallPreservedMask(CLI.CallConv)
137309467b48Spatrick                          : TRI->getCallPreservedMask(DAG.getMachineFunction(),
137409467b48Spatrick                                                      CLI.CallConv));
137509467b48Spatrick   assert(Mask && "Missing call preserved mask for calling convention");
137609467b48Spatrick   Ops.push_back(DAG.getRegisterMask(Mask));
137709467b48Spatrick 
137809467b48Spatrick   // Make sure the CopyToReg nodes are glued to the call instruction which
137909467b48Spatrick   // consumes the registers.
138009467b48Spatrick   if (InGlue.getNode())
138109467b48Spatrick     Ops.push_back(InGlue);
138209467b48Spatrick 
138309467b48Spatrick   // Now the call itself.
1384*a96b3639Srobert   if (CLI.IsTailCall) {
1385*a96b3639Srobert     DAG.getMachineFunction().getFrameInfo().setHasTailCall();
1386*a96b3639Srobert     return DAG.getNode(SPISD::TAIL_CALL, DL, MVT::Other, Ops);
1387*a96b3639Srobert   }
138809467b48Spatrick   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
138909467b48Spatrick   Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, Ops);
139009467b48Spatrick   InGlue = Chain.getValue(1);
139109467b48Spatrick 
139209467b48Spatrick   // Revert the stack pointer immediately after the call.
1393*a96b3639Srobert   Chain = DAG.getCALLSEQ_END(Chain, ArgsSize, 0, InGlue, DL);
139409467b48Spatrick   InGlue = Chain.getValue(1);
139509467b48Spatrick 
139609467b48Spatrick   // Now extract the return values. This is more or less the same as
139709467b48Spatrick   // LowerFormalArguments_64.
139809467b48Spatrick 
139909467b48Spatrick   // Assign locations to each value returned by this call.
140009467b48Spatrick   SmallVector<CCValAssign, 16> RVLocs;
140109467b48Spatrick   CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs,
140209467b48Spatrick                  *DAG.getContext());
140309467b48Spatrick 
140409467b48Spatrick   // Set inreg flag manually for codegen generated library calls that
140509467b48Spatrick   // return float.
1406097a140dSpatrick   if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CB)
140709467b48Spatrick     CLI.Ins[0].Flags.setInReg();
140809467b48Spatrick 
140909467b48Spatrick   RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64);
141009467b48Spatrick 
141109467b48Spatrick   // Copy all of the result registers out of their specified physreg.
141209467b48Spatrick   for (unsigned i = 0; i != RVLocs.size(); ++i) {
141309467b48Spatrick     CCValAssign &VA = RVLocs[i];
1414*a96b3639Srobert     assert(VA.isRegLoc() && "Can only return in registers!");
141509467b48Spatrick     unsigned Reg = toCallerWindow(VA.getLocReg());
141609467b48Spatrick 
141709467b48Spatrick     // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
141809467b48Spatrick     // reside in the same register in the high and low bits. Reuse the
141909467b48Spatrick     // CopyFromReg previous node to avoid duplicate copies.
142009467b48Spatrick     SDValue RV;
142109467b48Spatrick     if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1)))
142209467b48Spatrick       if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg)
142309467b48Spatrick         RV = Chain.getValue(0);
142409467b48Spatrick 
142509467b48Spatrick     // But usually we'll create a new CopyFromReg for a different register.
142609467b48Spatrick     if (!RV.getNode()) {
142709467b48Spatrick       RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue);
142809467b48Spatrick       Chain = RV.getValue(1);
142909467b48Spatrick       InGlue = Chain.getValue(2);
143009467b48Spatrick     }
143109467b48Spatrick 
143209467b48Spatrick     // Get the high bits for i32 struct elements.
143309467b48Spatrick     if (VA.getValVT() == MVT::i32 && VA.needsCustom())
143409467b48Spatrick       RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV,
143509467b48Spatrick                        DAG.getConstant(32, DL, MVT::i32));
143609467b48Spatrick 
143709467b48Spatrick     // The callee promoted the return value, so insert an Assert?ext SDNode so
143809467b48Spatrick     // we won't promote the value again in this function.
143909467b48Spatrick     switch (VA.getLocInfo()) {
144009467b48Spatrick     case CCValAssign::SExt:
144109467b48Spatrick       RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV,
144209467b48Spatrick                        DAG.getValueType(VA.getValVT()));
144309467b48Spatrick       break;
144409467b48Spatrick     case CCValAssign::ZExt:
144509467b48Spatrick       RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV,
144609467b48Spatrick                        DAG.getValueType(VA.getValVT()));
144709467b48Spatrick       break;
144809467b48Spatrick     default:
144909467b48Spatrick       break;
145009467b48Spatrick     }
145109467b48Spatrick 
145209467b48Spatrick     // Truncate the register down to the return value type.
145309467b48Spatrick     if (VA.isExtInLoc())
145409467b48Spatrick       RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV);
145509467b48Spatrick 
145609467b48Spatrick     InVals.push_back(RV);
145709467b48Spatrick   }
145809467b48Spatrick 
145909467b48Spatrick   return Chain;
146009467b48Spatrick }
146109467b48Spatrick 
146209467b48Spatrick //===----------------------------------------------------------------------===//
146309467b48Spatrick // TargetLowering Implementation
146409467b48Spatrick //===----------------------------------------------------------------------===//
146509467b48Spatrick 
shouldExpandAtomicRMWInIR(AtomicRMWInst * AI) const146609467b48Spatrick TargetLowering::AtomicExpansionKind SparcTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
146709467b48Spatrick   if (AI->getOperation() == AtomicRMWInst::Xchg &&
146809467b48Spatrick       AI->getType()->getPrimitiveSizeInBits() == 32)
146909467b48Spatrick     return AtomicExpansionKind::None; // Uses xchg instruction
147009467b48Spatrick 
147109467b48Spatrick   return AtomicExpansionKind::CmpXChg;
147209467b48Spatrick }
147309467b48Spatrick 
1474*a96b3639Srobert /// intCondCCodeToRcond - Convert a DAG integer condition code to a SPARC
1475*a96b3639Srobert /// rcond condition.
intCondCCodeToRcond(ISD::CondCode CC)1476*a96b3639Srobert static SPCC::CondCodes intCondCCodeToRcond(ISD::CondCode CC) {
1477*a96b3639Srobert   switch (CC) {
1478*a96b3639Srobert   default:
1479*a96b3639Srobert     llvm_unreachable("Unknown/unsigned integer condition code!");
1480*a96b3639Srobert   case ISD::SETEQ:
1481*a96b3639Srobert     return SPCC::REG_Z;
1482*a96b3639Srobert   case ISD::SETNE:
1483*a96b3639Srobert     return SPCC::REG_NZ;
1484*a96b3639Srobert   case ISD::SETLT:
1485*a96b3639Srobert     return SPCC::REG_LZ;
1486*a96b3639Srobert   case ISD::SETGT:
1487*a96b3639Srobert     return SPCC::REG_GZ;
1488*a96b3639Srobert   case ISD::SETLE:
1489*a96b3639Srobert     return SPCC::REG_LEZ;
1490*a96b3639Srobert   case ISD::SETGE:
1491*a96b3639Srobert     return SPCC::REG_GEZ;
1492*a96b3639Srobert   }
1493*a96b3639Srobert }
1494*a96b3639Srobert 
149509467b48Spatrick /// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC
149609467b48Spatrick /// condition.
IntCondCCodeToICC(ISD::CondCode CC)149709467b48Spatrick static SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
149809467b48Spatrick   switch (CC) {
149909467b48Spatrick   default: llvm_unreachable("Unknown integer condition code!");
150009467b48Spatrick   case ISD::SETEQ:  return SPCC::ICC_E;
150109467b48Spatrick   case ISD::SETNE:  return SPCC::ICC_NE;
150209467b48Spatrick   case ISD::SETLT:  return SPCC::ICC_L;
150309467b48Spatrick   case ISD::SETGT:  return SPCC::ICC_G;
150409467b48Spatrick   case ISD::SETLE:  return SPCC::ICC_LE;
150509467b48Spatrick   case ISD::SETGE:  return SPCC::ICC_GE;
150609467b48Spatrick   case ISD::SETULT: return SPCC::ICC_CS;
150709467b48Spatrick   case ISD::SETULE: return SPCC::ICC_LEU;
150809467b48Spatrick   case ISD::SETUGT: return SPCC::ICC_GU;
150909467b48Spatrick   case ISD::SETUGE: return SPCC::ICC_CC;
151009467b48Spatrick   }
151109467b48Spatrick }
151209467b48Spatrick 
151309467b48Spatrick /// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC
151409467b48Spatrick /// FCC condition.
FPCondCCodeToFCC(ISD::CondCode CC)151509467b48Spatrick static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
151609467b48Spatrick   switch (CC) {
151709467b48Spatrick   default: llvm_unreachable("Unknown fp condition code!");
151809467b48Spatrick   case ISD::SETEQ:
151909467b48Spatrick   case ISD::SETOEQ: return SPCC::FCC_E;
152009467b48Spatrick   case ISD::SETNE:
152109467b48Spatrick   case ISD::SETUNE: return SPCC::FCC_NE;
152209467b48Spatrick   case ISD::SETLT:
152309467b48Spatrick   case ISD::SETOLT: return SPCC::FCC_L;
152409467b48Spatrick   case ISD::SETGT:
152509467b48Spatrick   case ISD::SETOGT: return SPCC::FCC_G;
152609467b48Spatrick   case ISD::SETLE:
152709467b48Spatrick   case ISD::SETOLE: return SPCC::FCC_LE;
152809467b48Spatrick   case ISD::SETGE:
152909467b48Spatrick   case ISD::SETOGE: return SPCC::FCC_GE;
153009467b48Spatrick   case ISD::SETULT: return SPCC::FCC_UL;
153109467b48Spatrick   case ISD::SETULE: return SPCC::FCC_ULE;
153209467b48Spatrick   case ISD::SETUGT: return SPCC::FCC_UG;
153309467b48Spatrick   case ISD::SETUGE: return SPCC::FCC_UGE;
153409467b48Spatrick   case ISD::SETUO:  return SPCC::FCC_U;
153509467b48Spatrick   case ISD::SETO:   return SPCC::FCC_O;
153609467b48Spatrick   case ISD::SETONE: return SPCC::FCC_LG;
153709467b48Spatrick   case ISD::SETUEQ: return SPCC::FCC_UE;
153809467b48Spatrick   }
153909467b48Spatrick }
154009467b48Spatrick 
SparcTargetLowering(const TargetMachine & TM,const SparcSubtarget & STI)154109467b48Spatrick SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
154209467b48Spatrick                                          const SparcSubtarget &STI)
154309467b48Spatrick     : TargetLowering(TM), Subtarget(&STI) {
1544*a96b3639Srobert   MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
154509467b48Spatrick 
154609467b48Spatrick   // Instructions which use registers as conditionals examine all the
154709467b48Spatrick   // bits (as does the pseudo SELECT_CC expansion). I don't think it
154809467b48Spatrick   // matters much whether it's ZeroOrOneBooleanContent, or
154909467b48Spatrick   // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the
155009467b48Spatrick   // former.
155109467b48Spatrick   setBooleanContents(ZeroOrOneBooleanContent);
155209467b48Spatrick   setBooleanVectorContents(ZeroOrOneBooleanContent);
155309467b48Spatrick 
155409467b48Spatrick   // Set up the register classes.
155509467b48Spatrick   addRegisterClass(MVT::i32, &SP::IntRegsRegClass);
155609467b48Spatrick   if (!Subtarget->useSoftFloat()) {
155709467b48Spatrick     addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
155809467b48Spatrick     addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
155909467b48Spatrick     addRegisterClass(MVT::f128, &SP::QFPRegsRegClass);
156009467b48Spatrick   }
156109467b48Spatrick   if (Subtarget->is64Bit()) {
156209467b48Spatrick     addRegisterClass(MVT::i64, &SP::I64RegsRegClass);
156309467b48Spatrick   } else {
156409467b48Spatrick     // On 32bit sparc, we define a double-register 32bit register
156509467b48Spatrick     // class, as well. This is modeled in LLVM as a 2-vector of i32.
156609467b48Spatrick     addRegisterClass(MVT::v2i32, &SP::IntPairRegClass);
156709467b48Spatrick 
156809467b48Spatrick     // ...but almost all operations must be expanded, so set that as
156909467b48Spatrick     // the default.
157009467b48Spatrick     for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op) {
157109467b48Spatrick       setOperationAction(Op, MVT::v2i32, Expand);
157209467b48Spatrick     }
157309467b48Spatrick     // Truncating/extending stores/loads are also not supported.
157409467b48Spatrick     for (MVT VT : MVT::integer_fixedlen_vector_valuetypes()) {
157509467b48Spatrick       setLoadExtAction(ISD::SEXTLOAD, VT, MVT::v2i32, Expand);
157609467b48Spatrick       setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::v2i32, Expand);
157709467b48Spatrick       setLoadExtAction(ISD::EXTLOAD, VT, MVT::v2i32, Expand);
157809467b48Spatrick 
157909467b48Spatrick       setLoadExtAction(ISD::SEXTLOAD, MVT::v2i32, VT, Expand);
158009467b48Spatrick       setLoadExtAction(ISD::ZEXTLOAD, MVT::v2i32, VT, Expand);
158109467b48Spatrick       setLoadExtAction(ISD::EXTLOAD, MVT::v2i32, VT, Expand);
158209467b48Spatrick 
158309467b48Spatrick       setTruncStoreAction(VT, MVT::v2i32, Expand);
158409467b48Spatrick       setTruncStoreAction(MVT::v2i32, VT, Expand);
158509467b48Spatrick     }
158609467b48Spatrick     // However, load and store *are* legal.
158709467b48Spatrick     setOperationAction(ISD::LOAD, MVT::v2i32, Legal);
158809467b48Spatrick     setOperationAction(ISD::STORE, MVT::v2i32, Legal);
158909467b48Spatrick     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i32, Legal);
159009467b48Spatrick     setOperationAction(ISD::BUILD_VECTOR, MVT::v2i32, Legal);
159109467b48Spatrick 
159209467b48Spatrick     // And we need to promote i64 loads/stores into vector load/store
159309467b48Spatrick     setOperationAction(ISD::LOAD, MVT::i64, Custom);
159409467b48Spatrick     setOperationAction(ISD::STORE, MVT::i64, Custom);
159509467b48Spatrick 
159609467b48Spatrick     // Sadly, this doesn't work:
159709467b48Spatrick     //    AddPromotedToType(ISD::LOAD, MVT::i64, MVT::v2i32);
159809467b48Spatrick     //    AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32);
159909467b48Spatrick   }
160009467b48Spatrick 
160109467b48Spatrick   // Turn FP extload into load/fpextend
160209467b48Spatrick   for (MVT VT : MVT::fp_valuetypes()) {
1603097a140dSpatrick     setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
160409467b48Spatrick     setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
160509467b48Spatrick     setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand);
160609467b48Spatrick   }
160709467b48Spatrick 
160809467b48Spatrick   // Sparc doesn't have i1 sign extending load
160909467b48Spatrick   for (MVT VT : MVT::integer_valuetypes())
161009467b48Spatrick     setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
161109467b48Spatrick 
161209467b48Spatrick   // Turn FP truncstore into trunc + store.
1613097a140dSpatrick   setTruncStoreAction(MVT::f32, MVT::f16, Expand);
1614097a140dSpatrick   setTruncStoreAction(MVT::f64, MVT::f16, Expand);
161509467b48Spatrick   setTruncStoreAction(MVT::f64, MVT::f32, Expand);
1616a0747c9fSpatrick   setTruncStoreAction(MVT::f128, MVT::f16, Expand);
161709467b48Spatrick   setTruncStoreAction(MVT::f128, MVT::f32, Expand);
161809467b48Spatrick   setTruncStoreAction(MVT::f128, MVT::f64, Expand);
161909467b48Spatrick 
162009467b48Spatrick   // Custom legalize GlobalAddress nodes into LO/HI parts.
162109467b48Spatrick   setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
162209467b48Spatrick   setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);
162309467b48Spatrick   setOperationAction(ISD::ConstantPool, PtrVT, Custom);
162409467b48Spatrick   setOperationAction(ISD::BlockAddress, PtrVT, Custom);
162509467b48Spatrick 
162609467b48Spatrick   // Sparc doesn't have sext_inreg, replace them with shl/sra
162709467b48Spatrick   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
162809467b48Spatrick   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
162909467b48Spatrick   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
163009467b48Spatrick 
163109467b48Spatrick   // Sparc has no REM or DIVREM operations.
163209467b48Spatrick   setOperationAction(ISD::UREM, MVT::i32, Expand);
163309467b48Spatrick   setOperationAction(ISD::SREM, MVT::i32, Expand);
163409467b48Spatrick   setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
163509467b48Spatrick   setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
163609467b48Spatrick 
163709467b48Spatrick   // ... nor does SparcV9.
163809467b48Spatrick   if (Subtarget->is64Bit()) {
163909467b48Spatrick     setOperationAction(ISD::UREM, MVT::i64, Expand);
164009467b48Spatrick     setOperationAction(ISD::SREM, MVT::i64, Expand);
164109467b48Spatrick     setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
164209467b48Spatrick     setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
164309467b48Spatrick   }
164409467b48Spatrick 
164509467b48Spatrick   // Custom expand fp<->sint
164609467b48Spatrick   setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
164709467b48Spatrick   setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
164809467b48Spatrick   setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
164909467b48Spatrick   setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
165009467b48Spatrick 
165109467b48Spatrick   // Custom Expand fp<->uint
165209467b48Spatrick   setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
165309467b48Spatrick   setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
165409467b48Spatrick   setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
165509467b48Spatrick   setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
165609467b48Spatrick 
1657097a140dSpatrick   // Lower f16 conversion operations into library calls
1658097a140dSpatrick   setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
1659097a140dSpatrick   setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
1660097a140dSpatrick   setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
1661097a140dSpatrick   setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);
1662a0747c9fSpatrick   setOperationAction(ISD::FP16_TO_FP, MVT::f128, Expand);
1663a0747c9fSpatrick   setOperationAction(ISD::FP_TO_FP16, MVT::f128, Expand);
1664097a140dSpatrick 
166509467b48Spatrick   setOperationAction(ISD::BITCAST, MVT::f32, Expand);
166609467b48Spatrick   setOperationAction(ISD::BITCAST, MVT::i32, Expand);
166709467b48Spatrick 
166809467b48Spatrick   // Sparc has no select or setcc: expand to SELECT_CC.
166909467b48Spatrick   setOperationAction(ISD::SELECT, MVT::i32, Expand);
167009467b48Spatrick   setOperationAction(ISD::SELECT, MVT::f32, Expand);
167109467b48Spatrick   setOperationAction(ISD::SELECT, MVT::f64, Expand);
167209467b48Spatrick   setOperationAction(ISD::SELECT, MVT::f128, Expand);
167309467b48Spatrick 
167409467b48Spatrick   setOperationAction(ISD::SETCC, MVT::i32, Expand);
167509467b48Spatrick   setOperationAction(ISD::SETCC, MVT::f32, Expand);
167609467b48Spatrick   setOperationAction(ISD::SETCC, MVT::f64, Expand);
167709467b48Spatrick   setOperationAction(ISD::SETCC, MVT::f128, Expand);
167809467b48Spatrick 
167909467b48Spatrick   // Sparc doesn't have BRCOND either, it has BR_CC.
168009467b48Spatrick   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
168109467b48Spatrick   setOperationAction(ISD::BRIND, MVT::Other, Expand);
168209467b48Spatrick   setOperationAction(ISD::BR_JT, MVT::Other, Expand);
168309467b48Spatrick   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
168409467b48Spatrick   setOperationAction(ISD::BR_CC, MVT::f32, Custom);
168509467b48Spatrick   setOperationAction(ISD::BR_CC, MVT::f64, Custom);
168609467b48Spatrick   setOperationAction(ISD::BR_CC, MVT::f128, Custom);
168709467b48Spatrick 
168809467b48Spatrick   setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
168909467b48Spatrick   setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
169009467b48Spatrick   setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
169109467b48Spatrick   setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);
169209467b48Spatrick 
169309467b48Spatrick   setOperationAction(ISD::ADDC, MVT::i32, Custom);
169409467b48Spatrick   setOperationAction(ISD::ADDE, MVT::i32, Custom);
169509467b48Spatrick   setOperationAction(ISD::SUBC, MVT::i32, Custom);
169609467b48Spatrick   setOperationAction(ISD::SUBE, MVT::i32, Custom);
169709467b48Spatrick 
169809467b48Spatrick   if (Subtarget->is64Bit()) {
169909467b48Spatrick     setOperationAction(ISD::ADDC, MVT::i64, Custom);
170009467b48Spatrick     setOperationAction(ISD::ADDE, MVT::i64, Custom);
170109467b48Spatrick     setOperationAction(ISD::SUBC, MVT::i64, Custom);
170209467b48Spatrick     setOperationAction(ISD::SUBE, MVT::i64, Custom);
170309467b48Spatrick     setOperationAction(ISD::BITCAST, MVT::f64, Expand);
170409467b48Spatrick     setOperationAction(ISD::BITCAST, MVT::i64, Expand);
170509467b48Spatrick     setOperationAction(ISD::SELECT, MVT::i64, Expand);
170609467b48Spatrick     setOperationAction(ISD::SETCC, MVT::i64, Expand);
170709467b48Spatrick     setOperationAction(ISD::BR_CC, MVT::i64, Custom);
170809467b48Spatrick     setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
170909467b48Spatrick 
171009467b48Spatrick     setOperationAction(ISD::CTPOP, MVT::i64,
171109467b48Spatrick                        Subtarget->usePopc() ? Legal : Expand);
171209467b48Spatrick     setOperationAction(ISD::CTTZ , MVT::i64, Expand);
171309467b48Spatrick     setOperationAction(ISD::CTLZ , MVT::i64, Expand);
171409467b48Spatrick     setOperationAction(ISD::BSWAP, MVT::i64, Expand);
171509467b48Spatrick     setOperationAction(ISD::ROTL , MVT::i64, Expand);
171609467b48Spatrick     setOperationAction(ISD::ROTR , MVT::i64, Expand);
171709467b48Spatrick     setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
171809467b48Spatrick   }
171909467b48Spatrick 
172009467b48Spatrick   // ATOMICs.
172109467b48Spatrick   // Atomics are supported on SparcV9. 32-bit atomics are also
172209467b48Spatrick   // supported by some Leon SparcV8 variants. Otherwise, atomics
172309467b48Spatrick   // are unsupported.
172409467b48Spatrick   if (Subtarget->isV9())
172509467b48Spatrick     setMaxAtomicSizeInBitsSupported(64);
172609467b48Spatrick   else if (Subtarget->hasLeonCasa())
172709467b48Spatrick     setMaxAtomicSizeInBitsSupported(32);
172809467b48Spatrick   else
172909467b48Spatrick     setMaxAtomicSizeInBitsSupported(0);
173009467b48Spatrick 
173109467b48Spatrick   setMinCmpXchgSizeInBits(32);
173209467b48Spatrick 
173309467b48Spatrick   setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Legal);
173409467b48Spatrick 
173509467b48Spatrick   setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Legal);
173609467b48Spatrick 
173709467b48Spatrick   // Custom Lower Atomic LOAD/STORE
173809467b48Spatrick   setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Custom);
173909467b48Spatrick   setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Custom);
174009467b48Spatrick 
174109467b48Spatrick   if (Subtarget->is64Bit()) {
174209467b48Spatrick     setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Legal);
174309467b48Spatrick     setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Legal);
174409467b48Spatrick     setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Custom);
174509467b48Spatrick     setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom);
174609467b48Spatrick   }
174709467b48Spatrick 
174809467b48Spatrick   if (!Subtarget->is64Bit()) {
174909467b48Spatrick     // These libcalls are not available in 32-bit.
1750*a96b3639Srobert     setLibcallName(RTLIB::MULO_I64, nullptr);
175109467b48Spatrick     setLibcallName(RTLIB::SHL_I128, nullptr);
175209467b48Spatrick     setLibcallName(RTLIB::SRL_I128, nullptr);
175309467b48Spatrick     setLibcallName(RTLIB::SRA_I128, nullptr);
175409467b48Spatrick   }
175509467b48Spatrick 
1756*a96b3639Srobert   setLibcallName(RTLIB::MULO_I128, nullptr);
1757*a96b3639Srobert 
175809467b48Spatrick   if (!Subtarget->isV9()) {
175909467b48Spatrick     // SparcV8 does not have FNEGD and FABSD.
176009467b48Spatrick     setOperationAction(ISD::FNEG, MVT::f64, Custom);
176109467b48Spatrick     setOperationAction(ISD::FABS, MVT::f64, Custom);
176209467b48Spatrick   }
176309467b48Spatrick 
176409467b48Spatrick   setOperationAction(ISD::FSIN , MVT::f128, Expand);
176509467b48Spatrick   setOperationAction(ISD::FCOS , MVT::f128, Expand);
176609467b48Spatrick   setOperationAction(ISD::FSINCOS, MVT::f128, Expand);
176709467b48Spatrick   setOperationAction(ISD::FREM , MVT::f128, Expand);
176809467b48Spatrick   setOperationAction(ISD::FMA  , MVT::f128, Expand);
176909467b48Spatrick   setOperationAction(ISD::FSIN , MVT::f64, Expand);
177009467b48Spatrick   setOperationAction(ISD::FCOS , MVT::f64, Expand);
177109467b48Spatrick   setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
177209467b48Spatrick   setOperationAction(ISD::FREM , MVT::f64, Expand);
177309467b48Spatrick   setOperationAction(ISD::FMA  , MVT::f64, Expand);
177409467b48Spatrick   setOperationAction(ISD::FSIN , MVT::f32, Expand);
177509467b48Spatrick   setOperationAction(ISD::FCOS , MVT::f32, Expand);
177609467b48Spatrick   setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
177709467b48Spatrick   setOperationAction(ISD::FREM , MVT::f32, Expand);
177809467b48Spatrick   setOperationAction(ISD::FMA  , MVT::f32, Expand);
177909467b48Spatrick   setOperationAction(ISD::CTTZ , MVT::i32, Expand);
178009467b48Spatrick   setOperationAction(ISD::CTLZ , MVT::i32, Expand);
178109467b48Spatrick   setOperationAction(ISD::ROTL , MVT::i32, Expand);
178209467b48Spatrick   setOperationAction(ISD::ROTR , MVT::i32, Expand);
178309467b48Spatrick   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
178409467b48Spatrick   setOperationAction(ISD::FCOPYSIGN, MVT::f128, Expand);
178509467b48Spatrick   setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
178609467b48Spatrick   setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
178709467b48Spatrick   setOperationAction(ISD::FPOW , MVT::f128, Expand);
178809467b48Spatrick   setOperationAction(ISD::FPOW , MVT::f64, Expand);
178909467b48Spatrick   setOperationAction(ISD::FPOW , MVT::f32, Expand);
179009467b48Spatrick 
179109467b48Spatrick   setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
179209467b48Spatrick   setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
179309467b48Spatrick   setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
179409467b48Spatrick 
179509467b48Spatrick   // Expands to [SU]MUL_LOHI.
179609467b48Spatrick   setOperationAction(ISD::MULHU,     MVT::i32, Expand);
179709467b48Spatrick   setOperationAction(ISD::MULHS,     MVT::i32, Expand);
179809467b48Spatrick   setOperationAction(ISD::MUL,       MVT::i32, Expand);
179909467b48Spatrick 
180009467b48Spatrick   if (Subtarget->useSoftMulDiv()) {
180109467b48Spatrick     // .umul works for both signed and unsigned
180209467b48Spatrick     setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
180309467b48Spatrick     setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
180409467b48Spatrick     setLibcallName(RTLIB::MUL_I32, ".umul");
180509467b48Spatrick 
180609467b48Spatrick     setOperationAction(ISD::SDIV, MVT::i32, Expand);
180709467b48Spatrick     setLibcallName(RTLIB::SDIV_I32, ".div");
180809467b48Spatrick 
180909467b48Spatrick     setOperationAction(ISD::UDIV, MVT::i32, Expand);
181009467b48Spatrick     setLibcallName(RTLIB::UDIV_I32, ".udiv");
181109467b48Spatrick 
181209467b48Spatrick     setLibcallName(RTLIB::SREM_I32, ".rem");
181309467b48Spatrick     setLibcallName(RTLIB::UREM_I32, ".urem");
181409467b48Spatrick   }
181509467b48Spatrick 
181609467b48Spatrick   if (Subtarget->is64Bit()) {
181709467b48Spatrick     setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
181809467b48Spatrick     setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
181909467b48Spatrick     setOperationAction(ISD::MULHU,     MVT::i64, Expand);
182009467b48Spatrick     setOperationAction(ISD::MULHS,     MVT::i64, Expand);
182109467b48Spatrick 
182209467b48Spatrick     setOperationAction(ISD::UMULO,     MVT::i64, Custom);
182309467b48Spatrick     setOperationAction(ISD::SMULO,     MVT::i64, Custom);
182409467b48Spatrick 
182509467b48Spatrick     setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
182609467b48Spatrick     setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
182709467b48Spatrick     setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
182809467b48Spatrick   }
182909467b48Spatrick 
183009467b48Spatrick   // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
183109467b48Spatrick   setOperationAction(ISD::VASTART           , MVT::Other, Custom);
183209467b48Spatrick   // VAARG needs to be lowered to not do unaligned accesses for doubles.
183309467b48Spatrick   setOperationAction(ISD::VAARG             , MVT::Other, Custom);
183409467b48Spatrick 
183509467b48Spatrick   setOperationAction(ISD::TRAP              , MVT::Other, Legal);
183609467b48Spatrick   setOperationAction(ISD::DEBUGTRAP         , MVT::Other, Legal);
183709467b48Spatrick 
183809467b48Spatrick   // Use the default implementation.
183909467b48Spatrick   setOperationAction(ISD::VACOPY            , MVT::Other, Expand);
184009467b48Spatrick   setOperationAction(ISD::VAEND             , MVT::Other, Expand);
184109467b48Spatrick   setOperationAction(ISD::STACKSAVE         , MVT::Other, Expand);
184209467b48Spatrick   setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
184309467b48Spatrick   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
184409467b48Spatrick 
184509467b48Spatrick   setStackPointerRegisterToSaveRestore(SP::O6);
184609467b48Spatrick 
184709467b48Spatrick   setOperationAction(ISD::CTPOP, MVT::i32,
184809467b48Spatrick                      Subtarget->usePopc() ? Legal : Expand);
184909467b48Spatrick 
185009467b48Spatrick   if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
185109467b48Spatrick     setOperationAction(ISD::LOAD, MVT::f128, Legal);
185209467b48Spatrick     setOperationAction(ISD::STORE, MVT::f128, Legal);
185309467b48Spatrick   } else {
185409467b48Spatrick     setOperationAction(ISD::LOAD, MVT::f128, Custom);
185509467b48Spatrick     setOperationAction(ISD::STORE, MVT::f128, Custom);
185609467b48Spatrick   }
185709467b48Spatrick 
185809467b48Spatrick   if (Subtarget->hasHardQuad()) {
185909467b48Spatrick     setOperationAction(ISD::FADD,  MVT::f128, Legal);
186009467b48Spatrick     setOperationAction(ISD::FSUB,  MVT::f128, Legal);
186109467b48Spatrick     setOperationAction(ISD::FMUL,  MVT::f128, Legal);
186209467b48Spatrick     setOperationAction(ISD::FDIV,  MVT::f128, Legal);
186309467b48Spatrick     setOperationAction(ISD::FSQRT, MVT::f128, Legal);
186409467b48Spatrick     setOperationAction(ISD::FP_EXTEND, MVT::f128, Legal);
186509467b48Spatrick     setOperationAction(ISD::FP_ROUND,  MVT::f64, Legal);
186609467b48Spatrick     if (Subtarget->isV9()) {
186709467b48Spatrick       setOperationAction(ISD::FNEG, MVT::f128, Legal);
186809467b48Spatrick       setOperationAction(ISD::FABS, MVT::f128, Legal);
186909467b48Spatrick     } else {
187009467b48Spatrick       setOperationAction(ISD::FNEG, MVT::f128, Custom);
187109467b48Spatrick       setOperationAction(ISD::FABS, MVT::f128, Custom);
187209467b48Spatrick     }
187309467b48Spatrick 
187409467b48Spatrick     if (!Subtarget->is64Bit()) {
187509467b48Spatrick       setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll");
187609467b48Spatrick       setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull");
187709467b48Spatrick       setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq");
187809467b48Spatrick       setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq");
187909467b48Spatrick     }
188009467b48Spatrick 
188109467b48Spatrick   } else {
188209467b48Spatrick     // Custom legalize f128 operations.
188309467b48Spatrick 
188409467b48Spatrick     setOperationAction(ISD::FADD,  MVT::f128, Custom);
188509467b48Spatrick     setOperationAction(ISD::FSUB,  MVT::f128, Custom);
188609467b48Spatrick     setOperationAction(ISD::FMUL,  MVT::f128, Custom);
188709467b48Spatrick     setOperationAction(ISD::FDIV,  MVT::f128, Custom);
188809467b48Spatrick     setOperationAction(ISD::FSQRT, MVT::f128, Custom);
188909467b48Spatrick     setOperationAction(ISD::FNEG,  MVT::f128, Custom);
189009467b48Spatrick     setOperationAction(ISD::FABS,  MVT::f128, Custom);
189109467b48Spatrick 
189209467b48Spatrick     setOperationAction(ISD::FP_EXTEND, MVT::f128, Custom);
189309467b48Spatrick     setOperationAction(ISD::FP_ROUND,  MVT::f64, Custom);
189409467b48Spatrick     setOperationAction(ISD::FP_ROUND,  MVT::f32, Custom);
189509467b48Spatrick 
189609467b48Spatrick     // Setup Runtime library names.
189709467b48Spatrick     if (Subtarget->is64Bit() && !Subtarget->useSoftFloat()) {
189809467b48Spatrick       setLibcallName(RTLIB::ADD_F128,  "_Qp_add");
189909467b48Spatrick       setLibcallName(RTLIB::SUB_F128,  "_Qp_sub");
190009467b48Spatrick       setLibcallName(RTLIB::MUL_F128,  "_Qp_mul");
190109467b48Spatrick       setLibcallName(RTLIB::DIV_F128,  "_Qp_div");
190209467b48Spatrick       setLibcallName(RTLIB::SQRT_F128, "_Qp_sqrt");
190309467b48Spatrick       setLibcallName(RTLIB::FPTOSINT_F128_I32, "_Qp_qtoi");
190409467b48Spatrick       setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Qp_qtoui");
190509467b48Spatrick       setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Qp_itoq");
190609467b48Spatrick       setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Qp_uitoq");
190709467b48Spatrick       setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Qp_qtox");
190809467b48Spatrick       setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Qp_qtoux");
190909467b48Spatrick       setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Qp_xtoq");
191009467b48Spatrick       setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Qp_uxtoq");
191109467b48Spatrick       setLibcallName(RTLIB::FPEXT_F32_F128, "_Qp_stoq");
191209467b48Spatrick       setLibcallName(RTLIB::FPEXT_F64_F128, "_Qp_dtoq");
191309467b48Spatrick       setLibcallName(RTLIB::FPROUND_F128_F32, "_Qp_qtos");
191409467b48Spatrick       setLibcallName(RTLIB::FPROUND_F128_F64, "_Qp_qtod");
191509467b48Spatrick     } else if (!Subtarget->useSoftFloat()) {
191609467b48Spatrick       setLibcallName(RTLIB::ADD_F128,  "_Q_add");
191709467b48Spatrick       setLibcallName(RTLIB::SUB_F128,  "_Q_sub");
191809467b48Spatrick       setLibcallName(RTLIB::MUL_F128,  "_Q_mul");
191909467b48Spatrick       setLibcallName(RTLIB::DIV_F128,  "_Q_div");
192009467b48Spatrick       setLibcallName(RTLIB::SQRT_F128, "_Q_sqrt");
192109467b48Spatrick       setLibcallName(RTLIB::FPTOSINT_F128_I32, "_Q_qtoi");
192209467b48Spatrick       setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Q_qtou");
192309467b48Spatrick       setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Q_itoq");
192409467b48Spatrick       setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Q_utoq");
192509467b48Spatrick       setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll");
192609467b48Spatrick       setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull");
192709467b48Spatrick       setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq");
192809467b48Spatrick       setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq");
192909467b48Spatrick       setLibcallName(RTLIB::FPEXT_F32_F128, "_Q_stoq");
193009467b48Spatrick       setLibcallName(RTLIB::FPEXT_F64_F128, "_Q_dtoq");
193109467b48Spatrick       setLibcallName(RTLIB::FPROUND_F128_F32, "_Q_qtos");
193209467b48Spatrick       setLibcallName(RTLIB::FPROUND_F128_F64, "_Q_qtod");
193309467b48Spatrick     }
193409467b48Spatrick   }
193509467b48Spatrick 
193609467b48Spatrick   if (Subtarget->fixAllFDIVSQRT()) {
193709467b48Spatrick     // Promote FDIVS and FSQRTS to FDIVD and FSQRTD instructions instead as
193809467b48Spatrick     // the former instructions generate errata on LEON processors.
193909467b48Spatrick     setOperationAction(ISD::FDIV, MVT::f32, Promote);
194009467b48Spatrick     setOperationAction(ISD::FSQRT, MVT::f32, Promote);
194109467b48Spatrick   }
194209467b48Spatrick 
194309467b48Spatrick   if (Subtarget->hasNoFMULS()) {
194409467b48Spatrick     setOperationAction(ISD::FMUL, MVT::f32, Promote);
194509467b48Spatrick   }
194609467b48Spatrick 
194709467b48Spatrick   // Custom combine bitcast between f64 and v2i32
194809467b48Spatrick   if (!Subtarget->is64Bit())
194909467b48Spatrick     setTargetDAGCombine(ISD::BITCAST);
195009467b48Spatrick 
195109467b48Spatrick   if (Subtarget->hasLeonCycleCounter())
195209467b48Spatrick     setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
195309467b48Spatrick 
195409467b48Spatrick   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
195509467b48Spatrick 
195609467b48Spatrick   setMinFunctionAlignment(Align(4));
195709467b48Spatrick 
195809467b48Spatrick   computeRegisterProperties(Subtarget->getRegisterInfo());
195909467b48Spatrick }
196009467b48Spatrick 
useSoftFloat() const196109467b48Spatrick bool SparcTargetLowering::useSoftFloat() const {
196209467b48Spatrick   return Subtarget->useSoftFloat();
196309467b48Spatrick }
196409467b48Spatrick 
getTargetNodeName(unsigned Opcode) const196509467b48Spatrick const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
196609467b48Spatrick   switch ((SPISD::NodeType)Opcode) {
196709467b48Spatrick   case SPISD::FIRST_NUMBER:    break;
196809467b48Spatrick   case SPISD::CMPICC:          return "SPISD::CMPICC";
196909467b48Spatrick   case SPISD::CMPFCC:          return "SPISD::CMPFCC";
1970*a96b3639Srobert   case SPISD::CMPFCC_V9:
1971*a96b3639Srobert     return "SPISD::CMPFCC_V9";
197209467b48Spatrick   case SPISD::BRICC:           return "SPISD::BRICC";
1973*a96b3639Srobert   case SPISD::BPICC:
1974*a96b3639Srobert     return "SPISD::BPICC";
1975*a96b3639Srobert   case SPISD::BPXCC:
1976*a96b3639Srobert     return "SPISD::BPXCC";
197709467b48Spatrick   case SPISD::BRFCC:           return "SPISD::BRFCC";
1978*a96b3639Srobert   case SPISD::BRFCC_V9:
1979*a96b3639Srobert     return "SPISD::BRFCC_V9";
198009467b48Spatrick   case SPISD::SELECT_ICC:      return "SPISD::SELECT_ICC";
198109467b48Spatrick   case SPISD::SELECT_XCC:      return "SPISD::SELECT_XCC";
198209467b48Spatrick   case SPISD::SELECT_FCC:      return "SPISD::SELECT_FCC";
1983*a96b3639Srobert   case SPISD::SELECT_REG:
1984*a96b3639Srobert     return "SPISD::SELECT_REG";
198509467b48Spatrick   case SPISD::Hi:              return "SPISD::Hi";
198609467b48Spatrick   case SPISD::Lo:              return "SPISD::Lo";
198709467b48Spatrick   case SPISD::FTOI:            return "SPISD::FTOI";
198809467b48Spatrick   case SPISD::ITOF:            return "SPISD::ITOF";
198909467b48Spatrick   case SPISD::FTOX:            return "SPISD::FTOX";
199009467b48Spatrick   case SPISD::XTOF:            return "SPISD::XTOF";
199109467b48Spatrick   case SPISD::CALL:            return "SPISD::CALL";
199209467b48Spatrick   case SPISD::RET_FLAG:        return "SPISD::RET_FLAG";
199309467b48Spatrick   case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";
199409467b48Spatrick   case SPISD::FLUSHW:          return "SPISD::FLUSHW";
199509467b48Spatrick   case SPISD::TLS_ADD:         return "SPISD::TLS_ADD";
199609467b48Spatrick   case SPISD::TLS_LD:          return "SPISD::TLS_LD";
199709467b48Spatrick   case SPISD::TLS_CALL:        return "SPISD::TLS_CALL";
1998*a96b3639Srobert   case SPISD::TAIL_CALL:       return "SPISD::TAIL_CALL";
1999*a96b3639Srobert   case SPISD::LOAD_GDOP:       return "SPISD::LOAD_GDOP";
200009467b48Spatrick   }
200109467b48Spatrick   return nullptr;
200209467b48Spatrick }
200309467b48Spatrick 
getSetCCResultType(const DataLayout &,LLVMContext &,EVT VT) const200409467b48Spatrick EVT SparcTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
200509467b48Spatrick                                             EVT VT) const {
200609467b48Spatrick   if (!VT.isVector())
200709467b48Spatrick     return MVT::i32;
200809467b48Spatrick   return VT.changeVectorElementTypeToInteger();
200909467b48Spatrick }
201009467b48Spatrick 
201109467b48Spatrick /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
201209467b48Spatrick /// be zero. Op is expected to be a target specific node. Used by DAG
201309467b48Spatrick /// combiner.
computeKnownBitsForTargetNode(const SDValue Op,KnownBits & Known,const APInt & DemandedElts,const SelectionDAG & DAG,unsigned Depth) const201409467b48Spatrick void SparcTargetLowering::computeKnownBitsForTargetNode
201509467b48Spatrick                                 (const SDValue Op,
201609467b48Spatrick                                  KnownBits &Known,
201709467b48Spatrick                                  const APInt &DemandedElts,
201809467b48Spatrick                                  const SelectionDAG &DAG,
201909467b48Spatrick                                  unsigned Depth) const {
202009467b48Spatrick   KnownBits Known2;
202109467b48Spatrick   Known.resetAll();
202209467b48Spatrick 
202309467b48Spatrick   switch (Op.getOpcode()) {
202409467b48Spatrick   default: break;
202509467b48Spatrick   case SPISD::SELECT_ICC:
202609467b48Spatrick   case SPISD::SELECT_XCC:
202709467b48Spatrick   case SPISD::SELECT_FCC:
202809467b48Spatrick     Known = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
202909467b48Spatrick     Known2 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
203009467b48Spatrick 
203109467b48Spatrick     // Only known if known in both the LHS and RHS.
2032a0747c9fSpatrick     Known = KnownBits::commonBits(Known, Known2);
203309467b48Spatrick     break;
203409467b48Spatrick   }
203509467b48Spatrick }
203609467b48Spatrick 
203709467b48Spatrick // Look at LHS/RHS/CC and see if they are a lowered setcc instruction.  If so
203809467b48Spatrick // set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
LookThroughSetCC(SDValue & LHS,SDValue & RHS,ISD::CondCode CC,unsigned & SPCC)203909467b48Spatrick static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
204009467b48Spatrick                              ISD::CondCode CC, unsigned &SPCC) {
2041*a96b3639Srobert   if (isNullConstant(RHS) && CC == ISD::SETNE &&
204209467b48Spatrick       (((LHS.getOpcode() == SPISD::SELECT_ICC ||
204309467b48Spatrick          LHS.getOpcode() == SPISD::SELECT_XCC) &&
204409467b48Spatrick         LHS.getOperand(3).getOpcode() == SPISD::CMPICC) ||
204509467b48Spatrick        (LHS.getOpcode() == SPISD::SELECT_FCC &&
2046*a96b3639Srobert         (LHS.getOperand(3).getOpcode() == SPISD::CMPFCC ||
2047*a96b3639Srobert          LHS.getOperand(3).getOpcode() == SPISD::CMPFCC_V9))) &&
2048*a96b3639Srobert       isOneConstant(LHS.getOperand(0)) && isNullConstant(LHS.getOperand(1))) {
204909467b48Spatrick     SDValue CMPCC = LHS.getOperand(3);
205009467b48Spatrick     SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
205109467b48Spatrick     LHS = CMPCC.getOperand(0);
205209467b48Spatrick     RHS = CMPCC.getOperand(1);
205309467b48Spatrick   }
205409467b48Spatrick }
205509467b48Spatrick 
205609467b48Spatrick // Convert to a target node and set target flags.
withTargetFlags(SDValue Op,unsigned TF,SelectionDAG & DAG) const205709467b48Spatrick SDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF,
205809467b48Spatrick                                              SelectionDAG &DAG) const {
205909467b48Spatrick   if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
206009467b48Spatrick     return DAG.getTargetGlobalAddress(GA->getGlobal(),
206109467b48Spatrick                                       SDLoc(GA),
206209467b48Spatrick                                       GA->getValueType(0),
206309467b48Spatrick                                       GA->getOffset(), TF);
206409467b48Spatrick 
206509467b48Spatrick   if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op))
2066097a140dSpatrick     return DAG.getTargetConstantPool(CP->getConstVal(), CP->getValueType(0),
2067097a140dSpatrick                                      CP->getAlign(), CP->getOffset(), TF);
206809467b48Spatrick 
206909467b48Spatrick   if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op))
207009467b48Spatrick     return DAG.getTargetBlockAddress(BA->getBlockAddress(),
207109467b48Spatrick                                      Op.getValueType(),
207209467b48Spatrick                                      0,
207309467b48Spatrick                                      TF);
207409467b48Spatrick 
207509467b48Spatrick   if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op))
207609467b48Spatrick     return DAG.getTargetExternalSymbol(ES->getSymbol(),
207709467b48Spatrick                                        ES->getValueType(0), TF);
207809467b48Spatrick 
207909467b48Spatrick   llvm_unreachable("Unhandled address SDNode");
208009467b48Spatrick }
208109467b48Spatrick 
208209467b48Spatrick // Split Op into high and low parts according to HiTF and LoTF.
208309467b48Spatrick // Return an ADD node combining the parts.
makeHiLoPair(SDValue Op,unsigned HiTF,unsigned LoTF,SelectionDAG & DAG) const208409467b48Spatrick SDValue SparcTargetLowering::makeHiLoPair(SDValue Op,
208509467b48Spatrick                                           unsigned HiTF, unsigned LoTF,
208609467b48Spatrick                                           SelectionDAG &DAG) const {
208709467b48Spatrick   SDLoc DL(Op);
208809467b48Spatrick   EVT VT = Op.getValueType();
208909467b48Spatrick   SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
209009467b48Spatrick   SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
209109467b48Spatrick   return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
209209467b48Spatrick }
209309467b48Spatrick 
209409467b48Spatrick // Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
209509467b48Spatrick // or ExternalSymbol SDNode.
makeAddress(SDValue Op,SelectionDAG & DAG) const209609467b48Spatrick SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
209709467b48Spatrick   SDLoc DL(Op);
209809467b48Spatrick   EVT VT = getPointerTy(DAG.getDataLayout());
209909467b48Spatrick 
210009467b48Spatrick   // Handle PIC mode first. SPARC needs a got load for every variable!
210109467b48Spatrick   if (isPositionIndependent()) {
210209467b48Spatrick     const Module *M = DAG.getMachineFunction().getFunction().getParent();
210309467b48Spatrick     PICLevel::Level picLevel = M->getPICLevel();
210409467b48Spatrick     SDValue Idx;
210509467b48Spatrick 
210609467b48Spatrick     if (picLevel == PICLevel::SmallPIC) {
210709467b48Spatrick       // This is the pic13 code model, the GOT is known to be smaller than 8KiB.
210809467b48Spatrick       Idx = DAG.getNode(SPISD::Lo, DL, Op.getValueType(),
210909467b48Spatrick                         withTargetFlags(Op, SparcMCExpr::VK_Sparc_GOT13, DAG));
211009467b48Spatrick     } else {
211109467b48Spatrick       // This is the pic32 code model, the GOT is known to be smaller than 4GB.
211209467b48Spatrick       Idx = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22,
211309467b48Spatrick                          SparcMCExpr::VK_Sparc_GOT10, DAG);
211409467b48Spatrick     }
211509467b48Spatrick 
211609467b48Spatrick     SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
211709467b48Spatrick     SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Idx);
211809467b48Spatrick     // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
211909467b48Spatrick     // function has calls.
212009467b48Spatrick     MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
212109467b48Spatrick     MFI.setHasCalls(true);
212209467b48Spatrick     return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr,
212309467b48Spatrick                        MachinePointerInfo::getGOT(DAG.getMachineFunction()));
212409467b48Spatrick   }
212509467b48Spatrick 
212609467b48Spatrick   // This is one of the absolute code models.
212709467b48Spatrick   switch(getTargetMachine().getCodeModel()) {
212809467b48Spatrick   default:
212909467b48Spatrick     llvm_unreachable("Unsupported absolute code model");
213009467b48Spatrick   case CodeModel::Small:
213109467b48Spatrick     // abs32.
213209467b48Spatrick     return makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
213309467b48Spatrick                         SparcMCExpr::VK_Sparc_LO, DAG);
213409467b48Spatrick   case CodeModel::Medium: {
213509467b48Spatrick     // abs44.
213609467b48Spatrick     SDValue H44 = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_H44,
213709467b48Spatrick                                SparcMCExpr::VK_Sparc_M44, DAG);
213809467b48Spatrick     H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getConstant(12, DL, MVT::i32));
213909467b48Spatrick     SDValue L44 = withTargetFlags(Op, SparcMCExpr::VK_Sparc_L44, DAG);
214009467b48Spatrick     L44 = DAG.getNode(SPISD::Lo, DL, VT, L44);
214109467b48Spatrick     return DAG.getNode(ISD::ADD, DL, VT, H44, L44);
214209467b48Spatrick   }
214309467b48Spatrick   case CodeModel::Large: {
214409467b48Spatrick     // abs64.
214509467b48Spatrick     SDValue Hi = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HH,
214609467b48Spatrick                               SparcMCExpr::VK_Sparc_HM, DAG);
214709467b48Spatrick     Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(32, DL, MVT::i32));
214809467b48Spatrick     SDValue Lo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
214909467b48Spatrick                               SparcMCExpr::VK_Sparc_LO, DAG);
215009467b48Spatrick     return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
215109467b48Spatrick   }
215209467b48Spatrick   }
215309467b48Spatrick }
215409467b48Spatrick 
LowerGlobalAddress(SDValue Op,SelectionDAG & DAG) const215509467b48Spatrick SDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op,
215609467b48Spatrick                                                 SelectionDAG &DAG) const {
215709467b48Spatrick   return makeAddress(Op, DAG);
215809467b48Spatrick }
215909467b48Spatrick 
LowerConstantPool(SDValue Op,SelectionDAG & DAG) const216009467b48Spatrick SDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
216109467b48Spatrick                                                SelectionDAG &DAG) const {
216209467b48Spatrick   return makeAddress(Op, DAG);
216309467b48Spatrick }
216409467b48Spatrick 
LowerBlockAddress(SDValue Op,SelectionDAG & DAG) const216509467b48Spatrick SDValue SparcTargetLowering::LowerBlockAddress(SDValue Op,
216609467b48Spatrick                                                SelectionDAG &DAG) const {
216709467b48Spatrick   return makeAddress(Op, DAG);
216809467b48Spatrick }
216909467b48Spatrick 
LowerGlobalTLSAddress(SDValue Op,SelectionDAG & DAG) const217009467b48Spatrick SDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op,
217109467b48Spatrick                                                    SelectionDAG &DAG) const {
217209467b48Spatrick 
217309467b48Spatrick   GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
217409467b48Spatrick   if (DAG.getTarget().useEmulatedTLS())
217509467b48Spatrick     return LowerToTLSEmulatedModel(GA, DAG);
217609467b48Spatrick 
217709467b48Spatrick   SDLoc DL(GA);
217809467b48Spatrick   const GlobalValue *GV = GA->getGlobal();
217909467b48Spatrick   EVT PtrVT = getPointerTy(DAG.getDataLayout());
218009467b48Spatrick 
218109467b48Spatrick   TLSModel::Model model = getTargetMachine().getTLSModel(GV);
218209467b48Spatrick 
218309467b48Spatrick   if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {
218409467b48Spatrick     unsigned HiTF = ((model == TLSModel::GeneralDynamic)
218509467b48Spatrick                      ? SparcMCExpr::VK_Sparc_TLS_GD_HI22
218609467b48Spatrick                      : SparcMCExpr::VK_Sparc_TLS_LDM_HI22);
218709467b48Spatrick     unsigned LoTF = ((model == TLSModel::GeneralDynamic)
218809467b48Spatrick                      ? SparcMCExpr::VK_Sparc_TLS_GD_LO10
218909467b48Spatrick                      : SparcMCExpr::VK_Sparc_TLS_LDM_LO10);
219009467b48Spatrick     unsigned addTF = ((model == TLSModel::GeneralDynamic)
219109467b48Spatrick                       ? SparcMCExpr::VK_Sparc_TLS_GD_ADD
219209467b48Spatrick                       : SparcMCExpr::VK_Sparc_TLS_LDM_ADD);
219309467b48Spatrick     unsigned callTF = ((model == TLSModel::GeneralDynamic)
219409467b48Spatrick                        ? SparcMCExpr::VK_Sparc_TLS_GD_CALL
219509467b48Spatrick                        : SparcMCExpr::VK_Sparc_TLS_LDM_CALL);
219609467b48Spatrick 
219709467b48Spatrick     SDValue HiLo = makeHiLoPair(Op, HiTF, LoTF, DAG);
219809467b48Spatrick     SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT);
219909467b48Spatrick     SDValue Argument = DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Base, HiLo,
220009467b48Spatrick                                withTargetFlags(Op, addTF, DAG));
220109467b48Spatrick 
220209467b48Spatrick     SDValue Chain = DAG.getEntryNode();
220309467b48Spatrick     SDValue InFlag;
220409467b48Spatrick 
220509467b48Spatrick     Chain = DAG.getCALLSEQ_START(Chain, 1, 0, DL);
220609467b48Spatrick     Chain = DAG.getCopyToReg(Chain, DL, SP::O0, Argument, InFlag);
220709467b48Spatrick     InFlag = Chain.getValue(1);
220809467b48Spatrick     SDValue Callee = DAG.getTargetExternalSymbol("__tls_get_addr", PtrVT);
220909467b48Spatrick     SDValue Symbol = withTargetFlags(Op, callTF, DAG);
221009467b48Spatrick 
221109467b48Spatrick     SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
221209467b48Spatrick     const uint32_t *Mask = Subtarget->getRegisterInfo()->getCallPreservedMask(
221309467b48Spatrick         DAG.getMachineFunction(), CallingConv::C);
221409467b48Spatrick     assert(Mask && "Missing call preserved mask for calling convention");
221509467b48Spatrick     SDValue Ops[] = {Chain,
221609467b48Spatrick                      Callee,
221709467b48Spatrick                      Symbol,
221809467b48Spatrick                      DAG.getRegister(SP::O0, PtrVT),
221909467b48Spatrick                      DAG.getRegisterMask(Mask),
222009467b48Spatrick                      InFlag};
222109467b48Spatrick     Chain = DAG.getNode(SPISD::TLS_CALL, DL, NodeTys, Ops);
222209467b48Spatrick     InFlag = Chain.getValue(1);
2223*a96b3639Srobert     Chain = DAG.getCALLSEQ_END(Chain, 1, 0, InFlag, DL);
222409467b48Spatrick     InFlag = Chain.getValue(1);
222509467b48Spatrick     SDValue Ret = DAG.getCopyFromReg(Chain, DL, SP::O0, PtrVT, InFlag);
222609467b48Spatrick 
222709467b48Spatrick     if (model != TLSModel::LocalDynamic)
222809467b48Spatrick       return Ret;
222909467b48Spatrick 
223009467b48Spatrick     SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT,
223109467b48Spatrick                  withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_HIX22, DAG));
223209467b48Spatrick     SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT,
223309467b48Spatrick                  withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_LOX10, DAG));
223409467b48Spatrick     HiLo =  DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo);
223509467b48Spatrick     return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Ret, HiLo,
223609467b48Spatrick                    withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_ADD, DAG));
223709467b48Spatrick   }
223809467b48Spatrick 
223909467b48Spatrick   if (model == TLSModel::InitialExec) {
224009467b48Spatrick     unsigned ldTF     = ((PtrVT == MVT::i64)? SparcMCExpr::VK_Sparc_TLS_IE_LDX
224109467b48Spatrick                          : SparcMCExpr::VK_Sparc_TLS_IE_LD);
224209467b48Spatrick 
224309467b48Spatrick     SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT);
224409467b48Spatrick 
224509467b48Spatrick     // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
224609467b48Spatrick     // function has calls.
224709467b48Spatrick     MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
224809467b48Spatrick     MFI.setHasCalls(true);
224909467b48Spatrick 
225009467b48Spatrick     SDValue TGA = makeHiLoPair(Op,
225109467b48Spatrick                                SparcMCExpr::VK_Sparc_TLS_IE_HI22,
225209467b48Spatrick                                SparcMCExpr::VK_Sparc_TLS_IE_LO10, DAG);
225309467b48Spatrick     SDValue Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Base, TGA);
225409467b48Spatrick     SDValue Offset = DAG.getNode(SPISD::TLS_LD,
225509467b48Spatrick                                  DL, PtrVT, Ptr,
225609467b48Spatrick                                  withTargetFlags(Op, ldTF, DAG));
225709467b48Spatrick     return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT,
225809467b48Spatrick                        DAG.getRegister(SP::G7, PtrVT), Offset,
225909467b48Spatrick                        withTargetFlags(Op,
226009467b48Spatrick                                        SparcMCExpr::VK_Sparc_TLS_IE_ADD, DAG));
226109467b48Spatrick   }
226209467b48Spatrick 
226309467b48Spatrick   assert(model == TLSModel::LocalExec);
226409467b48Spatrick   SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT,
226509467b48Spatrick                   withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LE_HIX22, DAG));
226609467b48Spatrick   SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT,
226709467b48Spatrick                   withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LE_LOX10, DAG));
226809467b48Spatrick   SDValue Offset =  DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo);
226909467b48Spatrick 
227009467b48Spatrick   return DAG.getNode(ISD::ADD, DL, PtrVT,
227109467b48Spatrick                      DAG.getRegister(SP::G7, PtrVT), Offset);
227209467b48Spatrick }
227309467b48Spatrick 
LowerF128_LibCallArg(SDValue Chain,ArgListTy & Args,SDValue Arg,const SDLoc & DL,SelectionDAG & DAG) const227409467b48Spatrick SDValue SparcTargetLowering::LowerF128_LibCallArg(SDValue Chain,
227509467b48Spatrick                                                   ArgListTy &Args, SDValue Arg,
227609467b48Spatrick                                                   const SDLoc &DL,
227709467b48Spatrick                                                   SelectionDAG &DAG) const {
227809467b48Spatrick   MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
227909467b48Spatrick   EVT ArgVT = Arg.getValueType();
228009467b48Spatrick   Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
228109467b48Spatrick 
228209467b48Spatrick   ArgListEntry Entry;
228309467b48Spatrick   Entry.Node = Arg;
228409467b48Spatrick   Entry.Ty   = ArgTy;
228509467b48Spatrick 
228609467b48Spatrick   if (ArgTy->isFP128Ty()) {
228709467b48Spatrick     // Create a stack object and pass the pointer to the library function.
2288097a140dSpatrick     int FI = MFI.CreateStackObject(16, Align(8), false);
228909467b48Spatrick     SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
229009467b48Spatrick     Chain = DAG.getStore(Chain, DL, Entry.Node, FIPtr, MachinePointerInfo(),
2291a0747c9fSpatrick                          Align(8));
229209467b48Spatrick 
229309467b48Spatrick     Entry.Node = FIPtr;
229409467b48Spatrick     Entry.Ty   = PointerType::getUnqual(ArgTy);
229509467b48Spatrick   }
229609467b48Spatrick   Args.push_back(Entry);
229709467b48Spatrick   return Chain;
229809467b48Spatrick }
229909467b48Spatrick 
230009467b48Spatrick SDValue
LowerF128Op(SDValue Op,SelectionDAG & DAG,const char * LibFuncName,unsigned numArgs) const230109467b48Spatrick SparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG,
230209467b48Spatrick                                  const char *LibFuncName,
230309467b48Spatrick                                  unsigned numArgs) const {
230409467b48Spatrick 
230509467b48Spatrick   ArgListTy Args;
230609467b48Spatrick 
230709467b48Spatrick   MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
230809467b48Spatrick   auto PtrVT = getPointerTy(DAG.getDataLayout());
230909467b48Spatrick 
231009467b48Spatrick   SDValue Callee = DAG.getExternalSymbol(LibFuncName, PtrVT);
231109467b48Spatrick   Type *RetTy = Op.getValueType().getTypeForEVT(*DAG.getContext());
231209467b48Spatrick   Type *RetTyABI = RetTy;
231309467b48Spatrick   SDValue Chain = DAG.getEntryNode();
231409467b48Spatrick   SDValue RetPtr;
231509467b48Spatrick 
231609467b48Spatrick   if (RetTy->isFP128Ty()) {
231709467b48Spatrick     // Create a Stack Object to receive the return value of type f128.
231809467b48Spatrick     ArgListEntry Entry;
2319097a140dSpatrick     int RetFI = MFI.CreateStackObject(16, Align(8), false);
232009467b48Spatrick     RetPtr = DAG.getFrameIndex(RetFI, PtrVT);
232109467b48Spatrick     Entry.Node = RetPtr;
232209467b48Spatrick     Entry.Ty   = PointerType::getUnqual(RetTy);
2323*a96b3639Srobert     if (!Subtarget->is64Bit()) {
232409467b48Spatrick       Entry.IsSRet = true;
2325*a96b3639Srobert       Entry.IndirectType = RetTy;
2326*a96b3639Srobert     }
232709467b48Spatrick     Entry.IsReturned = false;
232809467b48Spatrick     Args.push_back(Entry);
232909467b48Spatrick     RetTyABI = Type::getVoidTy(*DAG.getContext());
233009467b48Spatrick   }
233109467b48Spatrick 
233209467b48Spatrick   assert(Op->getNumOperands() >= numArgs && "Not enough operands!");
233309467b48Spatrick   for (unsigned i = 0, e = numArgs; i != e; ++i) {
233409467b48Spatrick     Chain = LowerF128_LibCallArg(Chain, Args, Op.getOperand(i), SDLoc(Op), DAG);
233509467b48Spatrick   }
233609467b48Spatrick   TargetLowering::CallLoweringInfo CLI(DAG);
233709467b48Spatrick   CLI.setDebugLoc(SDLoc(Op)).setChain(Chain)
233809467b48Spatrick     .setCallee(CallingConv::C, RetTyABI, Callee, std::move(Args));
233909467b48Spatrick 
234009467b48Spatrick   std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
234109467b48Spatrick 
234209467b48Spatrick   // chain is in second result.
234309467b48Spatrick   if (RetTyABI == RetTy)
234409467b48Spatrick     return CallInfo.first;
234509467b48Spatrick 
234609467b48Spatrick   assert (RetTy->isFP128Ty() && "Unexpected return type!");
234709467b48Spatrick 
234809467b48Spatrick   Chain = CallInfo.second;
234909467b48Spatrick 
235009467b48Spatrick   // Load RetPtr to get the return value.
235109467b48Spatrick   return DAG.getLoad(Op.getValueType(), SDLoc(Op), Chain, RetPtr,
2352a0747c9fSpatrick                      MachinePointerInfo(), Align(8));
235309467b48Spatrick }
235409467b48Spatrick 
LowerF128Compare(SDValue LHS,SDValue RHS,unsigned & SPCC,const SDLoc & DL,SelectionDAG & DAG) const235509467b48Spatrick SDValue SparcTargetLowering::LowerF128Compare(SDValue LHS, SDValue RHS,
235609467b48Spatrick                                               unsigned &SPCC, const SDLoc &DL,
235709467b48Spatrick                                               SelectionDAG &DAG) const {
235809467b48Spatrick 
235909467b48Spatrick   const char *LibCall = nullptr;
236009467b48Spatrick   bool is64Bit = Subtarget->is64Bit();
236109467b48Spatrick   switch(SPCC) {
236209467b48Spatrick   default: llvm_unreachable("Unhandled conditional code!");
236309467b48Spatrick   case SPCC::FCC_E  : LibCall = is64Bit? "_Qp_feq" : "_Q_feq"; break;
236409467b48Spatrick   case SPCC::FCC_NE : LibCall = is64Bit? "_Qp_fne" : "_Q_fne"; break;
236509467b48Spatrick   case SPCC::FCC_L  : LibCall = is64Bit? "_Qp_flt" : "_Q_flt"; break;
236609467b48Spatrick   case SPCC::FCC_G  : LibCall = is64Bit? "_Qp_fgt" : "_Q_fgt"; break;
236709467b48Spatrick   case SPCC::FCC_LE : LibCall = is64Bit? "_Qp_fle" : "_Q_fle"; break;
236809467b48Spatrick   case SPCC::FCC_GE : LibCall = is64Bit? "_Qp_fge" : "_Q_fge"; break;
236909467b48Spatrick   case SPCC::FCC_UL :
237009467b48Spatrick   case SPCC::FCC_ULE:
237109467b48Spatrick   case SPCC::FCC_UG :
237209467b48Spatrick   case SPCC::FCC_UGE:
237309467b48Spatrick   case SPCC::FCC_U  :
237409467b48Spatrick   case SPCC::FCC_O  :
237509467b48Spatrick   case SPCC::FCC_LG :
237609467b48Spatrick   case SPCC::FCC_UE : LibCall = is64Bit? "_Qp_cmp" : "_Q_cmp"; break;
237709467b48Spatrick   }
237809467b48Spatrick 
237909467b48Spatrick   auto PtrVT = getPointerTy(DAG.getDataLayout());
238009467b48Spatrick   SDValue Callee = DAG.getExternalSymbol(LibCall, PtrVT);
238109467b48Spatrick   Type *RetTy = Type::getInt32Ty(*DAG.getContext());
238209467b48Spatrick   ArgListTy Args;
238309467b48Spatrick   SDValue Chain = DAG.getEntryNode();
238409467b48Spatrick   Chain = LowerF128_LibCallArg(Chain, Args, LHS, DL, DAG);
238509467b48Spatrick   Chain = LowerF128_LibCallArg(Chain, Args, RHS, DL, DAG);
238609467b48Spatrick 
238709467b48Spatrick   TargetLowering::CallLoweringInfo CLI(DAG);
238809467b48Spatrick   CLI.setDebugLoc(DL).setChain(Chain)
238909467b48Spatrick     .setCallee(CallingConv::C, RetTy, Callee, std::move(Args));
239009467b48Spatrick 
239109467b48Spatrick   std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
239209467b48Spatrick 
239309467b48Spatrick   // result is in first, and chain is in second result.
239409467b48Spatrick   SDValue Result =  CallInfo.first;
239509467b48Spatrick 
239609467b48Spatrick   switch(SPCC) {
239709467b48Spatrick   default: {
2398097a140dSpatrick     SDValue RHS = DAG.getConstant(0, DL, Result.getValueType());
239909467b48Spatrick     SPCC = SPCC::ICC_NE;
240009467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
240109467b48Spatrick   }
240209467b48Spatrick   case SPCC::FCC_UL : {
240309467b48Spatrick     SDValue Mask   = DAG.getConstant(1, DL, Result.getValueType());
240409467b48Spatrick     Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask);
2405097a140dSpatrick     SDValue RHS    = DAG.getConstant(0, DL, Result.getValueType());
240609467b48Spatrick     SPCC = SPCC::ICC_NE;
240709467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
240809467b48Spatrick   }
240909467b48Spatrick   case SPCC::FCC_ULE: {
2410097a140dSpatrick     SDValue RHS = DAG.getConstant(2, DL, Result.getValueType());
241109467b48Spatrick     SPCC = SPCC::ICC_NE;
241209467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
241309467b48Spatrick   }
241409467b48Spatrick   case SPCC::FCC_UG :  {
2415097a140dSpatrick     SDValue RHS = DAG.getConstant(1, DL, Result.getValueType());
241609467b48Spatrick     SPCC = SPCC::ICC_G;
241709467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
241809467b48Spatrick   }
241909467b48Spatrick   case SPCC::FCC_UGE: {
2420097a140dSpatrick     SDValue RHS = DAG.getConstant(1, DL, Result.getValueType());
242109467b48Spatrick     SPCC = SPCC::ICC_NE;
242209467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
242309467b48Spatrick   }
242409467b48Spatrick 
242509467b48Spatrick   case SPCC::FCC_U  :  {
2426097a140dSpatrick     SDValue RHS = DAG.getConstant(3, DL, Result.getValueType());
242709467b48Spatrick     SPCC = SPCC::ICC_E;
242809467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
242909467b48Spatrick   }
243009467b48Spatrick   case SPCC::FCC_O  :  {
2431097a140dSpatrick     SDValue RHS = DAG.getConstant(3, DL, Result.getValueType());
243209467b48Spatrick     SPCC = SPCC::ICC_NE;
243309467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
243409467b48Spatrick   }
243509467b48Spatrick   case SPCC::FCC_LG :  {
243609467b48Spatrick     SDValue Mask   = DAG.getConstant(3, DL, Result.getValueType());
243709467b48Spatrick     Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask);
2438097a140dSpatrick     SDValue RHS    = DAG.getConstant(0, DL, Result.getValueType());
243909467b48Spatrick     SPCC = SPCC::ICC_NE;
244009467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
244109467b48Spatrick   }
244209467b48Spatrick   case SPCC::FCC_UE : {
244309467b48Spatrick     SDValue Mask   = DAG.getConstant(3, DL, Result.getValueType());
244409467b48Spatrick     Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask);
2445097a140dSpatrick     SDValue RHS    = DAG.getConstant(0, DL, Result.getValueType());
244609467b48Spatrick     SPCC = SPCC::ICC_E;
244709467b48Spatrick     return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
244809467b48Spatrick   }
244909467b48Spatrick   }
245009467b48Spatrick }
245109467b48Spatrick 
245209467b48Spatrick static SDValue
LowerF128_FPEXTEND(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI)245309467b48Spatrick LowerF128_FPEXTEND(SDValue Op, SelectionDAG &DAG,
245409467b48Spatrick                    const SparcTargetLowering &TLI) {
245509467b48Spatrick 
245609467b48Spatrick   if (Op.getOperand(0).getValueType() == MVT::f64)
245709467b48Spatrick     return TLI.LowerF128Op(Op, DAG,
245809467b48Spatrick                            TLI.getLibcallName(RTLIB::FPEXT_F64_F128), 1);
245909467b48Spatrick 
246009467b48Spatrick   if (Op.getOperand(0).getValueType() == MVT::f32)
246109467b48Spatrick     return TLI.LowerF128Op(Op, DAG,
246209467b48Spatrick                            TLI.getLibcallName(RTLIB::FPEXT_F32_F128), 1);
246309467b48Spatrick 
246409467b48Spatrick   llvm_unreachable("fpextend with non-float operand!");
246509467b48Spatrick   return SDValue();
246609467b48Spatrick }
246709467b48Spatrick 
246809467b48Spatrick static SDValue
LowerF128_FPROUND(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI)246909467b48Spatrick LowerF128_FPROUND(SDValue Op, SelectionDAG &DAG,
247009467b48Spatrick                   const SparcTargetLowering &TLI) {
247109467b48Spatrick   // FP_ROUND on f64 and f32 are legal.
247209467b48Spatrick   if (Op.getOperand(0).getValueType() != MVT::f128)
247309467b48Spatrick     return Op;
247409467b48Spatrick 
247509467b48Spatrick   if (Op.getValueType() == MVT::f64)
247609467b48Spatrick     return TLI.LowerF128Op(Op, DAG,
247709467b48Spatrick                            TLI.getLibcallName(RTLIB::FPROUND_F128_F64), 1);
247809467b48Spatrick   if (Op.getValueType() == MVT::f32)
247909467b48Spatrick     return TLI.LowerF128Op(Op, DAG,
248009467b48Spatrick                            TLI.getLibcallName(RTLIB::FPROUND_F128_F32), 1);
248109467b48Spatrick 
248209467b48Spatrick   llvm_unreachable("fpround to non-float!");
248309467b48Spatrick   return SDValue();
248409467b48Spatrick }
248509467b48Spatrick 
LowerFP_TO_SINT(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,bool hasHardQuad)248609467b48Spatrick static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG,
248709467b48Spatrick                                const SparcTargetLowering &TLI,
248809467b48Spatrick                                bool hasHardQuad) {
248909467b48Spatrick   SDLoc dl(Op);
249009467b48Spatrick   EVT VT = Op.getValueType();
249109467b48Spatrick   assert(VT == MVT::i32 || VT == MVT::i64);
249209467b48Spatrick 
249309467b48Spatrick   // Expand f128 operations to fp128 abi calls.
249409467b48Spatrick   if (Op.getOperand(0).getValueType() == MVT::f128
249509467b48Spatrick       && (!hasHardQuad || !TLI.isTypeLegal(VT))) {
249609467b48Spatrick     const char *libName = TLI.getLibcallName(VT == MVT::i32
249709467b48Spatrick                                              ? RTLIB::FPTOSINT_F128_I32
249809467b48Spatrick                                              : RTLIB::FPTOSINT_F128_I64);
249909467b48Spatrick     return TLI.LowerF128Op(Op, DAG, libName, 1);
250009467b48Spatrick   }
250109467b48Spatrick 
250209467b48Spatrick   // Expand if the resulting type is illegal.
250309467b48Spatrick   if (!TLI.isTypeLegal(VT))
250409467b48Spatrick     return SDValue();
250509467b48Spatrick 
250609467b48Spatrick   // Otherwise, Convert the fp value to integer in an FP register.
250709467b48Spatrick   if (VT == MVT::i32)
250809467b48Spatrick     Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
250909467b48Spatrick   else
251009467b48Spatrick     Op = DAG.getNode(SPISD::FTOX, dl, MVT::f64, Op.getOperand(0));
251109467b48Spatrick 
251209467b48Spatrick   return DAG.getNode(ISD::BITCAST, dl, VT, Op);
251309467b48Spatrick }
251409467b48Spatrick 
LowerSINT_TO_FP(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,bool hasHardQuad)251509467b48Spatrick static SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG,
251609467b48Spatrick                                const SparcTargetLowering &TLI,
251709467b48Spatrick                                bool hasHardQuad) {
251809467b48Spatrick   SDLoc dl(Op);
251909467b48Spatrick   EVT OpVT = Op.getOperand(0).getValueType();
252009467b48Spatrick   assert(OpVT == MVT::i32 || (OpVT == MVT::i64));
252109467b48Spatrick 
252209467b48Spatrick   EVT floatVT = (OpVT == MVT::i32) ? MVT::f32 : MVT::f64;
252309467b48Spatrick 
252409467b48Spatrick   // Expand f128 operations to fp128 ABI calls.
252509467b48Spatrick   if (Op.getValueType() == MVT::f128
252609467b48Spatrick       && (!hasHardQuad || !TLI.isTypeLegal(OpVT))) {
252709467b48Spatrick     const char *libName = TLI.getLibcallName(OpVT == MVT::i32
252809467b48Spatrick                                              ? RTLIB::SINTTOFP_I32_F128
252909467b48Spatrick                                              : RTLIB::SINTTOFP_I64_F128);
253009467b48Spatrick     return TLI.LowerF128Op(Op, DAG, libName, 1);
253109467b48Spatrick   }
253209467b48Spatrick 
253309467b48Spatrick   // Expand if the operand type is illegal.
253409467b48Spatrick   if (!TLI.isTypeLegal(OpVT))
253509467b48Spatrick     return SDValue();
253609467b48Spatrick 
253709467b48Spatrick   // Otherwise, Convert the int value to FP in an FP register.
253809467b48Spatrick   SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, floatVT, Op.getOperand(0));
253909467b48Spatrick   unsigned opcode = (OpVT == MVT::i32)? SPISD::ITOF : SPISD::XTOF;
254009467b48Spatrick   return DAG.getNode(opcode, dl, Op.getValueType(), Tmp);
254109467b48Spatrick }
254209467b48Spatrick 
LowerFP_TO_UINT(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,bool hasHardQuad)254309467b48Spatrick static SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG,
254409467b48Spatrick                                const SparcTargetLowering &TLI,
254509467b48Spatrick                                bool hasHardQuad) {
254609467b48Spatrick   SDLoc dl(Op);
254709467b48Spatrick   EVT VT = Op.getValueType();
254809467b48Spatrick 
254909467b48Spatrick   // Expand if it does not involve f128 or the target has support for
255009467b48Spatrick   // quad floating point instructions and the resulting type is legal.
255109467b48Spatrick   if (Op.getOperand(0).getValueType() != MVT::f128 ||
255209467b48Spatrick       (hasHardQuad && TLI.isTypeLegal(VT)))
255309467b48Spatrick     return SDValue();
255409467b48Spatrick 
255509467b48Spatrick   assert(VT == MVT::i32 || VT == MVT::i64);
255609467b48Spatrick 
255709467b48Spatrick   return TLI.LowerF128Op(Op, DAG,
255809467b48Spatrick                          TLI.getLibcallName(VT == MVT::i32
255909467b48Spatrick                                             ? RTLIB::FPTOUINT_F128_I32
256009467b48Spatrick                                             : RTLIB::FPTOUINT_F128_I64),
256109467b48Spatrick                          1);
256209467b48Spatrick }
256309467b48Spatrick 
LowerUINT_TO_FP(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,bool hasHardQuad)256409467b48Spatrick static SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG,
256509467b48Spatrick                                const SparcTargetLowering &TLI,
256609467b48Spatrick                                bool hasHardQuad) {
256709467b48Spatrick   SDLoc dl(Op);
256809467b48Spatrick   EVT OpVT = Op.getOperand(0).getValueType();
256909467b48Spatrick   assert(OpVT == MVT::i32 || OpVT == MVT::i64);
257009467b48Spatrick 
257109467b48Spatrick   // Expand if it does not involve f128 or the target has support for
257209467b48Spatrick   // quad floating point instructions and the operand type is legal.
257309467b48Spatrick   if (Op.getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(OpVT)))
257409467b48Spatrick     return SDValue();
257509467b48Spatrick 
257609467b48Spatrick   return TLI.LowerF128Op(Op, DAG,
257709467b48Spatrick                          TLI.getLibcallName(OpVT == MVT::i32
257809467b48Spatrick                                             ? RTLIB::UINTTOFP_I32_F128
257909467b48Spatrick                                             : RTLIB::UINTTOFP_I64_F128),
258009467b48Spatrick                          1);
258109467b48Spatrick }
258209467b48Spatrick 
LowerBR_CC(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,bool hasHardQuad,bool isV9)258309467b48Spatrick static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG,
2584*a96b3639Srobert                           const SparcTargetLowering &TLI, bool hasHardQuad,
2585*a96b3639Srobert                           bool isV9) {
258609467b48Spatrick   SDValue Chain = Op.getOperand(0);
258709467b48Spatrick   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
258809467b48Spatrick   SDValue LHS = Op.getOperand(2);
258909467b48Spatrick   SDValue RHS = Op.getOperand(3);
259009467b48Spatrick   SDValue Dest = Op.getOperand(4);
259109467b48Spatrick   SDLoc dl(Op);
259209467b48Spatrick   unsigned Opc, SPCC = ~0U;
259309467b48Spatrick 
259409467b48Spatrick   // If this is a br_cc of a "setcc", and if the setcc got lowered into
259509467b48Spatrick   // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
259609467b48Spatrick   LookThroughSetCC(LHS, RHS, CC, SPCC);
2597*a96b3639Srobert   assert(LHS.getValueType() == RHS.getValueType());
259809467b48Spatrick 
259909467b48Spatrick   // Get the condition flag.
260009467b48Spatrick   SDValue CompareFlag;
260109467b48Spatrick   if (LHS.getValueType().isInteger()) {
260209467b48Spatrick     CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS);
260309467b48Spatrick     if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
2604*a96b3639Srobert     if (isV9)
260509467b48Spatrick       // 32-bit compares use the icc flags, 64-bit uses the xcc flags.
2606*a96b3639Srobert       Opc = LHS.getValueType() == MVT::i32 ? SPISD::BPICC : SPISD::BPXCC;
2607*a96b3639Srobert     else
2608*a96b3639Srobert       // Non-v9 targets don't have xcc.
2609*a96b3639Srobert       Opc = SPISD::BRICC;
261009467b48Spatrick   } else {
261109467b48Spatrick     if (!hasHardQuad && LHS.getValueType() == MVT::f128) {
261209467b48Spatrick       if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
261309467b48Spatrick       CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG);
2614*a96b3639Srobert       Opc = isV9 ? SPISD::BPICC : SPISD::BRICC;
261509467b48Spatrick     } else {
2616*a96b3639Srobert       unsigned CmpOpc = isV9 ? SPISD::CMPFCC_V9 : SPISD::CMPFCC;
2617*a96b3639Srobert       CompareFlag = DAG.getNode(CmpOpc, dl, MVT::Glue, LHS, RHS);
261809467b48Spatrick       if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
2619*a96b3639Srobert       Opc = isV9 ? SPISD::BRFCC_V9 : SPISD::BRFCC;
262009467b48Spatrick     }
262109467b48Spatrick   }
262209467b48Spatrick   return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest,
262309467b48Spatrick                      DAG.getConstant(SPCC, dl, MVT::i32), CompareFlag);
262409467b48Spatrick }
262509467b48Spatrick 
LowerSELECT_CC(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,bool hasHardQuad,bool isV9,bool is64Bit)262609467b48Spatrick static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2627*a96b3639Srobert                               const SparcTargetLowering &TLI, bool hasHardQuad,
2628*a96b3639Srobert                               bool isV9, bool is64Bit) {
262909467b48Spatrick   SDValue LHS = Op.getOperand(0);
263009467b48Spatrick   SDValue RHS = Op.getOperand(1);
263109467b48Spatrick   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
263209467b48Spatrick   SDValue TrueVal = Op.getOperand(2);
263309467b48Spatrick   SDValue FalseVal = Op.getOperand(3);
263409467b48Spatrick   SDLoc dl(Op);
263509467b48Spatrick   unsigned Opc, SPCC = ~0U;
263609467b48Spatrick 
263709467b48Spatrick   // If this is a select_cc of a "setcc", and if the setcc got lowered into
263809467b48Spatrick   // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
263909467b48Spatrick   LookThroughSetCC(LHS, RHS, CC, SPCC);
2640*a96b3639Srobert   assert(LHS.getValueType() == RHS.getValueType());
264109467b48Spatrick 
264209467b48Spatrick   SDValue CompareFlag;
264309467b48Spatrick   if (LHS.getValueType().isInteger()) {
2644*a96b3639Srobert     // On V9 processors running in 64-bit mode, if CC compares two `i64`s
2645*a96b3639Srobert     // and the RHS is zero we might be able to use a specialized select.
2646*a96b3639Srobert     // All SELECT_CC between any two scalar integer types are eligible for
2647*a96b3639Srobert     // lowering to specialized instructions. Additionally, f32 and f64 types
2648*a96b3639Srobert     // are also eligible, but for f128 we can only use the specialized
2649*a96b3639Srobert     // instruction when we have hardquad.
2650*a96b3639Srobert     EVT ValType = TrueVal.getValueType();
2651*a96b3639Srobert     bool IsEligibleType = ValType.isScalarInteger() || ValType == MVT::f32 ||
2652*a96b3639Srobert                           ValType == MVT::f64 ||
2653*a96b3639Srobert                           (ValType == MVT::f128 && hasHardQuad);
2654*a96b3639Srobert     if (is64Bit && isV9 && LHS.getValueType() == MVT::i64 &&
2655*a96b3639Srobert         isNullConstant(RHS) && !ISD::isUnsignedIntSetCC(CC) && IsEligibleType)
2656*a96b3639Srobert       return DAG.getNode(
2657*a96b3639Srobert           SPISD::SELECT_REG, dl, TrueVal.getValueType(), TrueVal, FalseVal,
2658*a96b3639Srobert           DAG.getConstant(intCondCCodeToRcond(CC), dl, MVT::i32), LHS);
2659*a96b3639Srobert 
266009467b48Spatrick     CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS);
266109467b48Spatrick     Opc = LHS.getValueType() == MVT::i32 ?
266209467b48Spatrick           SPISD::SELECT_ICC : SPISD::SELECT_XCC;
266309467b48Spatrick     if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
266409467b48Spatrick   } else {
266509467b48Spatrick     if (!hasHardQuad && LHS.getValueType() == MVT::f128) {
266609467b48Spatrick       if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
266709467b48Spatrick       CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG);
266809467b48Spatrick       Opc = SPISD::SELECT_ICC;
266909467b48Spatrick     } else {
2670*a96b3639Srobert       unsigned CmpOpc = isV9 ? SPISD::CMPFCC_V9 : SPISD::CMPFCC;
2671*a96b3639Srobert       CompareFlag = DAG.getNode(CmpOpc, dl, MVT::Glue, LHS, RHS);
267209467b48Spatrick       Opc = SPISD::SELECT_FCC;
267309467b48Spatrick       if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
267409467b48Spatrick     }
267509467b48Spatrick   }
267609467b48Spatrick   return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
267709467b48Spatrick                      DAG.getConstant(SPCC, dl, MVT::i32), CompareFlag);
267809467b48Spatrick }
267909467b48Spatrick 
LowerVASTART(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI)268009467b48Spatrick static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
268109467b48Spatrick                             const SparcTargetLowering &TLI) {
268209467b48Spatrick   MachineFunction &MF = DAG.getMachineFunction();
268309467b48Spatrick   SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
268409467b48Spatrick   auto PtrVT = TLI.getPointerTy(DAG.getDataLayout());
268509467b48Spatrick 
268609467b48Spatrick   // Need frame address to find the address of VarArgsFrameIndex.
268709467b48Spatrick   MF.getFrameInfo().setFrameAddressIsTaken(true);
268809467b48Spatrick 
268909467b48Spatrick   // vastart just stores the address of the VarArgsFrameIndex slot into the
269009467b48Spatrick   // memory location argument.
269109467b48Spatrick   SDLoc DL(Op);
269209467b48Spatrick   SDValue Offset =
269309467b48Spatrick       DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(SP::I6, PtrVT),
269409467b48Spatrick                   DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL));
269509467b48Spatrick   const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
269609467b48Spatrick   return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1),
269709467b48Spatrick                       MachinePointerInfo(SV));
269809467b48Spatrick }
269909467b48Spatrick 
LowerVAARG(SDValue Op,SelectionDAG & DAG)270009467b48Spatrick static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
270109467b48Spatrick   SDNode *Node = Op.getNode();
270209467b48Spatrick   EVT VT = Node->getValueType(0);
270309467b48Spatrick   SDValue InChain = Node->getOperand(0);
270409467b48Spatrick   SDValue VAListPtr = Node->getOperand(1);
270509467b48Spatrick   EVT PtrVT = VAListPtr.getValueType();
270609467b48Spatrick   const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
270709467b48Spatrick   SDLoc DL(Node);
270809467b48Spatrick   SDValue VAList =
270909467b48Spatrick       DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV));
271009467b48Spatrick   // Increment the pointer, VAList, to the next vaarg.
271109467b48Spatrick   SDValue NextPtr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
271209467b48Spatrick                                 DAG.getIntPtrConstant(VT.getSizeInBits()/8,
271309467b48Spatrick                                                       DL));
271409467b48Spatrick   // Store the incremented VAList to the legalized pointer.
271509467b48Spatrick   InChain = DAG.getStore(VAList.getValue(1), DL, NextPtr, VAListPtr,
271609467b48Spatrick                          MachinePointerInfo(SV));
271709467b48Spatrick   // Load the actual argument out of the pointer VAList.
271809467b48Spatrick   // We can't count on greater alignment than the word size.
2719a0747c9fSpatrick   return DAG.getLoad(
2720a0747c9fSpatrick       VT, DL, InChain, VAList, MachinePointerInfo(),
2721*a96b3639Srobert       Align(std::min(PtrVT.getFixedSizeInBits(), VT.getFixedSizeInBits()) / 8));
272209467b48Spatrick }
272309467b48Spatrick 
LowerDYNAMIC_STACKALLOC(SDValue Op,SelectionDAG & DAG,const SparcSubtarget * Subtarget)272409467b48Spatrick static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG,
272509467b48Spatrick                                        const SparcSubtarget *Subtarget) {
272609467b48Spatrick   SDValue Chain = Op.getOperand(0);  // Legalize the chain.
272709467b48Spatrick   SDValue Size  = Op.getOperand(1);  // Legalize the size.
2728097a140dSpatrick   MaybeAlign Alignment =
2729097a140dSpatrick       cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
2730097a140dSpatrick   Align StackAlign = Subtarget->getFrameLowering()->getStackAlign();
273109467b48Spatrick   EVT VT = Size->getValueType(0);
273209467b48Spatrick   SDLoc dl(Op);
273309467b48Spatrick 
273409467b48Spatrick   // TODO: implement over-aligned alloca. (Note: also implies
273509467b48Spatrick   // supporting support for overaligned function frames + dynamic
273609467b48Spatrick   // allocations, at all, which currently isn't supported)
2737097a140dSpatrick   if (Alignment && *Alignment > StackAlign) {
273809467b48Spatrick     const MachineFunction &MF = DAG.getMachineFunction();
273909467b48Spatrick     report_fatal_error("Function \"" + Twine(MF.getName()) + "\": "
274009467b48Spatrick                        "over-aligned dynamic alloca not supported.");
274109467b48Spatrick   }
274209467b48Spatrick 
274309467b48Spatrick   // The resultant pointer needs to be above the register spill area
274409467b48Spatrick   // at the bottom of the stack.
274509467b48Spatrick   unsigned regSpillArea;
274609467b48Spatrick   if (Subtarget->is64Bit()) {
274709467b48Spatrick     regSpillArea = 128;
274809467b48Spatrick   } else {
274909467b48Spatrick     // On Sparc32, the size of the spill area is 92. Unfortunately,
275009467b48Spatrick     // that's only 4-byte aligned, not 8-byte aligned (the stack
275109467b48Spatrick     // pointer is 8-byte aligned). So, if the user asked for an 8-byte
275209467b48Spatrick     // aligned dynamic allocation, we actually need to add 96 to the
275309467b48Spatrick     // bottom of the stack, instead of 92, to ensure 8-byte alignment.
275409467b48Spatrick 
275509467b48Spatrick     // That also means adding 4 to the size of the allocation --
275609467b48Spatrick     // before applying the 8-byte rounding. Unfortunately, we the
275709467b48Spatrick     // value we get here has already had rounding applied. So, we need
275809467b48Spatrick     // to add 8, instead, wasting a bit more memory.
275909467b48Spatrick 
276009467b48Spatrick     // Further, this only actually needs to be done if the required
276109467b48Spatrick     // alignment is > 4, but, we've lost that info by this point, too,
276209467b48Spatrick     // so we always apply it.
276309467b48Spatrick 
276409467b48Spatrick     // (An alternative approach would be to always reserve 96 bytes
276509467b48Spatrick     // instead of the required 92, but then we'd waste 4 extra bytes
276609467b48Spatrick     // in every frame, not just those with dynamic stack allocations)
276709467b48Spatrick 
276809467b48Spatrick     // TODO: modify code in SelectionDAGBuilder to make this less sad.
276909467b48Spatrick 
277009467b48Spatrick     Size = DAG.getNode(ISD::ADD, dl, VT, Size,
277109467b48Spatrick                        DAG.getConstant(8, dl, VT));
277209467b48Spatrick     regSpillArea = 96;
277309467b48Spatrick   }
277409467b48Spatrick 
277509467b48Spatrick   unsigned SPReg = SP::O6;
277609467b48Spatrick   SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
277709467b48Spatrick   SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value
277809467b48Spatrick   Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);    // Output chain
277909467b48Spatrick 
278009467b48Spatrick   regSpillArea += Subtarget->getStackPointerBias();
278109467b48Spatrick 
278209467b48Spatrick   SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP,
278309467b48Spatrick                                DAG.getConstant(regSpillArea, dl, VT));
278409467b48Spatrick   SDValue Ops[2] = { NewVal, Chain };
278509467b48Spatrick   return DAG.getMergeValues(Ops, dl);
278609467b48Spatrick }
278709467b48Spatrick 
278809467b48Spatrick 
getFLUSHW(SDValue Op,SelectionDAG & DAG)278909467b48Spatrick static SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) {
279009467b48Spatrick   SDLoc dl(Op);
279109467b48Spatrick   SDValue Chain = DAG.getNode(SPISD::FLUSHW,
279209467b48Spatrick                               dl, MVT::Other, DAG.getEntryNode());
279309467b48Spatrick   return Chain;
279409467b48Spatrick }
279509467b48Spatrick 
getFRAMEADDR(uint64_t depth,SDValue Op,SelectionDAG & DAG,const SparcSubtarget * Subtarget,bool AlwaysFlush=false)279609467b48Spatrick static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG,
279709467b48Spatrick                             const SparcSubtarget *Subtarget,
279809467b48Spatrick                             bool AlwaysFlush = false) {
279909467b48Spatrick   MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
280009467b48Spatrick   MFI.setFrameAddressIsTaken(true);
280109467b48Spatrick 
280209467b48Spatrick   EVT VT = Op.getValueType();
280309467b48Spatrick   SDLoc dl(Op);
280409467b48Spatrick   unsigned FrameReg = SP::I6;
280509467b48Spatrick   unsigned stackBias = Subtarget->getStackPointerBias();
280609467b48Spatrick 
280709467b48Spatrick   SDValue FrameAddr;
280809467b48Spatrick   SDValue Chain;
280909467b48Spatrick 
281009467b48Spatrick   // flush first to make sure the windowed registers' values are in stack
281109467b48Spatrick   Chain = (depth || AlwaysFlush) ? getFLUSHW(Op, DAG) : DAG.getEntryNode();
281209467b48Spatrick 
281309467b48Spatrick   FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
281409467b48Spatrick 
281509467b48Spatrick   unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
281609467b48Spatrick 
281709467b48Spatrick   while (depth--) {
281809467b48Spatrick     SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
281909467b48Spatrick                               DAG.getIntPtrConstant(Offset, dl));
282009467b48Spatrick     FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo());
282109467b48Spatrick   }
282209467b48Spatrick   if (Subtarget->is64Bit())
282309467b48Spatrick     FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
282409467b48Spatrick                             DAG.getIntPtrConstant(stackBias, dl));
282509467b48Spatrick   return FrameAddr;
282609467b48Spatrick }
282709467b48Spatrick 
282809467b48Spatrick 
LowerFRAMEADDR(SDValue Op,SelectionDAG & DAG,const SparcSubtarget * Subtarget)282909467b48Spatrick static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
283009467b48Spatrick                               const SparcSubtarget *Subtarget) {
283109467b48Spatrick 
283209467b48Spatrick   uint64_t depth = Op.getConstantOperandVal(0);
283309467b48Spatrick 
283409467b48Spatrick   return getFRAMEADDR(depth, Op, DAG, Subtarget);
283509467b48Spatrick 
283609467b48Spatrick }
283709467b48Spatrick 
LowerRETURNADDR(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI,const SparcSubtarget * Subtarget)283809467b48Spatrick static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG,
283909467b48Spatrick                                const SparcTargetLowering &TLI,
284009467b48Spatrick                                const SparcSubtarget *Subtarget) {
284109467b48Spatrick   MachineFunction &MF = DAG.getMachineFunction();
284209467b48Spatrick   MachineFrameInfo &MFI = MF.getFrameInfo();
284309467b48Spatrick   MFI.setReturnAddressIsTaken(true);
284409467b48Spatrick 
284509467b48Spatrick   if (TLI.verifyReturnAddressArgumentIsConstant(Op, DAG))
284609467b48Spatrick     return SDValue();
284709467b48Spatrick 
284809467b48Spatrick   EVT VT = Op.getValueType();
284909467b48Spatrick   SDLoc dl(Op);
285009467b48Spatrick   uint64_t depth = Op.getConstantOperandVal(0);
285109467b48Spatrick 
285209467b48Spatrick   SDValue RetAddr;
285309467b48Spatrick   if (depth == 0) {
285409467b48Spatrick     auto PtrVT = TLI.getPointerTy(DAG.getDataLayout());
2855*a96b3639Srobert     Register RetReg = MF.addLiveIn(SP::I7, TLI.getRegClassFor(PtrVT));
285609467b48Spatrick     RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
285709467b48Spatrick     return RetAddr;
285809467b48Spatrick   }
285909467b48Spatrick 
286009467b48Spatrick   // Need frame address to find return address of the caller.
286109467b48Spatrick   SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget, true);
286209467b48Spatrick 
286309467b48Spatrick   unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
286409467b48Spatrick   SDValue Ptr = DAG.getNode(ISD::ADD,
286509467b48Spatrick                             dl, VT,
286609467b48Spatrick                             FrameAddr,
286709467b48Spatrick                             DAG.getIntPtrConstant(Offset, dl));
286809467b48Spatrick   RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr, MachinePointerInfo());
286909467b48Spatrick 
287009467b48Spatrick   return RetAddr;
287109467b48Spatrick }
287209467b48Spatrick 
LowerF64Op(SDValue SrcReg64,const SDLoc & dl,SelectionDAG & DAG,unsigned opcode)287309467b48Spatrick static SDValue LowerF64Op(SDValue SrcReg64, const SDLoc &dl, SelectionDAG &DAG,
287409467b48Spatrick                           unsigned opcode) {
287509467b48Spatrick   assert(SrcReg64.getValueType() == MVT::f64 && "LowerF64Op called on non-double!");
287609467b48Spatrick   assert(opcode == ISD::FNEG || opcode == ISD::FABS);
287709467b48Spatrick 
287809467b48Spatrick   // Lower fneg/fabs on f64 to fneg/fabs on f32.
287909467b48Spatrick   // fneg f64 => fneg f32:sub_even, fmov f32:sub_odd.
288009467b48Spatrick   // fabs f64 => fabs f32:sub_even, fmov f32:sub_odd.
288109467b48Spatrick 
288209467b48Spatrick   // Note: in little-endian, the floating-point value is stored in the
288309467b48Spatrick   // registers are in the opposite order, so the subreg with the sign
288409467b48Spatrick   // bit is the highest-numbered (odd), rather than the
288509467b48Spatrick   // lowest-numbered (even).
288609467b48Spatrick 
288709467b48Spatrick   SDValue Hi32 = DAG.getTargetExtractSubreg(SP::sub_even, dl, MVT::f32,
288809467b48Spatrick                                             SrcReg64);
288909467b48Spatrick   SDValue Lo32 = DAG.getTargetExtractSubreg(SP::sub_odd, dl, MVT::f32,
289009467b48Spatrick                                             SrcReg64);
289109467b48Spatrick 
289209467b48Spatrick   if (DAG.getDataLayout().isLittleEndian())
289309467b48Spatrick     Lo32 = DAG.getNode(opcode, dl, MVT::f32, Lo32);
289409467b48Spatrick   else
289509467b48Spatrick     Hi32 = DAG.getNode(opcode, dl, MVT::f32, Hi32);
289609467b48Spatrick 
289709467b48Spatrick   SDValue DstReg64 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
289809467b48Spatrick                                                 dl, MVT::f64), 0);
289909467b48Spatrick   DstReg64 = DAG.getTargetInsertSubreg(SP::sub_even, dl, MVT::f64,
290009467b48Spatrick                                        DstReg64, Hi32);
290109467b48Spatrick   DstReg64 = DAG.getTargetInsertSubreg(SP::sub_odd, dl, MVT::f64,
290209467b48Spatrick                                        DstReg64, Lo32);
290309467b48Spatrick   return DstReg64;
290409467b48Spatrick }
290509467b48Spatrick 
290609467b48Spatrick // Lower a f128 load into two f64 loads.
LowerF128Load(SDValue Op,SelectionDAG & DAG)290709467b48Spatrick static SDValue LowerF128Load(SDValue Op, SelectionDAG &DAG)
290809467b48Spatrick {
290909467b48Spatrick   SDLoc dl(Op);
2910a0747c9fSpatrick   LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
2911a0747c9fSpatrick   assert(LdNode->getOffset().isUndef() && "Unexpected node type");
291209467b48Spatrick 
2913a0747c9fSpatrick   Align Alignment = commonAlignment(LdNode->getOriginalAlign(), 8);
291409467b48Spatrick 
291509467b48Spatrick   SDValue Hi64 =
291609467b48Spatrick       DAG.getLoad(MVT::f64, dl, LdNode->getChain(), LdNode->getBasePtr(),
2917a0747c9fSpatrick                   LdNode->getPointerInfo(), Alignment);
291809467b48Spatrick   EVT addrVT = LdNode->getBasePtr().getValueType();
291909467b48Spatrick   SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT,
292009467b48Spatrick                               LdNode->getBasePtr(),
292109467b48Spatrick                               DAG.getConstant(8, dl, addrVT));
292209467b48Spatrick   SDValue Lo64 = DAG.getLoad(MVT::f64, dl, LdNode->getChain(), LoPtr,
2923a0747c9fSpatrick                              LdNode->getPointerInfo().getWithOffset(8),
2924a0747c9fSpatrick                              Alignment);
292509467b48Spatrick 
292609467b48Spatrick   SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, dl, MVT::i32);
292709467b48Spatrick   SDValue SubRegOdd  = DAG.getTargetConstant(SP::sub_odd64, dl, MVT::i32);
292809467b48Spatrick 
292909467b48Spatrick   SDNode *InFP128 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
293009467b48Spatrick                                        dl, MVT::f128);
293109467b48Spatrick   InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
293209467b48Spatrick                                MVT::f128,
293309467b48Spatrick                                SDValue(InFP128, 0),
293409467b48Spatrick                                Hi64,
293509467b48Spatrick                                SubRegEven);
293609467b48Spatrick   InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
293709467b48Spatrick                                MVT::f128,
293809467b48Spatrick                                SDValue(InFP128, 0),
293909467b48Spatrick                                Lo64,
294009467b48Spatrick                                SubRegOdd);
294109467b48Spatrick   SDValue OutChains[2] = { SDValue(Hi64.getNode(), 1),
294209467b48Spatrick                            SDValue(Lo64.getNode(), 1) };
294309467b48Spatrick   SDValue OutChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
294409467b48Spatrick   SDValue Ops[2] = {SDValue(InFP128,0), OutChain};
294509467b48Spatrick   return DAG.getMergeValues(Ops, dl);
294609467b48Spatrick }
294709467b48Spatrick 
LowerLOAD(SDValue Op,SelectionDAG & DAG)294809467b48Spatrick static SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG)
294909467b48Spatrick {
295009467b48Spatrick   LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
295109467b48Spatrick 
295209467b48Spatrick   EVT MemVT = LdNode->getMemoryVT();
295309467b48Spatrick   if (MemVT == MVT::f128)
295409467b48Spatrick     return LowerF128Load(Op, DAG);
295509467b48Spatrick 
295609467b48Spatrick   return Op;
295709467b48Spatrick }
295809467b48Spatrick 
295909467b48Spatrick // Lower a f128 store into two f64 stores.
LowerF128Store(SDValue Op,SelectionDAG & DAG)296009467b48Spatrick static SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG) {
296109467b48Spatrick   SDLoc dl(Op);
2962a0747c9fSpatrick   StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode());
2963a0747c9fSpatrick   assert(StNode->getOffset().isUndef() && "Unexpected node type");
2964a0747c9fSpatrick 
296509467b48Spatrick   SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, dl, MVT::i32);
296609467b48Spatrick   SDValue SubRegOdd  = DAG.getTargetConstant(SP::sub_odd64, dl, MVT::i32);
296709467b48Spatrick 
296809467b48Spatrick   SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG,
296909467b48Spatrick                                     dl,
297009467b48Spatrick                                     MVT::f64,
297109467b48Spatrick                                     StNode->getValue(),
297209467b48Spatrick                                     SubRegEven);
297309467b48Spatrick   SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG,
297409467b48Spatrick                                     dl,
297509467b48Spatrick                                     MVT::f64,
297609467b48Spatrick                                     StNode->getValue(),
297709467b48Spatrick                                     SubRegOdd);
297809467b48Spatrick 
2979a0747c9fSpatrick   Align Alignment = commonAlignment(StNode->getOriginalAlign(), 8);
298009467b48Spatrick 
298109467b48Spatrick   SDValue OutChains[2];
298209467b48Spatrick   OutChains[0] =
298309467b48Spatrick       DAG.getStore(StNode->getChain(), dl, SDValue(Hi64, 0),
2984a0747c9fSpatrick                    StNode->getBasePtr(), StNode->getPointerInfo(),
2985a0747c9fSpatrick                    Alignment);
298609467b48Spatrick   EVT addrVT = StNode->getBasePtr().getValueType();
298709467b48Spatrick   SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT,
298809467b48Spatrick                               StNode->getBasePtr(),
298909467b48Spatrick                               DAG.getConstant(8, dl, addrVT));
299009467b48Spatrick   OutChains[1] = DAG.getStore(StNode->getChain(), dl, SDValue(Lo64, 0), LoPtr,
2991a0747c9fSpatrick                               StNode->getPointerInfo().getWithOffset(8),
2992a0747c9fSpatrick                               Alignment);
299309467b48Spatrick   return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
299409467b48Spatrick }
299509467b48Spatrick 
LowerSTORE(SDValue Op,SelectionDAG & DAG)299609467b48Spatrick static SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG)
299709467b48Spatrick {
299809467b48Spatrick   SDLoc dl(Op);
299909467b48Spatrick   StoreSDNode *St = cast<StoreSDNode>(Op.getNode());
300009467b48Spatrick 
300109467b48Spatrick   EVT MemVT = St->getMemoryVT();
300209467b48Spatrick   if (MemVT == MVT::f128)
300309467b48Spatrick     return LowerF128Store(Op, DAG);
300409467b48Spatrick 
300509467b48Spatrick   if (MemVT == MVT::i64) {
300609467b48Spatrick     // Custom handling for i64 stores: turn it into a bitcast and a
300709467b48Spatrick     // v2i32 store.
300809467b48Spatrick     SDValue Val = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, St->getValue());
300909467b48Spatrick     SDValue Chain = DAG.getStore(
301009467b48Spatrick         St->getChain(), dl, Val, St->getBasePtr(), St->getPointerInfo(),
3011a0747c9fSpatrick         St->getOriginalAlign(), St->getMemOperand()->getFlags(),
3012a0747c9fSpatrick         St->getAAInfo());
301309467b48Spatrick     return Chain;
301409467b48Spatrick   }
301509467b48Spatrick 
301609467b48Spatrick   return SDValue();
301709467b48Spatrick }
301809467b48Spatrick 
LowerFNEGorFABS(SDValue Op,SelectionDAG & DAG,bool isV9)301909467b48Spatrick static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
302009467b48Spatrick   assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS)
302109467b48Spatrick          && "invalid opcode");
302209467b48Spatrick 
302309467b48Spatrick   SDLoc dl(Op);
302409467b48Spatrick 
302509467b48Spatrick   if (Op.getValueType() == MVT::f64)
302609467b48Spatrick     return LowerF64Op(Op.getOperand(0), dl, DAG, Op.getOpcode());
302709467b48Spatrick   if (Op.getValueType() != MVT::f128)
302809467b48Spatrick     return Op;
302909467b48Spatrick 
303009467b48Spatrick   // Lower fabs/fneg on f128 to fabs/fneg on f64
303109467b48Spatrick   // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64
303209467b48Spatrick   // (As with LowerF64Op, on little-endian, we need to negate the odd
303309467b48Spatrick   // subreg)
303409467b48Spatrick 
303509467b48Spatrick   SDValue SrcReg128 = Op.getOperand(0);
303609467b48Spatrick   SDValue Hi64 = DAG.getTargetExtractSubreg(SP::sub_even64, dl, MVT::f64,
303709467b48Spatrick                                             SrcReg128);
303809467b48Spatrick   SDValue Lo64 = DAG.getTargetExtractSubreg(SP::sub_odd64, dl, MVT::f64,
303909467b48Spatrick                                             SrcReg128);
304009467b48Spatrick 
304109467b48Spatrick   if (DAG.getDataLayout().isLittleEndian()) {
304209467b48Spatrick     if (isV9)
304309467b48Spatrick       Lo64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Lo64);
304409467b48Spatrick     else
304509467b48Spatrick       Lo64 = LowerF64Op(Lo64, dl, DAG, Op.getOpcode());
304609467b48Spatrick   } else {
304709467b48Spatrick     if (isV9)
304809467b48Spatrick       Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64);
304909467b48Spatrick     else
305009467b48Spatrick       Hi64 = LowerF64Op(Hi64, dl, DAG, Op.getOpcode());
305109467b48Spatrick   }
305209467b48Spatrick 
305309467b48Spatrick   SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
305409467b48Spatrick                                                  dl, MVT::f128), 0);
305509467b48Spatrick   DstReg128 = DAG.getTargetInsertSubreg(SP::sub_even64, dl, MVT::f128,
305609467b48Spatrick                                         DstReg128, Hi64);
305709467b48Spatrick   DstReg128 = DAG.getTargetInsertSubreg(SP::sub_odd64, dl, MVT::f128,
305809467b48Spatrick                                         DstReg128, Lo64);
305909467b48Spatrick   return DstReg128;
306009467b48Spatrick }
306109467b48Spatrick 
LowerADDC_ADDE_SUBC_SUBE(SDValue Op,SelectionDAG & DAG)306209467b48Spatrick static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) {
306309467b48Spatrick 
306409467b48Spatrick   if (Op.getValueType() != MVT::i64)
306509467b48Spatrick     return Op;
306609467b48Spatrick 
306709467b48Spatrick   SDLoc dl(Op);
306809467b48Spatrick   SDValue Src1 = Op.getOperand(0);
306909467b48Spatrick   SDValue Src1Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src1);
307009467b48Spatrick   SDValue Src1Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Src1,
307109467b48Spatrick                                DAG.getConstant(32, dl, MVT::i64));
307209467b48Spatrick   Src1Hi = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src1Hi);
307309467b48Spatrick 
307409467b48Spatrick   SDValue Src2 = Op.getOperand(1);
307509467b48Spatrick   SDValue Src2Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src2);
307609467b48Spatrick   SDValue Src2Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Src2,
307709467b48Spatrick                                DAG.getConstant(32, dl, MVT::i64));
307809467b48Spatrick   Src2Hi = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src2Hi);
307909467b48Spatrick 
308009467b48Spatrick 
308109467b48Spatrick   bool hasChain = false;
308209467b48Spatrick   unsigned hiOpc = Op.getOpcode();
308309467b48Spatrick   switch (Op.getOpcode()) {
308409467b48Spatrick   default: llvm_unreachable("Invalid opcode");
308509467b48Spatrick   case ISD::ADDC: hiOpc = ISD::ADDE; break;
308609467b48Spatrick   case ISD::ADDE: hasChain = true; break;
308709467b48Spatrick   case ISD::SUBC: hiOpc = ISD::SUBE; break;
308809467b48Spatrick   case ISD::SUBE: hasChain = true; break;
308909467b48Spatrick   }
309009467b48Spatrick   SDValue Lo;
309109467b48Spatrick   SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Glue);
309209467b48Spatrick   if (hasChain) {
309309467b48Spatrick     Lo = DAG.getNode(Op.getOpcode(), dl, VTs, Src1Lo, Src2Lo,
309409467b48Spatrick                      Op.getOperand(2));
309509467b48Spatrick   } else {
309609467b48Spatrick     Lo = DAG.getNode(Op.getOpcode(), dl, VTs, Src1Lo, Src2Lo);
309709467b48Spatrick   }
309809467b48Spatrick   SDValue Hi = DAG.getNode(hiOpc, dl, VTs, Src1Hi, Src2Hi, Lo.getValue(1));
309909467b48Spatrick   SDValue Carry = Hi.getValue(1);
310009467b48Spatrick 
310109467b48Spatrick   Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Lo);
310209467b48Spatrick   Hi = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Hi);
310309467b48Spatrick   Hi = DAG.getNode(ISD::SHL, dl, MVT::i64, Hi,
310409467b48Spatrick                    DAG.getConstant(32, dl, MVT::i64));
310509467b48Spatrick 
310609467b48Spatrick   SDValue Dst = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, Lo);
310709467b48Spatrick   SDValue Ops[2] = { Dst, Carry };
310809467b48Spatrick   return DAG.getMergeValues(Ops, dl);
310909467b48Spatrick }
311009467b48Spatrick 
311109467b48Spatrick // Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode()
311209467b48Spatrick // in LegalizeDAG.cpp except the order of arguments to the library function.
LowerUMULO_SMULO(SDValue Op,SelectionDAG & DAG,const SparcTargetLowering & TLI)311309467b48Spatrick static SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG,
311409467b48Spatrick                                 const SparcTargetLowering &TLI)
311509467b48Spatrick {
311609467b48Spatrick   unsigned opcode = Op.getOpcode();
311709467b48Spatrick   assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode.");
311809467b48Spatrick 
311909467b48Spatrick   bool isSigned = (opcode == ISD::SMULO);
312009467b48Spatrick   EVT VT = MVT::i64;
312109467b48Spatrick   EVT WideVT = MVT::i128;
312209467b48Spatrick   SDLoc dl(Op);
312309467b48Spatrick   SDValue LHS = Op.getOperand(0);
312409467b48Spatrick 
312509467b48Spatrick   if (LHS.getValueType() != VT)
312609467b48Spatrick     return Op;
312709467b48Spatrick 
312809467b48Spatrick   SDValue ShiftAmt = DAG.getConstant(63, dl, VT);
312909467b48Spatrick 
313009467b48Spatrick   SDValue RHS = Op.getOperand(1);
3131*a96b3639Srobert   SDValue HiLHS, HiRHS;
3132*a96b3639Srobert   if (isSigned) {
3133*a96b3639Srobert     HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt);
3134*a96b3639Srobert     HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt);
3135*a96b3639Srobert   } else {
3136*a96b3639Srobert     HiLHS = DAG.getConstant(0, dl, VT);
3137*a96b3639Srobert     HiRHS = DAG.getConstant(0, dl, MVT::i64);
3138*a96b3639Srobert   }
3139*a96b3639Srobert 
314009467b48Spatrick   SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
314109467b48Spatrick 
314209467b48Spatrick   TargetLowering::MakeLibCallOptions CallOptions;
314309467b48Spatrick   CallOptions.setSExt(isSigned);
314409467b48Spatrick   SDValue MulResult = TLI.makeLibCall(DAG,
314509467b48Spatrick                                       RTLIB::MUL_I128, WideVT,
314609467b48Spatrick                                       Args, CallOptions, dl).first;
314709467b48Spatrick   SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
314809467b48Spatrick                                    MulResult, DAG.getIntPtrConstant(0, dl));
314909467b48Spatrick   SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
315009467b48Spatrick                                 MulResult, DAG.getIntPtrConstant(1, dl));
315109467b48Spatrick   if (isSigned) {
315209467b48Spatrick     SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt);
315309467b48Spatrick     TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE);
315409467b48Spatrick   } else {
315509467b48Spatrick     TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, dl, VT),
315609467b48Spatrick                            ISD::SETNE);
315709467b48Spatrick   }
315809467b48Spatrick   // MulResult is a node with an illegal type. Because such things are not
315909467b48Spatrick   // generally permitted during this phase of legalization, ensure that
316009467b48Spatrick   // nothing is left using the node. The above EXTRACT_ELEMENT nodes should have
316109467b48Spatrick   // been folded.
316209467b48Spatrick   assert(MulResult->use_empty() && "Illegally typed node still in use!");
316309467b48Spatrick 
316409467b48Spatrick   SDValue Ops[2] = { BottomHalf, TopHalf } ;
316509467b48Spatrick   return DAG.getMergeValues(Ops, dl);
316609467b48Spatrick }
316709467b48Spatrick 
LowerATOMIC_LOAD_STORE(SDValue Op,SelectionDAG & DAG)316809467b48Spatrick static SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) {
3169a0747c9fSpatrick   if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering())) {
317009467b48Spatrick     // Expand with a fence.
317109467b48Spatrick     return SDValue();
3172a0747c9fSpatrick   }
317309467b48Spatrick 
317409467b48Spatrick   // Monotonic load/stores are legal.
317509467b48Spatrick   return Op;
317609467b48Spatrick }
317709467b48Spatrick 
LowerINTRINSIC_WO_CHAIN(SDValue Op,SelectionDAG & DAG) const317809467b48Spatrick SDValue SparcTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
317909467b48Spatrick                                                      SelectionDAG &DAG) const {
318009467b48Spatrick   unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
318109467b48Spatrick   SDLoc dl(Op);
318209467b48Spatrick   switch (IntNo) {
318309467b48Spatrick   default: return SDValue();    // Don't custom lower most intrinsics.
318409467b48Spatrick   case Intrinsic::thread_pointer: {
318509467b48Spatrick     EVT PtrVT = getPointerTy(DAG.getDataLayout());
318609467b48Spatrick     return DAG.getRegister(SP::G7, PtrVT);
318709467b48Spatrick   }
318809467b48Spatrick   }
318909467b48Spatrick }
319009467b48Spatrick 
319109467b48Spatrick SDValue SparcTargetLowering::
LowerOperation(SDValue Op,SelectionDAG & DAG) const319209467b48Spatrick LowerOperation(SDValue Op, SelectionDAG &DAG) const {
319309467b48Spatrick 
319409467b48Spatrick   bool hasHardQuad = Subtarget->hasHardQuad();
319509467b48Spatrick   bool isV9        = Subtarget->isV9();
3196*a96b3639Srobert   bool is64Bit = Subtarget->is64Bit();
319709467b48Spatrick 
319809467b48Spatrick   switch (Op.getOpcode()) {
319909467b48Spatrick   default: llvm_unreachable("Should not custom lower this!");
320009467b48Spatrick 
320109467b48Spatrick   case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG, *this,
320209467b48Spatrick                                                        Subtarget);
320309467b48Spatrick   case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG,
320409467b48Spatrick                                                       Subtarget);
320509467b48Spatrick   case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
320609467b48Spatrick   case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
320709467b48Spatrick   case ISD::BlockAddress:       return LowerBlockAddress(Op, DAG);
320809467b48Spatrick   case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
320909467b48Spatrick   case ISD::FP_TO_SINT:         return LowerFP_TO_SINT(Op, DAG, *this,
321009467b48Spatrick                                                        hasHardQuad);
321109467b48Spatrick   case ISD::SINT_TO_FP:         return LowerSINT_TO_FP(Op, DAG, *this,
321209467b48Spatrick                                                        hasHardQuad);
321309467b48Spatrick   case ISD::FP_TO_UINT:         return LowerFP_TO_UINT(Op, DAG, *this,
321409467b48Spatrick                                                        hasHardQuad);
321509467b48Spatrick   case ISD::UINT_TO_FP:         return LowerUINT_TO_FP(Op, DAG, *this,
321609467b48Spatrick                                                        hasHardQuad);
3217*a96b3639Srobert   case ISD::BR_CC:
3218*a96b3639Srobert     return LowerBR_CC(Op, DAG, *this, hasHardQuad, isV9);
3219*a96b3639Srobert   case ISD::SELECT_CC:
3220*a96b3639Srobert     return LowerSELECT_CC(Op, DAG, *this, hasHardQuad, isV9, is64Bit);
322109467b48Spatrick   case ISD::VASTART:            return LowerVASTART(Op, DAG, *this);
322209467b48Spatrick   case ISD::VAARG:              return LowerVAARG(Op, DAG);
322309467b48Spatrick   case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG,
322409467b48Spatrick                                                                Subtarget);
322509467b48Spatrick 
322609467b48Spatrick   case ISD::LOAD:               return LowerLOAD(Op, DAG);
322709467b48Spatrick   case ISD::STORE:              return LowerSTORE(Op, DAG);
322809467b48Spatrick   case ISD::FADD:               return LowerF128Op(Op, DAG,
322909467b48Spatrick                                        getLibcallName(RTLIB::ADD_F128), 2);
323009467b48Spatrick   case ISD::FSUB:               return LowerF128Op(Op, DAG,
323109467b48Spatrick                                        getLibcallName(RTLIB::SUB_F128), 2);
323209467b48Spatrick   case ISD::FMUL:               return LowerF128Op(Op, DAG,
323309467b48Spatrick                                        getLibcallName(RTLIB::MUL_F128), 2);
323409467b48Spatrick   case ISD::FDIV:               return LowerF128Op(Op, DAG,
323509467b48Spatrick                                        getLibcallName(RTLIB::DIV_F128), 2);
323609467b48Spatrick   case ISD::FSQRT:              return LowerF128Op(Op, DAG,
323709467b48Spatrick                                        getLibcallName(RTLIB::SQRT_F128),1);
323809467b48Spatrick   case ISD::FABS:
323909467b48Spatrick   case ISD::FNEG:               return LowerFNEGorFABS(Op, DAG, isV9);
324009467b48Spatrick   case ISD::FP_EXTEND:          return LowerF128_FPEXTEND(Op, DAG, *this);
324109467b48Spatrick   case ISD::FP_ROUND:           return LowerF128_FPROUND(Op, DAG, *this);
324209467b48Spatrick   case ISD::ADDC:
324309467b48Spatrick   case ISD::ADDE:
324409467b48Spatrick   case ISD::SUBC:
324509467b48Spatrick   case ISD::SUBE:               return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
324609467b48Spatrick   case ISD::UMULO:
324709467b48Spatrick   case ISD::SMULO:              return LowerUMULO_SMULO(Op, DAG, *this);
324809467b48Spatrick   case ISD::ATOMIC_LOAD:
324909467b48Spatrick   case ISD::ATOMIC_STORE:       return LowerATOMIC_LOAD_STORE(Op, DAG);
325009467b48Spatrick   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
325109467b48Spatrick   }
325209467b48Spatrick }
325309467b48Spatrick 
bitcastConstantFPToInt(ConstantFPSDNode * C,const SDLoc & DL,SelectionDAG & DAG) const325409467b48Spatrick SDValue SparcTargetLowering::bitcastConstantFPToInt(ConstantFPSDNode *C,
325509467b48Spatrick                                                     const SDLoc &DL,
325609467b48Spatrick                                                     SelectionDAG &DAG) const {
325709467b48Spatrick   APInt V = C->getValueAPF().bitcastToAPInt();
325809467b48Spatrick   SDValue Lo = DAG.getConstant(V.zextOrTrunc(32), DL, MVT::i32);
325909467b48Spatrick   SDValue Hi = DAG.getConstant(V.lshr(32).zextOrTrunc(32), DL, MVT::i32);
326009467b48Spatrick   if (DAG.getDataLayout().isLittleEndian())
326109467b48Spatrick     std::swap(Lo, Hi);
326209467b48Spatrick   return DAG.getBuildVector(MVT::v2i32, DL, {Hi, Lo});
326309467b48Spatrick }
326409467b48Spatrick 
PerformBITCASTCombine(SDNode * N,DAGCombinerInfo & DCI) const326509467b48Spatrick SDValue SparcTargetLowering::PerformBITCASTCombine(SDNode *N,
326609467b48Spatrick                                                    DAGCombinerInfo &DCI) const {
326709467b48Spatrick   SDLoc dl(N);
326809467b48Spatrick   SDValue Src = N->getOperand(0);
326909467b48Spatrick 
327009467b48Spatrick   if (isa<ConstantFPSDNode>(Src) && N->getSimpleValueType(0) == MVT::v2i32 &&
327109467b48Spatrick       Src.getSimpleValueType() == MVT::f64)
327209467b48Spatrick     return bitcastConstantFPToInt(cast<ConstantFPSDNode>(Src), dl, DCI.DAG);
327309467b48Spatrick 
327409467b48Spatrick   return SDValue();
327509467b48Spatrick }
327609467b48Spatrick 
PerformDAGCombine(SDNode * N,DAGCombinerInfo & DCI) const327709467b48Spatrick SDValue SparcTargetLowering::PerformDAGCombine(SDNode *N,
327809467b48Spatrick                                                DAGCombinerInfo &DCI) const {
327909467b48Spatrick   switch (N->getOpcode()) {
328009467b48Spatrick   default:
328109467b48Spatrick     break;
328209467b48Spatrick   case ISD::BITCAST:
328309467b48Spatrick     return PerformBITCASTCombine(N, DCI);
328409467b48Spatrick   }
328509467b48Spatrick   return SDValue();
328609467b48Spatrick }
328709467b48Spatrick 
328809467b48Spatrick MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr & MI,MachineBasicBlock * BB) const328909467b48Spatrick SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
329009467b48Spatrick                                                  MachineBasicBlock *BB) const {
329109467b48Spatrick   switch (MI.getOpcode()) {
329209467b48Spatrick   default: llvm_unreachable("Unknown SELECT_CC!");
329309467b48Spatrick   case SP::SELECT_CC_Int_ICC:
329409467b48Spatrick   case SP::SELECT_CC_FP_ICC:
329509467b48Spatrick   case SP::SELECT_CC_DFP_ICC:
329609467b48Spatrick   case SP::SELECT_CC_QFP_ICC:
3297*a96b3639Srobert     if (Subtarget->isV9())
3298*a96b3639Srobert       return expandSelectCC(MI, BB, SP::BPICC);
329909467b48Spatrick     return expandSelectCC(MI, BB, SP::BCOND);
3300adae0cfdSpatrick   case SP::SELECT_CC_Int_XCC:
3301adae0cfdSpatrick   case SP::SELECT_CC_FP_XCC:
3302adae0cfdSpatrick   case SP::SELECT_CC_DFP_XCC:
3303adae0cfdSpatrick   case SP::SELECT_CC_QFP_XCC:
3304adae0cfdSpatrick     return expandSelectCC(MI, BB, SP::BPXCC);
330509467b48Spatrick   case SP::SELECT_CC_Int_FCC:
330609467b48Spatrick   case SP::SELECT_CC_FP_FCC:
330709467b48Spatrick   case SP::SELECT_CC_DFP_FCC:
330809467b48Spatrick   case SP::SELECT_CC_QFP_FCC:
3309*a96b3639Srobert     if (Subtarget->isV9())
3310*a96b3639Srobert       return expandSelectCC(MI, BB, SP::FBCOND_V9);
331109467b48Spatrick     return expandSelectCC(MI, BB, SP::FBCOND);
331209467b48Spatrick   }
331309467b48Spatrick }
331409467b48Spatrick 
331509467b48Spatrick MachineBasicBlock *
expandSelectCC(MachineInstr & MI,MachineBasicBlock * BB,unsigned BROpcode) const331609467b48Spatrick SparcTargetLowering::expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB,
331709467b48Spatrick                                     unsigned BROpcode) const {
331809467b48Spatrick   const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
331909467b48Spatrick   DebugLoc dl = MI.getDebugLoc();
332009467b48Spatrick   unsigned CC = (SPCC::CondCodes)MI.getOperand(3).getImm();
332109467b48Spatrick 
332209467b48Spatrick   // To "insert" a SELECT_CC instruction, we actually have to insert the
332309467b48Spatrick   // triangle control-flow pattern. The incoming instruction knows the
332409467b48Spatrick   // destination vreg to set, the condition code register to branch on, the
332509467b48Spatrick   // true/false values to select between, and the condition code for the branch.
332609467b48Spatrick   //
332709467b48Spatrick   // We produce the following control flow:
332809467b48Spatrick   //     ThisMBB
332909467b48Spatrick   //     |  \
333009467b48Spatrick   //     |  IfFalseMBB
333109467b48Spatrick   //     | /
333209467b48Spatrick   //    SinkMBB
333309467b48Spatrick   const BasicBlock *LLVM_BB = BB->getBasicBlock();
333409467b48Spatrick   MachineFunction::iterator It = ++BB->getIterator();
333509467b48Spatrick 
333609467b48Spatrick   MachineBasicBlock *ThisMBB = BB;
333709467b48Spatrick   MachineFunction *F = BB->getParent();
333809467b48Spatrick   MachineBasicBlock *IfFalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
333909467b48Spatrick   MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
334009467b48Spatrick   F->insert(It, IfFalseMBB);
334109467b48Spatrick   F->insert(It, SinkMBB);
334209467b48Spatrick 
334309467b48Spatrick   // Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
334409467b48Spatrick   SinkMBB->splice(SinkMBB->begin(), ThisMBB,
334509467b48Spatrick                   std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
334609467b48Spatrick   SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);
334709467b48Spatrick 
334809467b48Spatrick   // Set the new successors for ThisMBB.
334909467b48Spatrick   ThisMBB->addSuccessor(IfFalseMBB);
335009467b48Spatrick   ThisMBB->addSuccessor(SinkMBB);
335109467b48Spatrick 
335209467b48Spatrick   BuildMI(ThisMBB, dl, TII.get(BROpcode))
335309467b48Spatrick     .addMBB(SinkMBB)
335409467b48Spatrick     .addImm(CC);
335509467b48Spatrick 
335609467b48Spatrick   // IfFalseMBB just falls through to SinkMBB.
335709467b48Spatrick   IfFalseMBB->addSuccessor(SinkMBB);
335809467b48Spatrick 
335909467b48Spatrick   // %Result = phi [ %TrueValue, ThisMBB ], [ %FalseValue, IfFalseMBB ]
336009467b48Spatrick   BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(SP::PHI),
336109467b48Spatrick           MI.getOperand(0).getReg())
336209467b48Spatrick       .addReg(MI.getOperand(1).getReg())
336309467b48Spatrick       .addMBB(ThisMBB)
336409467b48Spatrick       .addReg(MI.getOperand(2).getReg())
336509467b48Spatrick       .addMBB(IfFalseMBB);
336609467b48Spatrick 
336709467b48Spatrick   MI.eraseFromParent(); // The pseudo instruction is gone now.
336809467b48Spatrick   return SinkMBB;
336909467b48Spatrick }
337009467b48Spatrick 
337109467b48Spatrick //===----------------------------------------------------------------------===//
337209467b48Spatrick //                         Sparc Inline Assembly Support
337309467b48Spatrick //===----------------------------------------------------------------------===//
337409467b48Spatrick 
337509467b48Spatrick /// getConstraintType - Given a constraint letter, return the type of
337609467b48Spatrick /// constraint it is for this target.
337709467b48Spatrick SparcTargetLowering::ConstraintType
getConstraintType(StringRef Constraint) const337809467b48Spatrick SparcTargetLowering::getConstraintType(StringRef Constraint) const {
337909467b48Spatrick   if (Constraint.size() == 1) {
338009467b48Spatrick     switch (Constraint[0]) {
338109467b48Spatrick     default:  break;
338209467b48Spatrick     case 'r':
338309467b48Spatrick     case 'f':
338409467b48Spatrick     case 'e':
338509467b48Spatrick       return C_RegisterClass;
338609467b48Spatrick     case 'I': // SIMM13
338709467b48Spatrick       return C_Immediate;
338809467b48Spatrick     }
338909467b48Spatrick   }
339009467b48Spatrick 
339109467b48Spatrick   return TargetLowering::getConstraintType(Constraint);
339209467b48Spatrick }
339309467b48Spatrick 
339409467b48Spatrick TargetLowering::ConstraintWeight SparcTargetLowering::
getSingleConstraintMatchWeight(AsmOperandInfo & info,const char * constraint) const339509467b48Spatrick getSingleConstraintMatchWeight(AsmOperandInfo &info,
339609467b48Spatrick                                const char *constraint) const {
339709467b48Spatrick   ConstraintWeight weight = CW_Invalid;
339809467b48Spatrick   Value *CallOperandVal = info.CallOperandVal;
339909467b48Spatrick   // If we don't have a value, we can't do a match,
340009467b48Spatrick   // but allow it at the lowest weight.
340109467b48Spatrick   if (!CallOperandVal)
340209467b48Spatrick     return CW_Default;
340309467b48Spatrick 
340409467b48Spatrick   // Look at the constraint type.
340509467b48Spatrick   switch (*constraint) {
340609467b48Spatrick   default:
340709467b48Spatrick     weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
340809467b48Spatrick     break;
340909467b48Spatrick   case 'I': // SIMM13
341009467b48Spatrick     if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
341109467b48Spatrick       if (isInt<13>(C->getSExtValue()))
341209467b48Spatrick         weight = CW_Constant;
341309467b48Spatrick     }
341409467b48Spatrick     break;
341509467b48Spatrick   }
341609467b48Spatrick   return weight;
341709467b48Spatrick }
341809467b48Spatrick 
341909467b48Spatrick /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
342009467b48Spatrick /// vector.  If it is invalid, don't add anything to Ops.
342109467b48Spatrick void SparcTargetLowering::
LowerAsmOperandForConstraint(SDValue Op,std::string & Constraint,std::vector<SDValue> & Ops,SelectionDAG & DAG) const342209467b48Spatrick LowerAsmOperandForConstraint(SDValue Op,
342309467b48Spatrick                              std::string &Constraint,
342409467b48Spatrick                              std::vector<SDValue> &Ops,
342509467b48Spatrick                              SelectionDAG &DAG) const {
3426*a96b3639Srobert   SDValue Result;
342709467b48Spatrick 
342809467b48Spatrick   // Only support length 1 constraints for now.
342909467b48Spatrick   if (Constraint.length() > 1)
343009467b48Spatrick     return;
343109467b48Spatrick 
343209467b48Spatrick   char ConstraintLetter = Constraint[0];
343309467b48Spatrick   switch (ConstraintLetter) {
343409467b48Spatrick   default: break;
343509467b48Spatrick   case 'I':
343609467b48Spatrick     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
343709467b48Spatrick       if (isInt<13>(C->getSExtValue())) {
343809467b48Spatrick         Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(Op),
343909467b48Spatrick                                        Op.getValueType());
344009467b48Spatrick         break;
344109467b48Spatrick       }
344209467b48Spatrick       return;
344309467b48Spatrick     }
344409467b48Spatrick   }
344509467b48Spatrick 
344609467b48Spatrick   if (Result.getNode()) {
344709467b48Spatrick     Ops.push_back(Result);
344809467b48Spatrick     return;
344909467b48Spatrick   }
345009467b48Spatrick   TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
345109467b48Spatrick }
345209467b48Spatrick 
345309467b48Spatrick std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo * TRI,StringRef Constraint,MVT VT) const345409467b48Spatrick SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
345509467b48Spatrick                                                   StringRef Constraint,
345609467b48Spatrick                                                   MVT VT) const {
3457*a96b3639Srobert   if (Constraint.empty())
3458*a96b3639Srobert     return std::make_pair(0U, nullptr);
3459*a96b3639Srobert 
346009467b48Spatrick   if (Constraint.size() == 1) {
346109467b48Spatrick     switch (Constraint[0]) {
346209467b48Spatrick     case 'r':
346309467b48Spatrick       if (VT == MVT::v2i32)
346409467b48Spatrick         return std::make_pair(0U, &SP::IntPairRegClass);
346509467b48Spatrick       else if (Subtarget->is64Bit())
346609467b48Spatrick         return std::make_pair(0U, &SP::I64RegsRegClass);
346709467b48Spatrick       else
346809467b48Spatrick         return std::make_pair(0U, &SP::IntRegsRegClass);
346909467b48Spatrick     case 'f':
347009467b48Spatrick       if (VT == MVT::f32 || VT == MVT::i32)
347109467b48Spatrick         return std::make_pair(0U, &SP::FPRegsRegClass);
347209467b48Spatrick       else if (VT == MVT::f64 || VT == MVT::i64)
347309467b48Spatrick         return std::make_pair(0U, &SP::LowDFPRegsRegClass);
347409467b48Spatrick       else if (VT == MVT::f128)
347509467b48Spatrick         return std::make_pair(0U, &SP::LowQFPRegsRegClass);
347609467b48Spatrick       // This will generate an error message
347709467b48Spatrick       return std::make_pair(0U, nullptr);
347809467b48Spatrick     case 'e':
347909467b48Spatrick       if (VT == MVT::f32 || VT == MVT::i32)
348009467b48Spatrick         return std::make_pair(0U, &SP::FPRegsRegClass);
348109467b48Spatrick       else if (VT == MVT::f64 || VT == MVT::i64 )
348209467b48Spatrick         return std::make_pair(0U, &SP::DFPRegsRegClass);
348309467b48Spatrick       else if (VT == MVT::f128)
348409467b48Spatrick         return std::make_pair(0U, &SP::QFPRegsRegClass);
348509467b48Spatrick       // This will generate an error message
348609467b48Spatrick       return std::make_pair(0U, nullptr);
348709467b48Spatrick     }
3488*a96b3639Srobert   }
3489*a96b3639Srobert 
3490*a96b3639Srobert   if (Constraint.front() != '{')
3491*a96b3639Srobert     return std::make_pair(0U, nullptr);
3492*a96b3639Srobert 
3493*a96b3639Srobert   assert(Constraint.back() == '}' && "Not a brace enclosed constraint?");
3494*a96b3639Srobert   StringRef RegName(Constraint.data() + 1, Constraint.size() - 2);
3495*a96b3639Srobert   if (RegName.empty())
3496*a96b3639Srobert     return std::make_pair(0U, nullptr);
3497*a96b3639Srobert 
3498*a96b3639Srobert   unsigned long long RegNo;
3499*a96b3639Srobert   // Handle numbered register aliases.
3500*a96b3639Srobert   if (RegName[0] == 'r' &&
3501*a96b3639Srobert       getAsUnsignedInteger(RegName.begin() + 1, 10, RegNo)) {
350209467b48Spatrick     // r0-r7   -> g0-g7
350309467b48Spatrick     // r8-r15  -> o0-o7
350409467b48Spatrick     // r16-r23 -> l0-l7
350509467b48Spatrick     // r24-r31 -> i0-i7
3506*a96b3639Srobert     if (RegNo > 31)
3507*a96b3639Srobert       return std::make_pair(0U, nullptr);
3508*a96b3639Srobert     const char RegTypes[] = {'g', 'o', 'l', 'i'};
3509*a96b3639Srobert     char RegType = RegTypes[RegNo / 8];
3510*a96b3639Srobert     char RegIndex = '0' + (RegNo % 8);
3511*a96b3639Srobert     char Tmp[] = {'{', RegType, RegIndex, '}', 0};
3512*a96b3639Srobert     return getRegForInlineAsmConstraint(TRI, Tmp, VT);
351309467b48Spatrick   }
351409467b48Spatrick 
3515*a96b3639Srobert   // Rewrite the fN constraint according to the value type if needed.
3516*a96b3639Srobert   if (VT != MVT::f32 && VT != MVT::Other && RegName[0] == 'f' &&
3517*a96b3639Srobert       getAsUnsignedInteger(RegName.begin() + 1, 10, RegNo)) {
3518*a96b3639Srobert     if (VT == MVT::f64 && (RegNo % 2 == 0)) {
3519*a96b3639Srobert       return getRegForInlineAsmConstraint(
3520*a96b3639Srobert           TRI, StringRef("{d" + utostr(RegNo / 2) + "}"), VT);
3521*a96b3639Srobert     } else if (VT == MVT::f128 && (RegNo % 4 == 0)) {
3522*a96b3639Srobert       return getRegForInlineAsmConstraint(
3523*a96b3639Srobert           TRI, StringRef("{q" + utostr(RegNo / 4) + "}"), VT);
352409467b48Spatrick     } else {
352509467b48Spatrick       return std::make_pair(0U, nullptr);
352609467b48Spatrick     }
352709467b48Spatrick   }
352809467b48Spatrick 
3529*a96b3639Srobert   auto ResultPair =
3530*a96b3639Srobert       TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3531*a96b3639Srobert   if (!ResultPair.second)
3532*a96b3639Srobert     return std::make_pair(0U, nullptr);
3533*a96b3639Srobert 
3534*a96b3639Srobert   // Force the use of I64Regs over IntRegs for 64-bit values.
3535*a96b3639Srobert   if (Subtarget->is64Bit() && VT == MVT::i64) {
3536*a96b3639Srobert     assert(ResultPair.second == &SP::IntRegsRegClass &&
3537*a96b3639Srobert            "Unexpected register class");
3538*a96b3639Srobert     return std::make_pair(ResultPair.first, &SP::I64RegsRegClass);
3539*a96b3639Srobert   }
3540*a96b3639Srobert 
3541*a96b3639Srobert   return ResultPair;
354209467b48Spatrick }
354309467b48Spatrick 
354409467b48Spatrick bool
isOffsetFoldingLegal(const GlobalAddressSDNode * GA) const354509467b48Spatrick SparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
354609467b48Spatrick   // The Sparc target isn't yet aware of offsets.
354709467b48Spatrick   return false;
354809467b48Spatrick }
354909467b48Spatrick 
ReplaceNodeResults(SDNode * N,SmallVectorImpl<SDValue> & Results,SelectionDAG & DAG) const355009467b48Spatrick void SparcTargetLowering::ReplaceNodeResults(SDNode *N,
355109467b48Spatrick                                              SmallVectorImpl<SDValue>& Results,
355209467b48Spatrick                                              SelectionDAG &DAG) const {
355309467b48Spatrick 
355409467b48Spatrick   SDLoc dl(N);
355509467b48Spatrick 
355609467b48Spatrick   RTLIB::Libcall libCall = RTLIB::UNKNOWN_LIBCALL;
355709467b48Spatrick 
355809467b48Spatrick   switch (N->getOpcode()) {
355909467b48Spatrick   default:
356009467b48Spatrick     llvm_unreachable("Do not know how to custom type legalize this operation!");
356109467b48Spatrick 
356209467b48Spatrick   case ISD::FP_TO_SINT:
356309467b48Spatrick   case ISD::FP_TO_UINT:
356409467b48Spatrick     // Custom lower only if it involves f128 or i64.
356509467b48Spatrick     if (N->getOperand(0).getValueType() != MVT::f128
356609467b48Spatrick         || N->getValueType(0) != MVT::i64)
356709467b48Spatrick       return;
356809467b48Spatrick     libCall = ((N->getOpcode() == ISD::FP_TO_SINT)
356909467b48Spatrick                ? RTLIB::FPTOSINT_F128_I64
357009467b48Spatrick                : RTLIB::FPTOUINT_F128_I64);
357109467b48Spatrick 
357209467b48Spatrick     Results.push_back(LowerF128Op(SDValue(N, 0),
357309467b48Spatrick                                   DAG,
357409467b48Spatrick                                   getLibcallName(libCall),
357509467b48Spatrick                                   1));
357609467b48Spatrick     return;
357709467b48Spatrick   case ISD::READCYCLECOUNTER: {
357809467b48Spatrick     assert(Subtarget->hasLeonCycleCounter());
357909467b48Spatrick     SDValue Lo = DAG.getCopyFromReg(N->getOperand(0), dl, SP::ASR23, MVT::i32);
358009467b48Spatrick     SDValue Hi = DAG.getCopyFromReg(Lo, dl, SP::G0, MVT::i32);
358109467b48Spatrick     SDValue Ops[] = { Lo, Hi };
358209467b48Spatrick     SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Ops);
358309467b48Spatrick     Results.push_back(Pair);
358409467b48Spatrick     Results.push_back(N->getOperand(0));
358509467b48Spatrick     return;
358609467b48Spatrick   }
358709467b48Spatrick   case ISD::SINT_TO_FP:
358809467b48Spatrick   case ISD::UINT_TO_FP:
358909467b48Spatrick     // Custom lower only if it involves f128 or i64.
359009467b48Spatrick     if (N->getValueType(0) != MVT::f128
359109467b48Spatrick         || N->getOperand(0).getValueType() != MVT::i64)
359209467b48Spatrick       return;
359309467b48Spatrick 
359409467b48Spatrick     libCall = ((N->getOpcode() == ISD::SINT_TO_FP)
359509467b48Spatrick                ? RTLIB::SINTTOFP_I64_F128
359609467b48Spatrick                : RTLIB::UINTTOFP_I64_F128);
359709467b48Spatrick 
359809467b48Spatrick     Results.push_back(LowerF128Op(SDValue(N, 0),
359909467b48Spatrick                                   DAG,
360009467b48Spatrick                                   getLibcallName(libCall),
360109467b48Spatrick                                   1));
360209467b48Spatrick     return;
360309467b48Spatrick   case ISD::LOAD: {
360409467b48Spatrick     LoadSDNode *Ld = cast<LoadSDNode>(N);
360509467b48Spatrick     // Custom handling only for i64: turn i64 load into a v2i32 load,
360609467b48Spatrick     // and a bitcast.
360709467b48Spatrick     if (Ld->getValueType(0) != MVT::i64 || Ld->getMemoryVT() != MVT::i64)
360809467b48Spatrick       return;
360909467b48Spatrick 
361009467b48Spatrick     SDLoc dl(N);
361109467b48Spatrick     SDValue LoadRes = DAG.getExtLoad(
361209467b48Spatrick         Ld->getExtensionType(), dl, MVT::v2i32, Ld->getChain(),
3613a0747c9fSpatrick         Ld->getBasePtr(), Ld->getPointerInfo(), MVT::v2i32,
3614a0747c9fSpatrick         Ld->getOriginalAlign(), Ld->getMemOperand()->getFlags(),
3615a0747c9fSpatrick         Ld->getAAInfo());
361609467b48Spatrick 
361709467b48Spatrick     SDValue Res = DAG.getNode(ISD::BITCAST, dl, MVT::i64, LoadRes);
361809467b48Spatrick     Results.push_back(Res);
361909467b48Spatrick     Results.push_back(LoadRes.getValue(1));
362009467b48Spatrick     return;
362109467b48Spatrick   }
362209467b48Spatrick   }
362309467b48Spatrick }
362409467b48Spatrick 
362509467b48Spatrick // Override to enable LOAD_STACK_GUARD lowering on Linux.
useLoadStackGuardNode() const362609467b48Spatrick bool SparcTargetLowering::useLoadStackGuardNode() const {
362709467b48Spatrick   if (!Subtarget->isTargetLinux())
362809467b48Spatrick     return TargetLowering::useLoadStackGuardNode();
362909467b48Spatrick   return true;
363009467b48Spatrick }
363109467b48Spatrick 
363209467b48Spatrick // Override to disable global variable loading on Linux.
insertSSPDeclarations(Module & M) const363309467b48Spatrick void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
363409467b48Spatrick   if (!Subtarget->isTargetLinux())
363509467b48Spatrick     return TargetLowering::insertSSPDeclarations(M);
363609467b48Spatrick }
3637