SparcISelLowering.cpp revision 87ce01739b058fd6d929cd8e609ceecf82f919a7
18cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===//
28cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//
38cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//                     The LLVM Compiler Infrastructure
48cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//
58cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// This file is distributed under the University of Illinois Open Source
68cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// License. See LICENSE.TXT for details.
78cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//
88cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//===----------------------------------------------------------------------===//
98cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//
108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// This file implements the interfaces that Sparc uses to lower LLVM code into a
118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// selection DAG.
128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//
138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//===----------------------------------------------------------------------===//
148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "SparcISelLowering.h"
168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "SparcMachineFunctionInfo.h"
178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "SparcTargetMachine.h"
188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "MCTargetDesc/SparcBaseInfo.h"
198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/CallingConvLower.h"
208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/MachineFrameInfo.h"
218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/MachineFunction.h"
228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/MachineInstrBuilder.h"
238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/MachineRegisterInfo.h"
248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/SelectionDAG.h"
258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/IR/DerivedTypes.h"
278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/IR/Function.h"
288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/IR/Module.h"
298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "llvm/Support/ErrorHandling.h"
308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comusing namespace llvm;
318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//===----------------------------------------------------------------------===//
348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Calling Convention Implementation
358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//===----------------------------------------------------------------------===//
368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comstatic bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT,
388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 ISD::ArgFlagsTy &ArgFlags, CCState &State)
408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com{
418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  assert (ArgFlags.isSRet());
428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  //Assign SRet argument
448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                         0,
468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                         LocVT, LocInfo));
478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return true;
488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comstatic bool CC_Sparc_Assign_f64(unsigned &ValNo, MVT &ValVT,
518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                MVT &LocVT, CCValAssign::LocInfo &LocInfo,
528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                ISD::ArgFlagsTy &ArgFlags, CCState &State)
538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com{
548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  static const uint16_t RegList[] = {
558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  };
578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  //Try to get first reg
588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (unsigned Reg = State.AllocateReg(RegList, 6)) {
598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  } else {
618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    //Assign whole thing in stack
628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                           State.AllocateStack(8,4),
648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                           LocVT, LocInfo));
658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return true;
668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  //Try to get second reg
698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (unsigned Reg = State.AllocateReg(RegList, 6))
708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  else
728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                           State.AllocateStack(4,4),
748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                           LocVT, LocInfo));
758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return true;
768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Allocate a full-sized argument for the 64-bit ABI.
798cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comstatic bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT,
808cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                            MVT &LocVT, CCValAssign::LocInfo &LocInfo,
818cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                            ISD::ArgFlagsTy &ArgFlags, CCState &State) {
828cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  assert((LocVT == MVT::f32 || LocVT.getSizeInBits() == 64) &&
838cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com         "Can't handle non-64 bits locations");
848cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
858cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Stack space is allocated for all arguments starting from [%fp+BIAS+128].
868cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  unsigned Offset = State.AllocateStack(8, 8);
878cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  unsigned Reg = 0;
888cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
898cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (LocVT == MVT::i64 && Offset < 6*8)
908cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Promote integers to %i0-%i5.
918cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Reg = SP::I0 + Offset/8;
928cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  else if (LocVT == MVT::f64 && Offset < 16*8)
938cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Promote doubles to %d0-%d30. (Which LLVM calls D0-D15).
948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Reg = SP::D0 + Offset/8;
958cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  else if (LocVT == MVT::f32 && Offset < 16*8)
968cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Promote floats to %f1, %f3, ...
978cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Reg = SP::F1 + Offset/4;
988cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
998cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Promote to register when possible, otherwise use the stack slot.
1008cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Reg) {
1018cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
1028cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return true;
1038cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
1048cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1058cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // This argument goes on the stack in an 8-byte slot.
1068cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to
1078cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // the right-aligned float. The first 4 bytes of the stack slot are undefined.
1088cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (LocVT == MVT::f32)
1098cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Offset += 4;
1108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
1128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return true;
1138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
1148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Allocate a half-sized argument for the 64-bit ABI.
1168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com//
1178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// This is used when passing { float, int } structs by value in registers.
1188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comstatic bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT,
1198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                            MVT &LocVT, CCValAssign::LocInfo &LocInfo,
1208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                            ISD::ArgFlagsTy &ArgFlags, CCState &State) {
1218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations");
1228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  unsigned Offset = State.AllocateStack(4, 4);
1238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (LocVT == MVT::f32 && Offset < 16*8) {
1258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Promote floats to %f0-%f31.
1268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    State.addLoc(CCValAssign::getReg(ValNo, ValVT, SP::F0 + Offset/4,
1278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                     LocVT, LocInfo));
1288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return true;
1298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
1308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (LocVT == MVT::i32 && Offset < 6*8) {
1328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Promote integers to %i0-%i5, using half the register.
1338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Reg = SP::I0 + Offset/8;
1348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    LocVT = MVT::i64;
1358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    LocInfo = CCValAssign::AExt;
1368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Set the Custom bit if this i32 goes in the high bits of a register.
1388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (Offset % 8 == 0)
1398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg,
1408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                             LocVT, LocInfo));
1418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    else
1428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
1438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return true;
1448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
1458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
1478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return true;
1488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
1498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com#include "SparcGenCallingConv.inc"
1518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// The calling conventions in SparcCallingConv.td are described in terms of the
1538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// callee's register window. This function translates registers to the
1548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// corresponding caller window %o register.
1558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comstatic unsigned toCallerWindow(unsigned Reg) {
1568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  assert(SP::I0 + 7 == SP::I7 && SP::O0 + 7 == SP::O7 && "Unexpected enum");
1578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Reg >= SP::I0 && Reg <= SP::I7)
1588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return Reg - SP::I0 + SP::O0;
1598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return Reg;
1608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
1618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue
1638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSparcTargetLowering::LowerReturn(SDValue Chain,
1648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 CallingConv::ID CallConv, bool IsVarArg,
1658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 const SmallVectorImpl<ISD::OutputArg> &Outs,
1668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 const SmallVectorImpl<SDValue> &OutVals,
1678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 DebugLoc DL, SelectionDAG &DAG) const {
1688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Subtarget->is64Bit())
1698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return LowerReturn_64(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
1708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return LowerReturn_32(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
1718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
1728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue
1748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSparcTargetLowering::LowerReturn_32(SDValue Chain,
1758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    CallingConv::ID CallConv, bool IsVarArg,
1768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    const SmallVectorImpl<ISD::OutputArg> &Outs,
1778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    const SmallVectorImpl<SDValue> &OutVals,
1788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    DebugLoc DL, SelectionDAG &DAG) const {
1798cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  MachineFunction &MF = DAG.getMachineFunction();
1808cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1818cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // CCValAssign - represent the assignment of the return value to locations.
1828cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<CCValAssign, 16> RVLocs;
1838cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1848cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // CCState - Info about the registers and stack slot.
1858cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
1868cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                 DAG.getTarget(), RVLocs, *DAG.getContext());
1878cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1888cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Analyze return values.
1898cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32);
1908cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1918cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SDValue Flag;
1928cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<SDValue, 4> RetOps(1, Chain);
1938cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Make room for the return address offset.
1948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  RetOps.push_back(SDValue());
1958cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
1968cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Copy the result values into the output registers.
1978cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  for (unsigned i = 0; i != RVLocs.size(); ++i) {
1988cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    CCValAssign &VA = RVLocs[i];
1998cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    assert(VA.isRegLoc() && "Can only return in registers!");
2008cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2018cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(),
2028cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                             OutVals[i], Flag);
2038cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2048cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Guarantee that all emitted copies are stuck together with flags.
2058cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Flag = Chain.getValue(1);
2068cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
2078cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
2088cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2098cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  unsigned RetAddrOffset = 8; //Call Inst + Delay Slot
2108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // If the function returns a struct, copy the SRetReturnReg to I0
2118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (MF.getFunction()->hasStructRetAttr()) {
2128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>();
2138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Reg = SFI->getSRetReturnReg();
2148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (!Reg)
2158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      llvm_unreachable("sret virtual register not created in the entry block");
2168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy());
2178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Flag);
2188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Flag = Chain.getValue(1);
2198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    RetOps.push_back(DAG.getRegister(SP::I0, getPointerTy()));
2208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    RetAddrOffset = 12; // CallInst + Delay Slot + Unimp
2218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
2228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  RetOps[0] = Chain;  // Update chain.
2248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  RetOps[1] = DAG.getConstant(RetAddrOffset, MVT::i32);
2258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Add the flag if we have it.
2278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Flag.getNode())
2288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    RetOps.push_back(Flag);
2298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other,
2318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     &RetOps[0], RetOps.size());
2328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
2338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Lower return values for the 64-bit ABI.
2358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Return values are passed the exactly the same way as function arguments.
2368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue
2378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSparcTargetLowering::LowerReturn_64(SDValue Chain,
2388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    CallingConv::ID CallConv, bool IsVarArg,
2398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    const SmallVectorImpl<ISD::OutputArg> &Outs,
2408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    const SmallVectorImpl<SDValue> &OutVals,
2418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                    DebugLoc DL, SelectionDAG &DAG) const {
2428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // CCValAssign - represent the assignment of the return value to locations.
2438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<CCValAssign, 16> RVLocs;
2448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // CCState - Info about the registers and stack slot.
2468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
2478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                 DAG.getTarget(), RVLocs, *DAG.getContext());
2488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Analyze return values.
2508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCInfo.AnalyzeReturn(Outs, CC_Sparc64);
2518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SDValue Flag;
2538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<SDValue, 4> RetOps(1, Chain);
2548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // The second operand on the return instruction is the return address offset.
2568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // The return address is always %i7+8 with the 64-bit ABI.
2578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  RetOps.push_back(DAG.getConstant(8, MVT::i32));
2588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Copy the result values into the output registers.
2608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  for (unsigned i = 0; i != RVLocs.size(); ++i) {
2618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    CCValAssign &VA = RVLocs[i];
2628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    assert(VA.isRegLoc() && "Can only return in registers!");
2638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue OutVal = OutVals[i];
2648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Integer return values must be sign or zero extended by the callee.
2668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    switch (VA.getLocInfo()) {
2678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    case CCValAssign::SExt:
2688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
2698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      break;
2708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    case CCValAssign::ZExt:
2718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
2728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      break;
2738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    case CCValAssign::AExt:
2748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
2758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    default:
2768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      break;
2778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
2788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2798cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // The custom bit on an i32 return value indicates that it should be passed
2808cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // in the high bits of the register.
2818cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
2828cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal,
2838cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                           DAG.getConstant(32, MVT::i32));
2848cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2858cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // The next value may go in the low bits of the same register.
2868cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // Handle both at once.
2878cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) {
2888cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]);
2898cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV);
2908cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        // Skip the next value, it's already done.
2918cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        ++i;
2928cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      }
2938cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
2948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2958cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag);
2968cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
2978cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Guarantee that all emitted copies are stuck together with flags.
2988cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Flag = Chain.getValue(1);
2998cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3008cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
3018cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3028cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  RetOps[0] = Chain;  // Update chain.
3038cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3048cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Add the flag if we have it.
3058cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Flag.getNode())
3068cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    RetOps.push_back(Flag);
3078cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3088cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other,
3098cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     &RetOps[0], RetOps.size());
3108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
3118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue SparcTargetLowering::
3138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comLowerFormalArguments(SDValue Chain,
3148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     CallingConv::ID CallConv,
3158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     bool IsVarArg,
3168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     const SmallVectorImpl<ISD::InputArg> &Ins,
3178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     DebugLoc DL,
3188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     SelectionDAG &DAG,
3198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                     SmallVectorImpl<SDValue> &InVals) const {
3208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Subtarget->is64Bit())
3218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins,
3228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                   DL, DAG, InVals);
3238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins,
3248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 DL, DAG, InVals);
3258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
3268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are
3288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com/// passed in either one or two GPRs, including FP values.  TODO: we should
3298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com/// pass FP values in FP registers for fastcc functions.
3308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue SparcTargetLowering::
3318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comLowerFormalArguments_32(SDValue Chain,
3328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        CallingConv::ID CallConv,
3338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        bool isVarArg,
3348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        const SmallVectorImpl<ISD::InputArg> &Ins,
3358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        DebugLoc dl,
3368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        SelectionDAG &DAG,
3378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        SmallVectorImpl<SDValue> &InVals) const {
3388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  MachineFunction &MF = DAG.getMachineFunction();
3398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  MachineRegisterInfo &RegInfo = MF.getRegInfo();
3408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
3418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Assign locations to all of the incoming arguments.
3438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<CCValAssign, 16> ArgLocs;
3448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
3458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                 getTargetMachine(), ArgLocs, *DAG.getContext());
3468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32);
3478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  const unsigned StackOffset = 92;
3498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
3518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    CCValAssign &VA = ArgLocs[i];
3528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (i == 0  && Ins[i].Flags.isSRet()) {
3548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      //Get SRet from [%fp+64]
3558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true);
3568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
3578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
3588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                MachinePointerInfo(),
3598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                false, false, false, 0);
3608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      InVals.push_back(Arg);
3618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      continue;
3628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
3638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (VA.isRegLoc()) {
3658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      if (VA.needsCustom()) {
3668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        assert(VA.getLocVT() == MVT::f64);
3678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
3688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi);
3698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32);
3708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        assert(i+1 < e);
3728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        CCValAssign &NextVA = ArgLocs[++i];
3738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
3748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        SDValue LoVal;
3758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        if (NextVA.isMemLoc()) {
3768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com          int FrameIdx = MF.getFrameInfo()->
3778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com            CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true);
3788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com          SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
3798cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com          LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
3808cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                              MachinePointerInfo(),
3818cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                              false, false, false, 0);
3828cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        } else {
3838cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com          unsigned loReg = MF.addLiveIn(NextVA.getLocReg(),
3848cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                        &SP::IntRegsRegClass);
3858cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com          LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32);
3868cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        }
3878cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        SDValue WholeValue =
3888cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com          DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
3898cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue);
3908cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        InVals.push_back(WholeValue);
3918cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        continue;
3928cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      }
3938cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
3948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg);
3958cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
3968cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      if (VA.getLocVT() == MVT::f32)
3978cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg);
3988cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      else if (VA.getLocVT() != MVT::i32) {
3998cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg,
4008cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          DAG.getValueType(VA.getLocVT()));
4018cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg);
4028cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      }
4038cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      InVals.push_back(Arg);
4048cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      continue;
4058cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
4068cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4078cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    assert(VA.isMemLoc());
4088cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4098cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Offset = VA.getLocMemOffset()+StackOffset;
4108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (VA.needsCustom()) {
4128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      assert(VA.getValVT() == MVT::f64);
4138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      //If it is double-word aligned, just load.
4148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      if (Offset % 8 == 0) {
4158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        int FI = MF.getFrameInfo()->CreateFixedObject(8,
4168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                      Offset,
4178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                      true);
4188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
4198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr,
4208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                   MachinePointerInfo(),
4218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                   false,false, false, 0);
4228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        InVals.push_back(Load);
4238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        continue;
4248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      }
4258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      int FI = MF.getFrameInfo()->CreateFixedObject(4,
4278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                    Offset,
4288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                    true);
4298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
4308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
4318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                  MachinePointerInfo(),
4328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                  false, false, false, 0);
4338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      int FI2 = MF.getFrameInfo()->CreateFixedObject(4,
4348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                     Offset+4,
4358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                     true);
4368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue FIPtr2 = DAG.getFrameIndex(FI2, getPointerTy());
4378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr2,
4398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                  MachinePointerInfo(),
4408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                  false, false, false, 0);
4418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue WholeValue =
4438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
4448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue);
4458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      InVals.push_back(WholeValue);
4468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      continue;
4478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
4488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    int FI = MF.getFrameInfo()->CreateFixedObject(4,
4508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                  Offset,
4518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                  true);
4528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
4538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue Load ;
4548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) {
4558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr,
4568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                         MachinePointerInfo(),
4578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                         false, false, false, 0);
4588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    } else {
4598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
4608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // Sparc is big endian, so add an offset based on the ObjectVT.
4618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      unsigned Offset = 4-std::max(1U, VA.getValVT().getSizeInBits()/8);
4628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr,
4638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          DAG.getConstant(Offset, MVT::i32));
4648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr,
4658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                            MachinePointerInfo(),
4668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                            VA.getValVT(), false, false,0);
4678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      Load = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Load);
4688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
4698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    InVals.push_back(Load);
4708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
4718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (MF.getFunction()->hasStructRetAttr()) {
4738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    //Copy the SRet Argument to SRetReturnReg
4748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>();
4758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Reg = SFI->getSRetReturnReg();
4768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (!Reg) {
4778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass);
4788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SFI->setSRetReturnReg(Reg);
4798cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
4808cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]);
4818cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
4828cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
4838cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4848cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Store remaining ArgRegs to the stack if this is a varargs function.
4858cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (isVarArg) {
4868cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    static const uint16_t ArgRegs[] = {
4878cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
4888cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    };
4898cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs, 6);
4908cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    const uint16_t *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6;
4918cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned ArgOffset = CCInfo.getNextStackOffset();
4928cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (NumAllocated == 6)
4938cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      ArgOffset += StackOffset;
4948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    else {
4958cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      assert(!ArgOffset);
4968cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      ArgOffset = 68+4*NumAllocated;
4978cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
4988cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
4998cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Remember the vararg offset for the va_start implementation.
5008cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    FuncInfo->setVarArgsFrameOffset(ArgOffset);
5018cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5028cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    std::vector<SDValue> OutChains;
5038cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5048cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
5058cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
5068cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
5078cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32);
5088cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5098cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset,
5108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                                          true);
5118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
5128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr,
5148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                       MachinePointerInfo(),
5158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                       false, false, 0));
5168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      ArgOffset += 4;
5178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
5188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (!OutChains.empty()) {
5208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      OutChains.push_back(Chain);
5218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          &OutChains[0], OutChains.size());
5238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
5248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
5258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return Chain;
5278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
5288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Lower formal arguments for the 64 bit ABI.
5308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue SparcTargetLowering::
5318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comLowerFormalArguments_64(SDValue Chain,
5328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        CallingConv::ID CallConv,
5338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        bool IsVarArg,
5348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        const SmallVectorImpl<ISD::InputArg> &Ins,
5358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        DebugLoc DL,
5368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        SelectionDAG &DAG,
5378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                        SmallVectorImpl<SDValue> &InVals) const {
5388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  MachineFunction &MF = DAG.getMachineFunction();
5398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Analyze arguments according to CC_Sparc64.
5418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<CCValAssign, 16> ArgLocs;
5428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
5438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                 getTargetMachine(), ArgLocs, *DAG.getContext());
5448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64);
5458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
5478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    CCValAssign &VA = ArgLocs[i];
5488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (VA.isRegLoc()) {
5498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // This argument is passed in a register.
5508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // All integer register arguments are promoted by the caller to i64.
5518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // Create a virtual register for the promoted live-in value.
5538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      unsigned VReg = MF.addLiveIn(VA.getLocReg(),
5548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                   getRegClassFor(VA.getLocVT()));
5558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
5568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // Get the high bits for i32 struct elements.
5588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      if (VA.getValVT() == MVT::i32 && VA.needsCustom())
5598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg,
5608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          DAG.getConstant(32, MVT::i32));
5618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // The caller promoted the argument, so insert an Assert?ext SDNode so we
5638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // won't promote the value again in this function.
5648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      switch (VA.getLocInfo()) {
5658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      case CCValAssign::SExt:
5668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
5678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          DAG.getValueType(VA.getValVT()));
5688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        break;
5698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      case CCValAssign::ZExt:
5708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
5718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          DAG.getValueType(VA.getValVT()));
5728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        break;
5738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      default:
5748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        break;
5758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      }
5768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      // Truncate the register down to the argument type.
5788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      if (VA.isExtInLoc())
5798cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
5808cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5818cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      InVals.push_back(Arg);
5828cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      continue;
5838cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    }
5848cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
5858cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // The registers are exhausted. This argument was passed on the stack.
5868cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    assert(VA.isMemLoc());
5878cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // The CC_Sparc64_Full/Half functions compute stack offsets relative to the
5888cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // beginning of the arguments area at %fp+BIAS+128.
5898cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Offset = VA.getLocMemOffset() + 128;
5908cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned ValSize = VA.getValVT().getSizeInBits() / 8;
5918cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // Adjust offset for extended arguments, SPARC is big-endian.
5928cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // The caller will have written the full slot with extended bytes, but we
5938cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    // prefer our own extending loads.
5948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (VA.isExtInLoc())
5958cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      Offset += 8 - ValSize;
5968cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true);
5978cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain,
5988cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 DAG.getFrameIndex(FI, getPointerTy()),
5998cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 MachinePointerInfo::getFixedStack(FI),
6008cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                 false, false, false, 0));
6018cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
6028cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return Chain;
6038cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
6048cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6058cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue
6068cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
6078cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                               SmallVectorImpl<SDValue> &InVals) const {
6088cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  if (Subtarget->is64Bit())
6098cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    return LowerCall_64(CLI, InVals);
6108cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  return LowerCall_32(CLI, InVals);
6118cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com}
6128cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6138cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com// Lower a call for the 32-bit ABI.
6148cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSDValue
6158cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comSparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
6168cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                                  SmallVectorImpl<SDValue> &InVals) const {
6178cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SelectionDAG &DAG                     = CLI.DAG;
6188cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  DebugLoc &dl                          = CLI.DL;
6198cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
6208cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
6218cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
6228cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SDValue Chain                         = CLI.Chain;
6238cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SDValue Callee                        = CLI.Callee;
6248cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  bool &isTailCall                      = CLI.IsTailCall;
6258cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CallingConv::ID CallConv              = CLI.CallConv;
6268cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  bool isVarArg                         = CLI.IsVarArg;
6278cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6288cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Sparc target does not yet support tail call optimization.
6298cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  isTailCall = false;
6308cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6318cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Analyze operands of the call, assigning locations to each operand.
6328cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<CCValAssign, 16> ArgLocs;
6338cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
6348cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                 DAG.getTarget(), ArgLocs, *DAG.getContext());
6358cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32);
6368cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6378cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Get the size of the outgoing arguments stack space requirement.
6388cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  unsigned ArgsSize = CCInfo.getNextStackOffset();
6398cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Keep stack frames 8-byte aligned.
6418cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  ArgsSize = (ArgsSize+7) & ~7;
6428cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6438cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
6448cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6458cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  //Create local copies for byval args.
6468cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<SDValue, 8> ByValArgs;
6478cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  for (unsigned i = 0,  e = Outs.size(); i != e; ++i) {
6488cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    ISD::ArgFlagsTy Flags = Outs[i].Flags;
6498cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    if (!Flags.isByVal())
6508cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com      continue;
6518cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6528cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue Arg = OutVals[i];
6538cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Size = Flags.getByValSize();
6548cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    unsigned Align = Flags.getByValAlign();
6558cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6568cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    int FI = MFI->CreateStackObject(Size, Align, false);
6578cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
6588cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    SDValue SizeNode = DAG.getConstant(Size, MVT::i32);
6598cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6608cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Align,
6618cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          false,        //isVolatile,
6628cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          (Size <= 32), //AlwaysInline if size <= 32
6638cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com                          MachinePointerInfo(), MachinePointerInfo());
6648cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    ByValArgs.push_back(FIPtr);
6658cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  }
6668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true));
6688cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6698cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
6708cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  SmallVector<SDValue, 8> MemOpChains;
6718cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com
6728cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  const unsigned StackOffset = 92;
6738cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  bool hasStructRetAttr = false;
6748cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  // Walk the register/memloc assignments, inserting copies/loads.
6758cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com  for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size();
6768cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com       i != e;
6778cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com       ++i, ++realArgIdx) {
6788cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com    CCValAssign &VA = ArgLocs[i];
679    SDValue Arg = OutVals[realArgIdx];
680
681    ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
682
683    //Use local copy if it is a byval arg.
684    if (Flags.isByVal())
685      Arg = ByValArgs[byvalArgIdx++];
686
687    // Promote the value if needed.
688    switch (VA.getLocInfo()) {
689    default: llvm_unreachable("Unknown loc info!");
690    case CCValAssign::Full: break;
691    case CCValAssign::SExt:
692      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
693      break;
694    case CCValAssign::ZExt:
695      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
696      break;
697    case CCValAssign::AExt:
698      Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
699      break;
700    case CCValAssign::BCvt:
701      Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
702      break;
703    }
704
705    if (Flags.isSRet()) {
706      assert(VA.needsCustom());
707      // store SRet argument in %sp+64
708      SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
709      SDValue PtrOff = DAG.getIntPtrConstant(64);
710      PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
711      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
712                                         MachinePointerInfo(),
713                                         false, false, 0));
714      hasStructRetAttr = true;
715      continue;
716    }
717
718    if (VA.needsCustom()) {
719      assert(VA.getLocVT() == MVT::f64);
720
721      if (VA.isMemLoc()) {
722        unsigned Offset = VA.getLocMemOffset() + StackOffset;
723        //if it is double-word aligned, just store.
724        if (Offset % 8 == 0) {
725          SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
726          SDValue PtrOff = DAG.getIntPtrConstant(Offset);
727          PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
728          MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
729                                             MachinePointerInfo(),
730                                             false, false, 0));
731          continue;
732        }
733      }
734
735      SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
736      SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
737                                   Arg, StackPtr, MachinePointerInfo(),
738                                   false, false, 0);
739      // Sparc is big-endian, so the high part comes first.
740      SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr,
741                               MachinePointerInfo(), false, false, false, 0);
742      // Increment the pointer to the other half.
743      StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
744                             DAG.getIntPtrConstant(4));
745      // Load the low part.
746      SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr,
747                               MachinePointerInfo(), false, false, false, 0);
748
749      if (VA.isRegLoc()) {
750        RegsToPass.push_back(std::make_pair(VA.getLocReg(), Hi));
751        assert(i+1 != e);
752        CCValAssign &NextVA = ArgLocs[++i];
753        if (NextVA.isRegLoc()) {
754          RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Lo));
755        } else {
756          //Store the low part in stack.
757          unsigned Offset = NextVA.getLocMemOffset() + StackOffset;
758          SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
759          SDValue PtrOff = DAG.getIntPtrConstant(Offset);
760          PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
761          MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff,
762                                             MachinePointerInfo(),
763                                             false, false, 0));
764        }
765      } else {
766        unsigned Offset = VA.getLocMemOffset() + StackOffset;
767        // Store the high part.
768        SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
769        SDValue PtrOff = DAG.getIntPtrConstant(Offset);
770        PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
771        MemOpChains.push_back(DAG.getStore(Chain, dl, Hi, PtrOff,
772                                           MachinePointerInfo(),
773                                           false, false, 0));
774        // Store the low part.
775        PtrOff = DAG.getIntPtrConstant(Offset+4);
776        PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
777        MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff,
778                                           MachinePointerInfo(),
779                                           false, false, 0));
780      }
781      continue;
782    }
783
784    // Arguments that can be passed on register must be kept at
785    // RegsToPass vector
786    if (VA.isRegLoc()) {
787      if (VA.getLocVT() != MVT::f32) {
788        RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
789        continue;
790      }
791      Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
792      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
793      continue;
794    }
795
796    assert(VA.isMemLoc());
797
798    // Create a store off the stack pointer for this argument.
799    SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
800    SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+StackOffset);
801    PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
802    MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
803                                       MachinePointerInfo(),
804                                       false, false, 0));
805  }
806
807
808  // Emit all stores, make sure the occur before any copies into physregs.
809  if (!MemOpChains.empty())
810    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
811                        &MemOpChains[0], MemOpChains.size());
812
813  // Build a sequence of copy-to-reg nodes chained together with token
814  // chain and flag operands which copy the outgoing args into registers.
815  // The InFlag in necessary since all emitted instructions must be
816  // stuck together.
817  SDValue InFlag;
818  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
819    unsigned Reg = toCallerWindow(RegsToPass[i].first);
820    Chain = DAG.getCopyToReg(Chain, dl, Reg, RegsToPass[i].second, InFlag);
821    InFlag = Chain.getValue(1);
822  }
823
824  unsigned SRetArgSize = (hasStructRetAttr)? getSRetArgSize(DAG, Callee):0;
825
826  // If the callee is a GlobalAddress node (quite common, every direct call is)
827  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
828  // Likewise ExternalSymbol -> TargetExternalSymbol.
829  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
830    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
831  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
832    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
833
834  // Returns a chain & a flag for retval copy to use
835  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
836  SmallVector<SDValue, 8> Ops;
837  Ops.push_back(Chain);
838  Ops.push_back(Callee);
839  if (hasStructRetAttr)
840    Ops.push_back(DAG.getTargetConstant(SRetArgSize, MVT::i32));
841  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
842    Ops.push_back(DAG.getRegister(toCallerWindow(RegsToPass[i].first),
843                                  RegsToPass[i].second.getValueType()));
844  if (InFlag.getNode())
845    Ops.push_back(InFlag);
846
847  Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
848  InFlag = Chain.getValue(1);
849
850  Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true),
851                             DAG.getIntPtrConstant(0, true), InFlag);
852  InFlag = Chain.getValue(1);
853
854  // Assign locations to each value returned by this call.
855  SmallVector<CCValAssign, 16> RVLocs;
856  CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(),
857                 DAG.getTarget(), RVLocs, *DAG.getContext());
858
859  RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32);
860
861  // Copy all of the result registers out of their specified physreg.
862  for (unsigned i = 0; i != RVLocs.size(); ++i) {
863    Chain = DAG.getCopyFromReg(Chain, dl, toCallerWindow(RVLocs[i].getLocReg()),
864                               RVLocs[i].getValVT(), InFlag).getValue(1);
865    InFlag = Chain.getValue(2);
866    InVals.push_back(Chain.getValue(0));
867  }
868
869  return Chain;
870}
871
872unsigned
873SparcTargetLowering::getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const
874{
875  const Function *CalleeFn = 0;
876  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
877    CalleeFn = dyn_cast<Function>(G->getGlobal());
878  } else if (ExternalSymbolSDNode *E =
879             dyn_cast<ExternalSymbolSDNode>(Callee)) {
880    const Function *Fn = DAG.getMachineFunction().getFunction();
881    const Module *M = Fn->getParent();
882    CalleeFn = M->getFunction(E->getSymbol());
883  }
884
885  if (!CalleeFn)
886    return 0;
887
888  assert(CalleeFn->hasStructRetAttr() &&
889         "Callee does not have the StructRet attribute.");
890
891  PointerType *Ty = cast<PointerType>(CalleeFn->arg_begin()->getType());
892  Type *ElementTy = Ty->getElementType();
893  return getDataLayout()->getTypeAllocSize(ElementTy);
894}
895
896// Lower a call for the 64-bit ABI.
897SDValue
898SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
899                                  SmallVectorImpl<SDValue> &InVals) const {
900  SelectionDAG &DAG = CLI.DAG;
901  DebugLoc DL = CLI.DL;
902  SDValue Chain = CLI.Chain;
903
904  // Analyze operands of the call, assigning locations to each operand.
905  SmallVector<CCValAssign, 16> ArgLocs;
906  CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
907                 DAG.getTarget(), ArgLocs, *DAG.getContext());
908  CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64);
909
910  // Get the size of the outgoing arguments stack space requirement.
911  // The stack offset computed by CC_Sparc64 includes all arguments.
912  // Called functions expect 6 argument words to exist in the stack frame, used
913  // or not.
914  unsigned ArgsSize = std::max(6*8u, CCInfo.getNextStackOffset());
915
916  // Keep stack frames 16-byte aligned.
917  ArgsSize = RoundUpToAlignment(ArgsSize, 16);
918
919  // Adjust the stack pointer to make room for the arguments.
920  // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
921  // with more than 6 arguments.
922  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true));
923
924  // Collect the set of registers to pass to the function and their values.
925  // This will be emitted as a sequence of CopyToReg nodes glued to the call
926  // instruction.
927  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
928
929  // Collect chains from all the memory opeations that copy arguments to the
930  // stack. They must follow the stack pointer adjustment above and precede the
931  // call instruction itself.
932  SmallVector<SDValue, 8> MemOpChains;
933
934  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
935    const CCValAssign &VA = ArgLocs[i];
936    SDValue Arg = CLI.OutVals[i];
937
938    // Promote the value if needed.
939    switch (VA.getLocInfo()) {
940    default:
941      llvm_unreachable("Unknown location info!");
942    case CCValAssign::Full:
943      break;
944    case CCValAssign::SExt:
945      Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
946      break;
947    case CCValAssign::ZExt:
948      Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
949      break;
950    case CCValAssign::AExt:
951      Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
952      break;
953    case CCValAssign::BCvt:
954      Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
955      break;
956    }
957
958    if (VA.isRegLoc()) {
959      // The custom bit on an i32 return value indicates that it should be
960      // passed in the high bits of the register.
961      if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
962        Arg = DAG.getNode(ISD::SHL, DL, MVT::i64, Arg,
963                          DAG.getConstant(32, MVT::i32));
964
965        // The next value may go in the low bits of the same register.
966        // Handle both at once.
967        if (i+1 < ArgLocs.size() && ArgLocs[i+1].isRegLoc() &&
968            ArgLocs[i+1].getLocReg() == VA.getLocReg()) {
969          SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64,
970                                   CLI.OutVals[i+1]);
971          Arg = DAG.getNode(ISD::OR, DL, MVT::i64, Arg, NV);
972          // Skip the next value, it's already done.
973          ++i;
974        }
975      }
976      RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()), Arg));
977      continue;
978    }
979
980    assert(VA.isMemLoc());
981
982    // Create a store off the stack pointer for this argument.
983    SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy());
984    // The argument area starts at %fp+BIAS+128 in the callee frame,
985    // %sp+BIAS+128 in ours.
986    SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() +
987                                           Subtarget->getStackPointerBias() +
988                                           128);
989    PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, PtrOff);
990    MemOpChains.push_back(DAG.getStore(Chain, DL, Arg, PtrOff,
991                                       MachinePointerInfo(),
992                                       false, false, 0));
993  }
994
995  // Emit all stores, make sure they occur before the call.
996  if (!MemOpChains.empty())
997    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
998                        &MemOpChains[0], MemOpChains.size());
999
1000  // Build a sequence of CopyToReg nodes glued together with token chain and
1001  // glue operands which copy the outgoing args into registers. The InGlue is
1002  // necessary since all emitted instructions must be stuck together in order
1003  // to pass the live physical registers.
1004  SDValue InGlue;
1005  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1006    Chain = DAG.getCopyToReg(Chain, DL,
1007                             RegsToPass[i].first, RegsToPass[i].second, InGlue);
1008    InGlue = Chain.getValue(1);
1009  }
1010
1011  // If the callee is a GlobalAddress node (quite common, every direct call is)
1012  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1013  // Likewise ExternalSymbol -> TargetExternalSymbol.
1014  SDValue Callee = CLI.Callee;
1015  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1016    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy());
1017  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
1018    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
1019
1020  // Build the operands for the call instruction itself.
1021  SmallVector<SDValue, 8> Ops;
1022  Ops.push_back(Chain);
1023  Ops.push_back(Callee);
1024  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1025    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1026                                  RegsToPass[i].second.getValueType()));
1027
1028  // Make sure the CopyToReg nodes are glued to the call instruction which
1029  // consumes the registers.
1030  if (InGlue.getNode())
1031    Ops.push_back(InGlue);
1032
1033  // Now the call itself.
1034  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1035  Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, &Ops[0], Ops.size());
1036  InGlue = Chain.getValue(1);
1037
1038  // Revert the stack pointer immediately after the call.
1039  Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true),
1040                             DAG.getIntPtrConstant(0, true), InGlue);
1041  InGlue = Chain.getValue(1);
1042
1043  // Now extract the return values. This is more or less the same as
1044  // LowerFormalArguments_64.
1045
1046  // Assign locations to each value returned by this call.
1047  SmallVector<CCValAssign, 16> RVLocs;
1048  CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
1049                 DAG.getTarget(), RVLocs, *DAG.getContext());
1050  RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64);
1051
1052  // Copy all of the result registers out of their specified physreg.
1053  for (unsigned i = 0; i != RVLocs.size(); ++i) {
1054    CCValAssign &VA = RVLocs[i];
1055    unsigned Reg = toCallerWindow(VA.getLocReg());
1056
1057    // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
1058    // reside in the same register in the high and low bits. Reuse the
1059    // CopyFromReg previous node to avoid duplicate copies.
1060    SDValue RV;
1061    if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1)))
1062      if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg)
1063        RV = Chain.getValue(0);
1064
1065    // But usually we'll create a new CopyFromReg for a different register.
1066    if (!RV.getNode()) {
1067      RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue);
1068      Chain = RV.getValue(1);
1069      InGlue = Chain.getValue(2);
1070    }
1071
1072    // Get the high bits for i32 struct elements.
1073    if (VA.getValVT() == MVT::i32 && VA.needsCustom())
1074      RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV,
1075                       DAG.getConstant(32, MVT::i32));
1076
1077    // The callee promoted the return value, so insert an Assert?ext SDNode so
1078    // we won't promote the value again in this function.
1079    switch (VA.getLocInfo()) {
1080    case CCValAssign::SExt:
1081      RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV,
1082                       DAG.getValueType(VA.getValVT()));
1083      break;
1084    case CCValAssign::ZExt:
1085      RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV,
1086                       DAG.getValueType(VA.getValVT()));
1087      break;
1088    default:
1089      break;
1090    }
1091
1092    // Truncate the register down to the return value type.
1093    if (VA.isExtInLoc())
1094      RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV);
1095
1096    InVals.push_back(RV);
1097  }
1098
1099  return Chain;
1100}
1101
1102//===----------------------------------------------------------------------===//
1103// TargetLowering Implementation
1104//===----------------------------------------------------------------------===//
1105
1106/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC
1107/// condition.
1108static SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
1109  switch (CC) {
1110  default: llvm_unreachable("Unknown integer condition code!");
1111  case ISD::SETEQ:  return SPCC::ICC_E;
1112  case ISD::SETNE:  return SPCC::ICC_NE;
1113  case ISD::SETLT:  return SPCC::ICC_L;
1114  case ISD::SETGT:  return SPCC::ICC_G;
1115  case ISD::SETLE:  return SPCC::ICC_LE;
1116  case ISD::SETGE:  return SPCC::ICC_GE;
1117  case ISD::SETULT: return SPCC::ICC_CS;
1118  case ISD::SETULE: return SPCC::ICC_LEU;
1119  case ISD::SETUGT: return SPCC::ICC_GU;
1120  case ISD::SETUGE: return SPCC::ICC_CC;
1121  }
1122}
1123
1124/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC
1125/// FCC condition.
1126static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
1127  switch (CC) {
1128  default: llvm_unreachable("Unknown fp condition code!");
1129  case ISD::SETEQ:
1130  case ISD::SETOEQ: return SPCC::FCC_E;
1131  case ISD::SETNE:
1132  case ISD::SETUNE: return SPCC::FCC_NE;
1133  case ISD::SETLT:
1134  case ISD::SETOLT: return SPCC::FCC_L;
1135  case ISD::SETGT:
1136  case ISD::SETOGT: return SPCC::FCC_G;
1137  case ISD::SETLE:
1138  case ISD::SETOLE: return SPCC::FCC_LE;
1139  case ISD::SETGE:
1140  case ISD::SETOGE: return SPCC::FCC_GE;
1141  case ISD::SETULT: return SPCC::FCC_UL;
1142  case ISD::SETULE: return SPCC::FCC_ULE;
1143  case ISD::SETUGT: return SPCC::FCC_UG;
1144  case ISD::SETUGE: return SPCC::FCC_UGE;
1145  case ISD::SETUO:  return SPCC::FCC_U;
1146  case ISD::SETO:   return SPCC::FCC_O;
1147  case ISD::SETONE: return SPCC::FCC_LG;
1148  case ISD::SETUEQ: return SPCC::FCC_UE;
1149  }
1150}
1151
1152SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
1153  : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
1154  Subtarget = &TM.getSubtarget<SparcSubtarget>();
1155
1156  // Set up the register classes.
1157  addRegisterClass(MVT::i32, &SP::IntRegsRegClass);
1158  addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
1159  addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
1160  if (Subtarget->is64Bit())
1161    addRegisterClass(MVT::i64, &SP::I64RegsRegClass);
1162
1163  // Turn FP extload into load/fextend
1164  setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
1165  // Sparc doesn't have i1 sign extending load
1166  setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
1167  // Turn FP truncstore into trunc + store.
1168  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
1169
1170  // Custom legalize GlobalAddress nodes into LO/HI parts.
1171  setOperationAction(ISD::GlobalAddress, getPointerTy(), Custom);
1172  setOperationAction(ISD::GlobalTLSAddress, getPointerTy(), Custom);
1173  setOperationAction(ISD::ConstantPool, getPointerTy(), Custom);
1174
1175  // Sparc doesn't have sext_inreg, replace them with shl/sra
1176  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
1177  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
1178  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
1179
1180  // Sparc has no REM or DIVREM operations.
1181  setOperationAction(ISD::UREM, MVT::i32, Expand);
1182  setOperationAction(ISD::SREM, MVT::i32, Expand);
1183  setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
1184  setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
1185
1186  // Custom expand fp<->sint
1187  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
1188  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
1189
1190  // Expand fp<->uint
1191  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
1192  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
1193
1194  setOperationAction(ISD::BITCAST, MVT::f32, Expand);
1195  setOperationAction(ISD::BITCAST, MVT::i32, Expand);
1196
1197  // Sparc has no select or setcc: expand to SELECT_CC.
1198  setOperationAction(ISD::SELECT, MVT::i32, Expand);
1199  setOperationAction(ISD::SELECT, MVT::f32, Expand);
1200  setOperationAction(ISD::SELECT, MVT::f64, Expand);
1201  setOperationAction(ISD::SETCC, MVT::i32, Expand);
1202  setOperationAction(ISD::SETCC, MVT::f32, Expand);
1203  setOperationAction(ISD::SETCC, MVT::f64, Expand);
1204
1205  // Sparc doesn't have BRCOND either, it has BR_CC.
1206  setOperationAction(ISD::BRCOND, MVT::Other, Expand);
1207  setOperationAction(ISD::BRIND, MVT::Other, Expand);
1208  setOperationAction(ISD::BR_JT, MVT::Other, Expand);
1209  setOperationAction(ISD::BR_CC, MVT::i32, Custom);
1210  setOperationAction(ISD::BR_CC, MVT::f32, Custom);
1211  setOperationAction(ISD::BR_CC, MVT::f64, Custom);
1212
1213  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
1214  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
1215  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
1216
1217  if (Subtarget->is64Bit()) {
1218    setOperationAction(ISD::BR_CC, MVT::i64, Custom);
1219    setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
1220  }
1221
1222  // FIXME: There are instructions available for ATOMIC_FENCE
1223  // on SparcV8 and later.
1224  setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
1225  setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
1226
1227  setOperationAction(ISD::FSIN , MVT::f64, Expand);
1228  setOperationAction(ISD::FCOS , MVT::f64, Expand);
1229  setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
1230  setOperationAction(ISD::FREM , MVT::f64, Expand);
1231  setOperationAction(ISD::FMA  , MVT::f64, Expand);
1232  setOperationAction(ISD::FSIN , MVT::f32, Expand);
1233  setOperationAction(ISD::FCOS , MVT::f32, Expand);
1234  setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
1235  setOperationAction(ISD::FREM , MVT::f32, Expand);
1236  setOperationAction(ISD::FMA  , MVT::f32, Expand);
1237  setOperationAction(ISD::CTPOP, MVT::i32, Expand);
1238  setOperationAction(ISD::CTTZ , MVT::i32, Expand);
1239  setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
1240  setOperationAction(ISD::CTLZ , MVT::i32, Expand);
1241  setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
1242  setOperationAction(ISD::ROTL , MVT::i32, Expand);
1243  setOperationAction(ISD::ROTR , MVT::i32, Expand);
1244  setOperationAction(ISD::BSWAP, MVT::i32, Expand);
1245  setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
1246  setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
1247  setOperationAction(ISD::FPOW , MVT::f64, Expand);
1248  setOperationAction(ISD::FPOW , MVT::f32, Expand);
1249
1250  setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
1251  setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
1252  setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
1253
1254  // FIXME: Sparc provides these multiplies, but we don't have them yet.
1255  setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
1256  setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
1257
1258  setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
1259
1260  // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
1261  setOperationAction(ISD::VASTART           , MVT::Other, Custom);
1262  // VAARG needs to be lowered to not do unaligned accesses for doubles.
1263  setOperationAction(ISD::VAARG             , MVT::Other, Custom);
1264
1265  // Use the default implementation.
1266  setOperationAction(ISD::VACOPY            , MVT::Other, Expand);
1267  setOperationAction(ISD::VAEND             , MVT::Other, Expand);
1268  setOperationAction(ISD::STACKSAVE         , MVT::Other, Expand);
1269  setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
1270  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
1271
1272  // No debug info support yet.
1273  setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
1274
1275  setStackPointerRegisterToSaveRestore(SP::O6);
1276
1277  if (TM.getSubtarget<SparcSubtarget>().isV9())
1278    setOperationAction(ISD::CTPOP, MVT::i32, Legal);
1279
1280  setMinFunctionAlignment(2);
1281
1282  computeRegisterProperties();
1283}
1284
1285const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
1286  switch (Opcode) {
1287  default: return 0;
1288  case SPISD::CMPICC:     return "SPISD::CMPICC";
1289  case SPISD::CMPFCC:     return "SPISD::CMPFCC";
1290  case SPISD::BRICC:      return "SPISD::BRICC";
1291  case SPISD::BRXCC:      return "SPISD::BRXCC";
1292  case SPISD::BRFCC:      return "SPISD::BRFCC";
1293  case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
1294  case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC";
1295  case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
1296  case SPISD::Hi:         return "SPISD::Hi";
1297  case SPISD::Lo:         return "SPISD::Lo";
1298  case SPISD::FTOI:       return "SPISD::FTOI";
1299  case SPISD::ITOF:       return "SPISD::ITOF";
1300  case SPISD::CALL:       return "SPISD::CALL";
1301  case SPISD::RET_FLAG:   return "SPISD::RET_FLAG";
1302  case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";
1303  case SPISD::FLUSHW:     return "SPISD::FLUSHW";
1304  }
1305}
1306
1307/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
1308/// be zero. Op is expected to be a target specific node. Used by DAG
1309/// combiner.
1310void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
1311                                                         APInt &KnownZero,
1312                                                         APInt &KnownOne,
1313                                                         const SelectionDAG &DAG,
1314                                                         unsigned Depth) const {
1315  APInt KnownZero2, KnownOne2;
1316  KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0);
1317
1318  switch (Op.getOpcode()) {
1319  default: break;
1320  case SPISD::SELECT_ICC:
1321  case SPISD::SELECT_XCC:
1322  case SPISD::SELECT_FCC:
1323    DAG.ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
1324    DAG.ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
1325    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
1326    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
1327
1328    // Only known if known in both the LHS and RHS.
1329    KnownOne &= KnownOne2;
1330    KnownZero &= KnownZero2;
1331    break;
1332  }
1333}
1334
1335// Look at LHS/RHS/CC and see if they are a lowered setcc instruction.  If so
1336// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
1337static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
1338                             ISD::CondCode CC, unsigned &SPCC) {
1339  if (isa<ConstantSDNode>(RHS) &&
1340      cast<ConstantSDNode>(RHS)->isNullValue() &&
1341      CC == ISD::SETNE &&
1342      (((LHS.getOpcode() == SPISD::SELECT_ICC ||
1343         LHS.getOpcode() == SPISD::SELECT_XCC) &&
1344        LHS.getOperand(3).getOpcode() == SPISD::CMPICC) ||
1345       (LHS.getOpcode() == SPISD::SELECT_FCC &&
1346        LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) &&
1347      isa<ConstantSDNode>(LHS.getOperand(0)) &&
1348      isa<ConstantSDNode>(LHS.getOperand(1)) &&
1349      cast<ConstantSDNode>(LHS.getOperand(0))->isOne() &&
1350      cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) {
1351    SDValue CMPCC = LHS.getOperand(3);
1352    SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
1353    LHS = CMPCC.getOperand(0);
1354    RHS = CMPCC.getOperand(1);
1355  }
1356}
1357
1358// Convert to a target node and set target flags.
1359SDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF,
1360                                             SelectionDAG &DAG) const {
1361  if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
1362    return DAG.getTargetGlobalAddress(GA->getGlobal(),
1363                                      GA->getDebugLoc(),
1364                                      GA->getValueType(0),
1365                                      GA->getOffset(), TF);
1366
1367  if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op))
1368    return DAG.getTargetConstantPool(CP->getConstVal(),
1369                                     CP->getValueType(0),
1370                                     CP->getAlignment(),
1371                                     CP->getOffset(), TF);
1372
1373  if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op))
1374    return DAG.getTargetExternalSymbol(ES->getSymbol(),
1375                                       ES->getValueType(0), TF);
1376
1377  llvm_unreachable("Unhandled address SDNode");
1378}
1379
1380// Split Op into high and low parts according to HiTF and LoTF.
1381// Return an ADD node combining the parts.
1382SDValue SparcTargetLowering::makeHiLoPair(SDValue Op,
1383                                          unsigned HiTF, unsigned LoTF,
1384                                          SelectionDAG &DAG) const {
1385  DebugLoc DL = Op.getDebugLoc();
1386  EVT VT = Op.getValueType();
1387  SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
1388  SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
1389  return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
1390}
1391
1392// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
1393// or ExternalSymbol SDNode.
1394SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
1395  DebugLoc DL = Op.getDebugLoc();
1396  EVT VT = getPointerTy();
1397
1398  // Handle PIC mode first.
1399  if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
1400    // This is the pic32 code model, the GOT is known to be smaller than 4GB.
1401    SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
1402    SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
1403    SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
1404    return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr,
1405                       MachinePointerInfo::getGOT(), false, false, false, 0);
1406  }
1407
1408  // This is one of the absolute code models.
1409  switch(getTargetMachine().getCodeModel()) {
1410  default:
1411    llvm_unreachable("Unsupported absolute code model");
1412  case CodeModel::Small:
1413    return makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
1414  case CodeModel::Medium: {
1415    SDValue H44 = makeHiLoPair(Op, SPII::MO_H44, SPII::MO_M44, DAG);
1416    H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getIntPtrConstant(12));
1417    SDValue L44 = withTargetFlags(Op, SPII::MO_L44, DAG);
1418    L44 = DAG.getNode(SPISD::Lo, DL, VT, L44);
1419    return DAG.getNode(ISD::ADD, DL, VT, H44, L44);
1420  }
1421  }
1422}
1423
1424SDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op,
1425                                                SelectionDAG &DAG) const {
1426  return makeAddress(Op, DAG);
1427}
1428
1429SDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
1430                                               SelectionDAG &DAG) const {
1431  return makeAddress(Op, DAG);
1432}
1433
1434static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
1435  DebugLoc dl = Op.getDebugLoc();
1436  // Convert the fp value to integer in an FP register.
1437  assert(Op.getValueType() == MVT::i32);
1438  Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
1439  return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
1440}
1441
1442static SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
1443  DebugLoc dl = Op.getDebugLoc();
1444  assert(Op.getOperand(0).getValueType() == MVT::i32);
1445  SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Op.getOperand(0));
1446  // Convert the int value to FP in an FP register.
1447  return DAG.getNode(SPISD::ITOF, dl, Op.getValueType(), Tmp);
1448}
1449
1450static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
1451  SDValue Chain = Op.getOperand(0);
1452  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
1453  SDValue LHS = Op.getOperand(2);
1454  SDValue RHS = Op.getOperand(3);
1455  SDValue Dest = Op.getOperand(4);
1456  DebugLoc dl = Op.getDebugLoc();
1457  unsigned Opc, SPCC = ~0U;
1458
1459  // If this is a br_cc of a "setcc", and if the setcc got lowered into
1460  // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1461  LookThroughSetCC(LHS, RHS, CC, SPCC);
1462
1463  // Get the condition flag.
1464  SDValue CompareFlag;
1465  if (LHS.getValueType().isInteger()) {
1466    EVT VTs[] = { LHS.getValueType(), MVT::Glue };
1467    SDValue Ops[2] = { LHS, RHS };
1468    CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
1469    if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
1470    // 32-bit compares use the icc flags, 64-bit uses the xcc flags.
1471    Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC;
1472  } else {
1473    CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
1474    if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
1475    Opc = SPISD::BRFCC;
1476  }
1477  return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest,
1478                     DAG.getConstant(SPCC, MVT::i32), CompareFlag);
1479}
1480
1481static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
1482  SDValue LHS = Op.getOperand(0);
1483  SDValue RHS = Op.getOperand(1);
1484  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1485  SDValue TrueVal = Op.getOperand(2);
1486  SDValue FalseVal = Op.getOperand(3);
1487  DebugLoc dl = Op.getDebugLoc();
1488  unsigned Opc, SPCC = ~0U;
1489
1490  // If this is a select_cc of a "setcc", and if the setcc got lowered into
1491  // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1492  LookThroughSetCC(LHS, RHS, CC, SPCC);
1493
1494  SDValue CompareFlag;
1495  if (LHS.getValueType().isInteger()) {
1496    // subcc returns a value
1497    EVT VTs[] = { LHS.getValueType(), MVT::Glue };
1498    SDValue Ops[2] = { LHS, RHS };
1499    CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
1500    Opc = LHS.getValueType() == MVT::i32 ?
1501          SPISD::SELECT_ICC : SPISD::SELECT_XCC;
1502    if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
1503  } else {
1504    CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
1505    Opc = SPISD::SELECT_FCC;
1506    if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
1507  }
1508  return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
1509                     DAG.getConstant(SPCC, MVT::i32), CompareFlag);
1510}
1511
1512static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
1513                            const SparcTargetLowering &TLI) {
1514  MachineFunction &MF = DAG.getMachineFunction();
1515  SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
1516
1517  // vastart just stores the address of the VarArgsFrameIndex slot into the
1518  // memory location argument.
1519  DebugLoc dl = Op.getDebugLoc();
1520  SDValue Offset =
1521    DAG.getNode(ISD::ADD, dl, MVT::i32,
1522                DAG.getRegister(SP::I6, MVT::i32),
1523                DAG.getConstant(FuncInfo->getVarArgsFrameOffset(),
1524                                MVT::i32));
1525  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1526  return DAG.getStore(Op.getOperand(0), dl, Offset, Op.getOperand(1),
1527                      MachinePointerInfo(SV), false, false, 0);
1528}
1529
1530static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
1531  SDNode *Node = Op.getNode();
1532  EVT VT = Node->getValueType(0);
1533  SDValue InChain = Node->getOperand(0);
1534  SDValue VAListPtr = Node->getOperand(1);
1535  const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1536  DebugLoc dl = Node->getDebugLoc();
1537  SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr,
1538                               MachinePointerInfo(SV), false, false, false, 0);
1539  // Increment the pointer, VAList, to the next vaarg
1540  SDValue NextPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, VAList,
1541                                  DAG.getConstant(VT.getSizeInBits()/8,
1542                                                  MVT::i32));
1543  // Store the incremented VAList to the legalized pointer
1544  InChain = DAG.getStore(VAList.getValue(1), dl, NextPtr,
1545                         VAListPtr, MachinePointerInfo(SV), false, false, 0);
1546  // Load the actual argument out of the pointer VAList, unless this is an
1547  // f64 load.
1548  if (VT != MVT::f64)
1549    return DAG.getLoad(VT, dl, InChain, VAList, MachinePointerInfo(),
1550                       false, false, false, 0);
1551
1552  // Otherwise, load it as i64, then do a bitconvert.
1553  SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, MachinePointerInfo(),
1554                          false, false, false, 0);
1555
1556  // Bit-Convert the value to f64.
1557  SDValue Ops[2] = {
1558    DAG.getNode(ISD::BITCAST, dl, MVT::f64, V),
1559    V.getValue(1)
1560  };
1561  return DAG.getMergeValues(Ops, 2, dl);
1562}
1563
1564static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) {
1565  SDValue Chain = Op.getOperand(0);  // Legalize the chain.
1566  SDValue Size  = Op.getOperand(1);  // Legalize the size.
1567  DebugLoc dl = Op.getDebugLoc();
1568
1569  unsigned SPReg = SP::O6;
1570  SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, MVT::i32);
1571  SDValue NewSP = DAG.getNode(ISD::SUB, dl, MVT::i32, SP, Size); // Value
1572  Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);    // Output chain
1573
1574  // The resultant pointer is actually 16 words from the bottom of the stack,
1575  // to provide a register spill area.
1576  SDValue NewVal = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP,
1577                                 DAG.getConstant(96, MVT::i32));
1578  SDValue Ops[2] = { NewVal, Chain };
1579  return DAG.getMergeValues(Ops, 2, dl);
1580}
1581
1582
1583static SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) {
1584  DebugLoc dl = Op.getDebugLoc();
1585  SDValue Chain = DAG.getNode(SPISD::FLUSHW,
1586                              dl, MVT::Other, DAG.getEntryNode());
1587  return Chain;
1588}
1589
1590static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
1591  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
1592  MFI->setFrameAddressIsTaken(true);
1593
1594  EVT VT = Op.getValueType();
1595  DebugLoc dl = Op.getDebugLoc();
1596  unsigned FrameReg = SP::I6;
1597
1598  uint64_t depth = Op.getConstantOperandVal(0);
1599
1600  SDValue FrameAddr;
1601  if (depth == 0)
1602    FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1603  else {
1604    // flush first to make sure the windowed registers' values are in stack
1605    SDValue Chain = getFLUSHW(Op, DAG);
1606    FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
1607
1608    for (uint64_t i = 0; i != depth; ++i) {
1609      SDValue Ptr = DAG.getNode(ISD::ADD,
1610                                dl, MVT::i32,
1611                                FrameAddr, DAG.getIntPtrConstant(56));
1612      FrameAddr = DAG.getLoad(MVT::i32, dl,
1613                              Chain,
1614                              Ptr,
1615                              MachinePointerInfo(), false, false, false, 0);
1616    }
1617  }
1618  return FrameAddr;
1619}
1620
1621static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
1622  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
1623  MFI->setReturnAddressIsTaken(true);
1624
1625  EVT VT = Op.getValueType();
1626  DebugLoc dl = Op.getDebugLoc();
1627  unsigned RetReg = SP::I7;
1628
1629  uint64_t depth = Op.getConstantOperandVal(0);
1630
1631  SDValue RetAddr;
1632  if (depth == 0)
1633    RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
1634  else {
1635    // flush first to make sure the windowed registers' values are in stack
1636    SDValue Chain = getFLUSHW(Op, DAG);
1637    RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT);
1638
1639    for (uint64_t i = 0; i != depth; ++i) {
1640      SDValue Ptr = DAG.getNode(ISD::ADD,
1641                                dl, MVT::i32,
1642                                RetAddr,
1643                                DAG.getIntPtrConstant((i == depth-1)?60:56));
1644      RetAddr = DAG.getLoad(MVT::i32, dl,
1645                            Chain,
1646                            Ptr,
1647                            MachinePointerInfo(), false, false, false, 0);
1648    }
1649  }
1650  return RetAddr;
1651}
1652
1653SDValue SparcTargetLowering::
1654LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1655  switch (Op.getOpcode()) {
1656  default: llvm_unreachable("Should not custom lower this!");
1657  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
1658  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
1659  case ISD::GlobalTLSAddress:
1660    llvm_unreachable("TLS not implemented for Sparc.");
1661  case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
1662  case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
1663  case ISD::FP_TO_SINT:         return LowerFP_TO_SINT(Op, DAG);
1664  case ISD::SINT_TO_FP:         return LowerSINT_TO_FP(Op, DAG);
1665  case ISD::BR_CC:              return LowerBR_CC(Op, DAG);
1666  case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
1667  case ISD::VASTART:            return LowerVASTART(Op, DAG, *this);
1668  case ISD::VAARG:              return LowerVAARG(Op, DAG);
1669  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
1670  }
1671}
1672
1673MachineBasicBlock *
1674SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1675                                                 MachineBasicBlock *BB) const {
1676  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1677  unsigned BROpcode;
1678  unsigned CC;
1679  DebugLoc dl = MI->getDebugLoc();
1680  // Figure out the conditional branch opcode to use for this select_cc.
1681  switch (MI->getOpcode()) {
1682  default: llvm_unreachable("Unknown SELECT_CC!");
1683  case SP::SELECT_CC_Int_ICC:
1684  case SP::SELECT_CC_FP_ICC:
1685  case SP::SELECT_CC_DFP_ICC:
1686    BROpcode = SP::BCOND;
1687    break;
1688  case SP::SELECT_CC_Int_FCC:
1689  case SP::SELECT_CC_FP_FCC:
1690  case SP::SELECT_CC_DFP_FCC:
1691    BROpcode = SP::FBCOND;
1692    break;
1693  }
1694
1695  CC = (SPCC::CondCodes)MI->getOperand(3).getImm();
1696
1697  // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1698  // control-flow pattern.  The incoming instruction knows the destination vreg
1699  // to set, the condition code register to branch on, the true/false values to
1700  // select between, and a branch opcode to use.
1701  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1702  MachineFunction::iterator It = BB;
1703  ++It;
1704
1705  //  thisMBB:
1706  //  ...
1707  //   TrueVal = ...
1708  //   [f]bCC copy1MBB
1709  //   fallthrough --> copy0MBB
1710  MachineBasicBlock *thisMBB = BB;
1711  MachineFunction *F = BB->getParent();
1712  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1713  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1714  F->insert(It, copy0MBB);
1715  F->insert(It, sinkMBB);
1716
1717  // Transfer the remainder of BB and its successor edges to sinkMBB.
1718  sinkMBB->splice(sinkMBB->begin(), BB,
1719                  llvm::next(MachineBasicBlock::iterator(MI)),
1720                  BB->end());
1721  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
1722
1723  // Add the true and fallthrough blocks as its successors.
1724  BB->addSuccessor(copy0MBB);
1725  BB->addSuccessor(sinkMBB);
1726
1727  BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC);
1728
1729  //  copy0MBB:
1730  //   %FalseValue = ...
1731  //   # fallthrough to sinkMBB
1732  BB = copy0MBB;
1733
1734  // Update machine-CFG edges
1735  BB->addSuccessor(sinkMBB);
1736
1737  //  sinkMBB:
1738  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1739  //  ...
1740  BB = sinkMBB;
1741  BuildMI(*BB, BB->begin(), dl, TII.get(SP::PHI), MI->getOperand(0).getReg())
1742    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1743    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
1744
1745  MI->eraseFromParent();   // The pseudo instruction is gone now.
1746  return BB;
1747}
1748
1749//===----------------------------------------------------------------------===//
1750//                         Sparc Inline Assembly Support
1751//===----------------------------------------------------------------------===//
1752
1753/// getConstraintType - Given a constraint letter, return the type of
1754/// constraint it is for this target.
1755SparcTargetLowering::ConstraintType
1756SparcTargetLowering::getConstraintType(const std::string &Constraint) const {
1757  if (Constraint.size() == 1) {
1758    switch (Constraint[0]) {
1759    default:  break;
1760    case 'r': return C_RegisterClass;
1761    }
1762  }
1763
1764  return TargetLowering::getConstraintType(Constraint);
1765}
1766
1767std::pair<unsigned, const TargetRegisterClass*>
1768SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
1769                                                  EVT VT) const {
1770  if (Constraint.size() == 1) {
1771    switch (Constraint[0]) {
1772    case 'r':
1773      return std::make_pair(0U, &SP::IntRegsRegClass);
1774    }
1775  }
1776
1777  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
1778}
1779
1780bool
1781SparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
1782  // The Sparc target isn't yet aware of offsets.
1783  return false;
1784}
1785