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