SparcISelLowering.cpp revision 5b3fca50a08865f0db55fc92ad1c037a04e12177
1d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===//
2d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//
3d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//                     The LLVM Compiler Infrastructure
4d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//
5d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// This file is distributed under the University of Illinois Open Source
6d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// License. See LICENSE.TXT for details.
7d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//
8d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===//
9d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//
10d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// This file implements the interfaces that Sparc uses to lower LLVM code into a
11d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// selection DAG.
12d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//
13d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===//
14d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
15d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "SparcISelLowering.h"
161e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman#include "SparcMachineFunctionInfo.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "SparcTargetMachine.h"
180ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen#include "MCTargetDesc/SparcBaseInfo.h"
195a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner#include "llvm/CodeGen/CallingConvLower.h"
20d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineFrameInfo.h"
21d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineFunction.h"
22d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineInstrBuilder.h"
23d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h"
24d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner#include "llvm/CodeGen/SelectionDAG.h"
25362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
29c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
30d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattnerusing namespace llvm;
31d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
33d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===//
345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner// Calling Convention Implementation
35d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner//===----------------------------------------------------------------------===//
36d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
378184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindarajustatic bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT,
388184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
398184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                 ISD::ArgFlagsTy &ArgFlags, CCState &State)
408184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju{
418184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  assert (ArgFlags.isSRet());
428184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju
431e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju  // Assign SRet argument.
448184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
458184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                         0,
468184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                         LocVT, LocInfo));
478184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  return true;
488184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju}
498184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju
50687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindarajustatic bool CC_Sparc_Assign_f64(unsigned &ValNo, MVT &ValVT,
51687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                MVT &LocVT, CCValAssign::LocInfo &LocInfo,
52687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                ISD::ArgFlagsTy &ArgFlags, CCState &State)
53687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju{
54c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t RegList[] = {
55687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
56687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  };
571e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju  // Try to get first reg.
58687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  if (unsigned Reg = State.AllocateReg(RegList, 6)) {
59687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
60687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  } else {
611e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju    // Assign whole thing in stack.
62687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
63687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           State.AllocateStack(8,4),
64687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           LocVT, LocInfo));
65687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    return true;
66687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  }
67687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
681e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju  // Try to get second reg.
69687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  if (unsigned Reg = State.AllocateReg(RegList, 6))
70687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
71687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  else
72687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
73687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           State.AllocateStack(4,4),
74687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           LocVT, LocInfo));
75687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  return true;
76687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju}
77687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
781f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// Allocate a full-sized argument for the 64-bit ABI.
791f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesenstatic bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT,
801f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                            MVT &LocVT, CCValAssign::LocInfo &LocInfo,
811f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                            ISD::ArgFlagsTy &ArgFlags, CCState &State) {
821f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  assert((LocVT == MVT::f32 || LocVT.getSizeInBits() == 64) &&
831f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen         "Can't handle non-64 bits locations");
841f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
851f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  // Stack space is allocated for all arguments starting from [%fp+BIAS+128].
861f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  unsigned Offset = State.AllocateStack(8, 8);
871f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  unsigned Reg = 0;
881f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
891f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  if (LocVT == MVT::i64 && Offset < 6*8)
901f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Promote integers to %i0-%i5.
911f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    Reg = SP::I0 + Offset/8;
921f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  else if (LocVT == MVT::f64 && Offset < 16*8)
931f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Promote doubles to %d0-%d30. (Which LLVM calls D0-D15).
941f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    Reg = SP::D0 + Offset/8;
951f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  else if (LocVT == MVT::f32 && Offset < 16*8)
961f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Promote floats to %f1, %f3, ...
971f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    Reg = SP::F1 + Offset/4;
981f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
991f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  // Promote to register when possible, otherwise use the stack slot.
1001f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  if (Reg) {
1011f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
1021f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    return true;
1031f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  }
1041f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1051f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  // This argument goes on the stack in an 8-byte slot.
1061f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to
1071f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  // the right-aligned float. The first 4 bytes of the stack slot are undefined.
1081f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  if (LocVT == MVT::f32)
1091f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    Offset += 4;
1101f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1111f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
1121f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  return true;
1131f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen}
1141f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1151f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// Allocate a half-sized argument for the 64-bit ABI.
1161f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen//
1171f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen// This is used when passing { float, int } structs by value in registers.
1181f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesenstatic bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT,
1191f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                            MVT &LocVT, CCValAssign::LocInfo &LocInfo,
1201f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                            ISD::ArgFlagsTy &ArgFlags, CCState &State) {
1211f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations");
1221f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  unsigned Offset = State.AllocateStack(4, 4);
1231f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1241f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  if (LocVT == MVT::f32 && Offset < 16*8) {
1251f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Promote floats to %f0-%f31.
1261f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    State.addLoc(CCValAssign::getReg(ValNo, ValVT, SP::F0 + Offset/4,
1271f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                                     LocVT, LocInfo));
1281f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    return true;
1291f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  }
1301f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1311f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  if (LocVT == MVT::i32 && Offset < 6*8) {
1321f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Promote integers to %i0-%i5, using half the register.
1331f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    unsigned Reg = SP::I0 + Offset/8;
1341f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    LocVT = MVT::i64;
1351f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    LocInfo = CCValAssign::AExt;
1361f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1371f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Set the Custom bit if this i32 goes in the high bits of a register.
1381f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    if (Offset % 8 == 0)
1391f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen      State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg,
1401f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                                             LocVT, LocInfo));
1411f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    else
1421f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
1431f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    return true;
1441f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  }
1451f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1461f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
1471f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen  return true;
1481f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen}
1491f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
1505a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner#include "SparcGenCallingConv.inc"
151d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1521b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// The calling conventions in SparcCallingConv.td are described in terms of the
1531b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// callee's register window. This function translates registers to the
1541b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen// corresponding caller window %o register.
1551b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesenstatic unsigned toCallerWindow(unsigned Reg) {
1561b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen  assert(SP::I0 + 7 == SP::I7 && SP::O0 + 7 == SP::O7 && "Unexpected enum");
1571b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen  if (Reg >= SP::I0 && Reg <= SP::I7)
1581b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen    return Reg - SP::I0 + SP::O0;
1591b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen  return Reg;
1601b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen}
1611b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen
16298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
16398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSparcTargetLowering::LowerReturn(SDValue Chain,
16453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                 CallingConv::ID CallConv, bool IsVarArg,
16598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                 const SmallVectorImpl<ISD::OutputArg> &Outs,
166c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                 const SmallVectorImpl<SDValue> &OutVals,
167ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                 SDLoc DL, SelectionDAG &DAG) const {
16853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  if (Subtarget->is64Bit())
16953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    return LowerReturn_64(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
17053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  return LowerReturn_32(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
17153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen}
17298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
17353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSDValue
17453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSparcTargetLowering::LowerReturn_32(SDValue Chain,
17553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                    CallingConv::ID CallConv, bool IsVarArg,
17653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                    const SmallVectorImpl<ISD::OutputArg> &Outs,
17753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                    const SmallVectorImpl<SDValue> &OutVals,
178ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                    SDLoc DL, SelectionDAG &DAG) const {
1798184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  MachineFunction &MF = DAG.getMachineFunction();
1808184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju
1815a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // CCValAssign - represent the assignment of the return value to locations.
1825a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  SmallVector<CCValAssign, 16> RVLocs;
18353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1845a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // CCState - Info about the registers and stack slot.
18553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
18656cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 DAG.getTarget(), RVLocs, *DAG.getContext());
18753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
18853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // Analyze return values.
18953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32);
19053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
191475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Flag;
192067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
193067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen  // Make room for the return address offset.
194067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen  RetOps.push_back(SDValue());
195d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1965a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Copy the result values into the output registers.
1975a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  for (unsigned i = 0; i != RVLocs.size(); ++i) {
1985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    CCValAssign &VA = RVLocs[i];
1995a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    assert(VA.isRegLoc() && "Can only return in registers!");
20053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
20153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(),
202c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                             OutVals[i], Flag);
20353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
2045a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    // Guarantee that all emitted copies are stuck together with flags.
2055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    Flag = Chain.getValue(1);
206067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
207d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
20858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
2091e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju  unsigned RetAddrOffset = 8; // Call Inst + Delay Slot
2108184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  // If the function returns a struct, copy the SRetReturnReg to I0
2118184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  if (MF.getFunction()->hasStructRetAttr()) {
2128184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>();
2138184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    unsigned Reg = SFI->getSRetReturnReg();
2148184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    if (!Reg)
2158184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      llvm_unreachable("sret virtual register not created in the entry block");
21653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy());
21753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Flag);
2188184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    Flag = Chain.getValue(1);
219067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(SP::I0, getPointerTy()));
22058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    RetAddrOffset = 12; // CallInst + Delay Slot + Unimp
2218184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  }
22253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
223067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
224067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen  RetOps[1] = DAG.getConstant(RetAddrOffset, MVT::i32);
22558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
226067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen  // Add the flag if we have it.
227ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (Flag.getNode())
228067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen    RetOps.push_back(Flag);
229067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen
23053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other,
23153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                     &RetOps[0], RetOps.size());
23253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen}
23353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
23453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen// Lower return values for the 64-bit ABI.
23553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen// Return values are passed the exactly the same way as function arguments.
23653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSDValue
23753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund OlesenSparcTargetLowering::LowerReturn_64(SDValue Chain,
23853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                    CallingConv::ID CallConv, bool IsVarArg,
23953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                    const SmallVectorImpl<ISD::OutputArg> &Outs,
24053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                                    const SmallVectorImpl<SDValue> &OutVals,
241ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                    SDLoc DL, SelectionDAG &DAG) const {
24253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // CCValAssign - represent the assignment of the return value to locations.
24353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  SmallVector<CCValAssign, 16> RVLocs;
24453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
24553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // CCState - Info about the registers and stack slot.
24653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
24753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                 DAG.getTarget(), RVLocs, *DAG.getContext());
24853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
24953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // Analyze return values.
25053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  CCInfo.AnalyzeReturn(Outs, CC_Sparc64);
25153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
25253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  SDValue Flag;
25353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
25453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
25553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // The second operand on the return instruction is the return address offset.
25653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // The return address is always %i7+8 with the 64-bit ABI.
25753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  RetOps.push_back(DAG.getConstant(8, MVT::i32));
25853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
25953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // Copy the result values into the output registers.
26053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  for (unsigned i = 0; i != RVLocs.size(); ++i) {
26153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    CCValAssign &VA = RVLocs[i];
26253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    assert(VA.isRegLoc() && "Can only return in registers!");
26353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    SDValue OutVal = OutVals[i];
26453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
26553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    // Integer return values must be sign or zero extended by the callee.
26653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    switch (VA.getLocInfo()) {
26753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    case CCValAssign::SExt:
26853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
26953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      break;
27053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    case CCValAssign::ZExt:
27153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
27253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      break;
27353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    case CCValAssign::AExt:
27453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
27553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    default:
27653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      break;
27753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    }
27853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
27953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    // The custom bit on an i32 return value indicates that it should be passed
28053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    // in the high bits of the register.
28153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
28253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal,
28353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen                           DAG.getConstant(32, MVT::i32));
28453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
28553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      // The next value may go in the low bits of the same register.
28653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      // Handle both at once.
28753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) {
28853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen        SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]);
28953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen        OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV);
29053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen        // Skip the next value, it's already done.
29153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen        ++i;
29253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen      }
29353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    }
29453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
29553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag);
29653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
29753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    // Guarantee that all emitted copies are stuck together with flags.
29853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    Flag = Chain.getValue(1);
29953d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
30053d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  }
30153d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
30253d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
30353d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
30453d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  // Add the flag if we have it.
30553d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  if (Flag.getNode())
30653d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen    RetOps.push_back(Flag);
30753d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen
30853d4bcf35e7bc362e9340085264c2f4acd3c912bJakob Stoklund Olesen  return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other,
309067e5a2a1a3ed35bce7dc9e9b2eedee501db53c9Jakob Stoklund Olesen                     &RetOps[0], RetOps.size());
310d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
311d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
312f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering::
313f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments(SDValue Chain,
314f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                     CallingConv::ID CallConv,
315f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                     bool IsVarArg,
316f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                     const SmallVectorImpl<ISD::InputArg> &Ins,
317ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                     SDLoc DL,
318f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                     SelectionDAG &DAG,
319f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                     SmallVectorImpl<SDValue> &InVals) const {
320f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  if (Subtarget->is64Bit())
321f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen    return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins,
322f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                                   DL, DAG, InVals);
323f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins,
324f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                                 DL, DAG, InVals);
325f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen}
326f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
327f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are
32898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// passed in either one or two GPRs, including FP values.  TODO: we should
32998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// pass FP values in FP registers for fastcc functions.
330f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering::
331f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments_32(SDValue Chain,
332f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        CallingConv::ID CallConv,
333f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        bool isVarArg,
334f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        const SmallVectorImpl<ISD::InputArg> &Ins,
335ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                        SDLoc dl,
336f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        SelectionDAG &DAG,
337f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        SmallVectorImpl<SDValue> &InVals) const {
338d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  MachineFunction &MF = DAG.getMachineFunction();
339d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  MachineRegisterInfo &RegInfo = MF.getRegInfo();
3401e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
341a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman
342a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman  // Assign locations to all of the incoming arguments.
343a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman  SmallVector<CCValAssign, 16> ArgLocs;
344471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
34556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
34698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32);
34753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
348687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  const unsigned StackOffset = 92;
34953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
350a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
351a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman    CCValAssign &VA = ArgLocs[i];
35253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
3538184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    if (i == 0  && Ins[i].Flags.isSRet()) {
3541e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju      // Get SRet from [%fp+64].
3558184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true);
3568184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
3578184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
3588184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                MachinePointerInfo(),
359d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                false, false, false, 0);
3608184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      InVals.push_back(Arg);
3618184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      continue;
3628184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    }
3638184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju
364687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    if (VA.isRegLoc()) {
365687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      if (VA.needsCustom()) {
366687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        assert(VA.getLocVT() == MVT::f64);
367687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
368687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi);
369687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32);
370d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
371687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        assert(i+1 < e);
372687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        CCValAssign &NextVA = ArgLocs[++i];
37353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
374475871a144eb604ddaf37503397ba0941442e5fbDan Gohman        SDValue LoVal;
375687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        if (NextVA.isMemLoc()) {
376687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          int FrameIdx = MF.getFrameInfo()->
377687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju            CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true);
378825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
379687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
380687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                              MachinePointerInfo(),
381d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                              false, false, false, 0);
382687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        } else {
383687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          unsigned loReg = MF.addLiveIn(NextVA.getLocReg(),
38468e6beeccc0b9ac2e8d3687a8a5b7d4b172edca1Devang Patel                                        &SP::IntRegsRegClass);
385687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32);
386d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner        }
38753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov        SDValue WholeValue =
388825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
389687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue);
390687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        InVals.push_back(WholeValue);
391687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        continue;
392687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      }
393687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
394687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg);
395687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
396687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      if (VA.getLocVT() == MVT::f32)
397687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg);
398687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      else if (VA.getLocVT() != MVT::i32) {
399687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg,
400687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                          DAG.getValueType(VA.getLocVT()));
401687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg);
402687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      }
403687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      InVals.push_back(Arg);
404687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      continue;
405687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    }
40653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
407687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    assert(VA.isMemLoc());
40853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
409687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    unsigned Offset = VA.getLocMemOffset()+StackOffset;
410687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
411687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    if (VA.needsCustom()) {
412687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      assert(VA.getValVT() == MVT::f64);
4131e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju      // If it is double-word aligned, just load.
414687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      if (Offset % 8 == 0) {
415687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        int FI = MF.getFrameInfo()->CreateFixedObject(8,
416687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                      Offset,
417687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                      true);
418687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
419687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr,
420687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                   MachinePointerInfo(),
421d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                   false,false, false, 0);
422687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        InVals.push_back(Load);
423687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        continue;
424d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      }
425687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
426687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      int FI = MF.getFrameInfo()->CreateFixedObject(4,
427687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                    Offset,
428687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                    true);
429687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
430687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
431687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                  MachinePointerInfo(),
432d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                  false, false, false, 0);
433687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      int FI2 = MF.getFrameInfo()->CreateFixedObject(4,
434687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                     Offset+4,
435687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                     true);
436687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SDValue FIPtr2 = DAG.getFrameIndex(FI2, getPointerTy());
437687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
438687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SDValue LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr2,
439687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                  MachinePointerInfo(),
440d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                  false, false, false, 0);
441687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
442687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SDValue WholeValue =
443687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
444687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue);
445687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      InVals.push_back(WholeValue);
446687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      continue;
447d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    }
448687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
449687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    int FI = MF.getFrameInfo()->CreateFixedObject(4,
450687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                  Offset,
451687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                                  true);
452687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
453687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    SDValue Load ;
454687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) {
455687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr,
456687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                         MachinePointerInfo(),
457d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                         false, false, false, 0);
458687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    } else {
459687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
460687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      // Sparc is big endian, so add an offset based on the ObjectVT.
461687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      unsigned Offset = 4-std::max(1U, VA.getValVT().getSizeInBits()/8);
462687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr,
463687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                          DAG.getConstant(Offset, MVT::i32));
464a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings      Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr,
465687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                            MachinePointerInfo(),
466687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                            VA.getValVT(), false, false,0);
467687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Load = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Load);
468687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    }
469687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    InVals.push_back(Load);
470d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
47153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
4728184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  if (MF.getFunction()->hasStructRetAttr()) {
4731e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju    // Copy the SRet Argument to SRetReturnReg.
4748184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    SparcMachineFunctionInfo *SFI = MF.getInfo<SparcMachineFunctionInfo>();
4758184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    unsigned Reg = SFI->getSRetReturnReg();
4768184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    if (!Reg) {
4778184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass);
4788184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      SFI->setSRetReturnReg(Reg);
4798184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    }
4808184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]);
4818184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
4828184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju  }
4838184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju
484d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Store remaining ArgRegs to the stack if this is a varargs function.
485a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman  if (isVarArg) {
486c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper    static const uint16_t ArgRegs[] = {
487687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
488687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    };
489687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs, 6);
490c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper    const uint16_t *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6;
491687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    unsigned ArgOffset = CCInfo.getNextStackOffset();
492687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    if (NumAllocated == 6)
493687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      ArgOffset += StackOffset;
494687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    else {
495687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      assert(!ArgOffset);
496687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      ArgOffset = 68+4*NumAllocated;
497687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    }
498687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
499d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    // Remember the vararg offset for the va_start implementation.
5001e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman    FuncInfo->setVarArgsFrameOffset(ArgOffset);
50153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
502a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman    std::vector<SDValue> OutChains;
503a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman
504d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
505d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
506d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
507825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32);
508d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
5093f2bf85d14759cc4b28a86805f566ac805a54d00David Greene      int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset,
510ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng                                                          true);
511825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
512d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
5136229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner      OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr,
5146229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner                                       MachinePointerInfo(),
51554a7aa84294e31140a023e0c721703a647fe227bDavid Greene                                       false, false, 0));
516d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      ArgOffset += 4;
517d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    }
518a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman
519a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman    if (!OutChains.empty()) {
52098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman      OutChains.push_back(Chain);
521825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
52298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                          &OutChains[0], OutChains.size());
523a786c7b90cfacf1c36c975ad35c3b793c232e3d8Eli Friedman    }
524d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
52553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
52698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
527d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
528d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
529f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen// Lower formal arguments for the 64 bit ABI.
530f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenSDValue SparcTargetLowering::
531f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund OlesenLowerFormalArguments_64(SDValue Chain,
532f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        CallingConv::ID CallConv,
533f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        bool IsVarArg,
534f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        const SmallVectorImpl<ISD::InputArg> &Ins,
535ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                        SDLoc DL,
536f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        SelectionDAG &DAG,
537f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                        SmallVectorImpl<SDValue> &InVals) const {
538f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  MachineFunction &MF = DAG.getMachineFunction();
539f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
540f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  // Analyze arguments according to CC_Sparc64.
541f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  SmallVector<CCValAssign, 16> ArgLocs;
542f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
543f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                 getTargetMachine(), ArgLocs, *DAG.getContext());
544f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64);
545f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
546da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // The argument array begins at %fp+BIAS+128, after the register save area.
547da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  const unsigned ArgArea = 128;
548da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen
549f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
550f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen    CCValAssign &VA = ArgLocs[i];
551f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen    if (VA.isRegLoc()) {
552f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      // This argument is passed in a register.
553f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      // All integer register arguments are promoted by the caller to i64.
554f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
555f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      // Create a virtual register for the promoted live-in value.
556f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      unsigned VReg = MF.addLiveIn(VA.getLocReg(),
557f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                                   getRegClassFor(VA.getLocVT()));
558f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
559f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
5601f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen      // Get the high bits for i32 struct elements.
5611f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen      if (VA.getValVT() == MVT::i32 && VA.needsCustom())
5621f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen        Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg,
5631f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                          DAG.getConstant(32, MVT::i32));
5641f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen
565f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      // The caller promoted the argument, so insert an Assert?ext SDNode so we
566f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      // won't promote the value again in this function.
567f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      switch (VA.getLocInfo()) {
568f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      case CCValAssign::SExt:
569f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen        Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
570f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                          DAG.getValueType(VA.getValVT()));
571f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen        break;
572f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      case CCValAssign::ZExt:
573f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen        Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
574f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen                          DAG.getValueType(VA.getValVT()));
575f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen        break;
576f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      default:
577f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen        break;
578f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      }
579f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
580f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      // Truncate the register down to the argument type.
581f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      if (VA.isExtInLoc())
582f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen        Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
583f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
584f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      InVals.push_back(Arg);
585f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen      continue;
586f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen    }
587f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
588f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen    // The registers are exhausted. This argument was passed on the stack.
589f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen    assert(VA.isMemLoc());
5901f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // The CC_Sparc64_Full/Half functions compute stack offsets relative to the
5911f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // beginning of the arguments area at %fp+BIAS+128.
592da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    unsigned Offset = VA.getLocMemOffset() + ArgArea;
5931f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    unsigned ValSize = VA.getValVT().getSizeInBits() / 8;
5941f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // Adjust offset for extended arguments, SPARC is big-endian.
5951f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // The caller will have written the full slot with extended bytes, but we
5961f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    // prefer our own extending loads.
5971f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    if (VA.isExtInLoc())
5981f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen      Offset += 8 - ValSize;
5991f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true);
6001f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen    InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain,
6011f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                                 DAG.getFrameIndex(FI, getPointerTy()),
6021f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                                 MachinePointerInfo::getFixedStack(FI),
6031f25fe50236e5842b19198fbfe8a812be0b40cf5Jakob Stoklund Olesen                                 false, false, false, 0));
604f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  }
605da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen
606da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  if (!IsVarArg)
607da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    return Chain;
608da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen
609da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // This function takes variable arguments, some of which may have been passed
610da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // in registers %i0-%i5. Variable floating point arguments are never passed
611da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // in floating point registers. They go on %i0-%i5 or on the stack like
612da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // integer arguments.
613da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  //
614da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // The va_start intrinsic needs to know the offset to the first variable
615da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // argument.
616da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  unsigned ArgOffset = CCInfo.getNextStackOffset();
617da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
618da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // Skip the 128 bytes of register save area.
619da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgArea +
620da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                                  Subtarget->getStackPointerBias());
621da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen
622da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // Save the variable arguments that were passed in registers.
623da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // The caller is required to reserve stack space for 6 arguments regardless
624da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // of how many arguments were actually passed.
625da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  SmallVector<SDValue, 8> OutChains;
626da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  for (; ArgOffset < 6*8; ArgOffset += 8) {
627da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    unsigned VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass);
628da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64);
629da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    int FI = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset + ArgArea, true);
630da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    OutChains.push_back(DAG.getStore(Chain, DL, VArg,
631da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                                     DAG.getFrameIndex(FI, getPointerTy()),
632da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                                     MachinePointerInfo::getFixedStack(FI),
633da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                                     false, false, 0));
634da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  }
635da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen
636da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  if (!OutChains.empty())
637da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
638da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                        &OutChains[0], OutChains.size());
639da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen
640f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen  return Chain;
641f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen}
642f37812e906a3abbdb8353e2eb9e8223ff9036b68Jakob Stoklund Olesen
64398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
644d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiSparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
645d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                               SmallVectorImpl<SDValue> &InVals) const {
64618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  if (Subtarget->is64Bit())
64718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    return LowerCall_64(CLI, InVals);
64818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  return LowerCall_32(CLI, InVals);
64918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen}
65018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
65118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen// Lower a call for the 32-bit ABI.
65218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSDValue
65318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
65418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                  SmallVectorImpl<SDValue> &InVals) const {
655d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
656ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc &dl                             = CLI.DL;
657d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
658d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
659d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
660d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
661d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
662d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
663d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
664d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
665d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
6660c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  // Sparc target does not yet support tail call optimization.
6670c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  isTailCall = false;
66898949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner
669315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  // Analyze operands of the call, assigning locations to each operand.
670315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  SmallVector<CCValAssign, 16> ArgLocs;
671471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
67256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 DAG.getTarget(), ArgLocs, *DAG.getContext());
67398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32);
67453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
675315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  // Get the size of the outgoing arguments stack space requirement.
676315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  unsigned ArgsSize = CCInfo.getNextStackOffset();
67753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
678d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Keep stack frames 8-byte aligned.
679d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  ArgsSize = (ArgsSize+7) & ~7;
680d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
68146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
68246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
6831e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju  // Create local copies for byval args.
68446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju  SmallVector<SDValue, 8> ByValArgs;
68546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju  for (unsigned i = 0,  e = Outs.size(); i != e; ++i) {
68646713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    ISD::ArgFlagsTy Flags = Outs[i].Flags;
68746713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    if (!Flags.isByVal())
68846713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju      continue;
68946713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
69046713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    SDValue Arg = OutVals[i];
69146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    unsigned Size = Flags.getByValSize();
69246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    unsigned Align = Flags.getByValAlign();
69346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
69446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    int FI = MFI->CreateStackObject(Size, Align, false);
69546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy());
69646713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    SDValue SizeNode = DAG.getConstant(Size, MVT::i32);
69746713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
69846713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Align,
6991e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                          false,        // isVolatile,
7001e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                          (Size <= 32), // AlwaysInline if size <= 32
70146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju                          MachinePointerInfo(), MachinePointerInfo());
70246713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    ByValArgs.push_back(FIPtr);
70346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju  }
70446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
7056e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true),
7066e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                               dl);
70753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
708475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
709475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SmallVector<SDValue, 8> MemOpChains;
71053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
711687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju  const unsigned StackOffset = 92;
71258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  bool hasStructRetAttr = false;
713315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  // Walk the register/memloc assignments, inserting copies/loads.
71446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju  for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size();
715687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju       i != e;
716687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju       ++i, ++realArgIdx) {
717315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    CCValAssign &VA = ArgLocs[i];
718687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    SDValue Arg = OutVals[realArgIdx];
719315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner
72046713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
72146713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
7221e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju    // Use local copy if it is a byval arg.
72346713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju    if (Flags.isByVal())
72446713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju      Arg = ByValArgs[byvalArgIdx++];
72546713296e0da8f413b94b9c2b82b079e6e3bd6e2Venkatraman Govindaraju
726315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    // Promote the value if needed.
727315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    switch (VA.getLocInfo()) {
728c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown loc info!");
729315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    case CCValAssign::Full: break;
730315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    case CCValAssign::SExt:
731687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
732315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner      break;
733315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    case CCValAssign::ZExt:
734687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
735315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner      break;
736315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    case CCValAssign::AExt:
737687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
738687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      break;
739687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    case CCValAssign::BCvt:
740687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
741315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner      break;
742315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner    }
74353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
7448184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    if (Flags.isSRet()) {
7458184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      assert(VA.needsCustom());
7468184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      // store SRet argument in %sp+64
7478184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
7488184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      SDValue PtrOff = DAG.getIntPtrConstant(64);
7498184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
7508184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
7518184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                         MachinePointerInfo(),
7528184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju                                         false, false, 0));
75358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju      hasStructRetAttr = true;
7548184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju      continue;
7558184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju    }
7568184e289db45acd0bd8bbf7087f7a1274ef55f15Venkatraman Govindaraju
757687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    if (VA.needsCustom()) {
758687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      assert(VA.getLocVT() == MVT::f64);
759687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
760687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      if (VA.isMemLoc()) {
761687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        unsigned Offset = VA.getLocMemOffset() + StackOffset;
7621e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju        // if it is double-word aligned, just store.
763687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        if (Offset % 8 == 0) {
764687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
765687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          SDValue PtrOff = DAG.getIntPtrConstant(Offset);
766687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
767687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
768687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                             MachinePointerInfo(),
769687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                             false, false, 0));
770687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          continue;
77112db7b68b683371a6ae464e76b4c850fa0199eebVenkatraman Govindaraju        }
7728c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands      }
773687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
774825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
775bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
776687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                   Arg, StackPtr, MachinePointerInfo(),
77754a7aa84294e31140a023e0c721703a647fe227bDavid Greene                                   false, false, 0);
7788c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands      // Sparc is big-endian, so the high part comes first.
779d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner      SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr,
780d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                               MachinePointerInfo(), false, false, false, 0);
7818c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands      // Increment the pointer to the other half.
78233c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen      StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
7838c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands                             DAG.getIntPtrConstant(4));
7848c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands      // Load the low part.
785d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner      SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr,
786d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                               MachinePointerInfo(), false, false, false, 0);
7878c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands
788687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      if (VA.isRegLoc()) {
789687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        RegsToPass.push_back(std::make_pair(VA.getLocReg(), Hi));
790687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        assert(i+1 != e);
791687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        CCValAssign &NextVA = ArgLocs[++i];
792687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        if (NextVA.isRegLoc()) {
793687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Lo));
794687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        } else {
7951e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju          // Store the low part in stack.
796687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          unsigned Offset = NextVA.getLocMemOffset() + StackOffset;
797687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
798687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          SDValue PtrOff = DAG.getIntPtrConstant(Offset);
799687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
800687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju          MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff,
801687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                             MachinePointerInfo(),
802687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                             false, false, 0));
803687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        }
8048c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands      } else {
805687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        unsigned Offset = VA.getLocMemOffset() + StackOffset;
806687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        // Store the high part.
807687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
808687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        SDValue PtrOff = DAG.getIntPtrConstant(Offset);
809687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
810687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        MemOpChains.push_back(DAG.getStore(Chain, dl, Hi, PtrOff,
811687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           MachinePointerInfo(),
812687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           false, false, 0));
813687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        // Store the low part.
814687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        PtrOff = DAG.getIntPtrConstant(Offset+4);
815687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
816687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        MemOpChains.push_back(DAG.getStore(Chain, dl, Lo, PtrOff,
817687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           MachinePointerInfo(),
818687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                           false, false, 0));
8198c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands      }
820687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      continue;
8218c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands    }
82253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
823687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    // Arguments that can be passed on register must be kept at
824687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    // RegsToPass vector
825687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    if (VA.isRegLoc()) {
826687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      if (VA.getLocVT() != MVT::f32) {
827687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
828687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju        continue;
829d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      }
830687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
831687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
832687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju      continue;
8338c0f244c3ed90a3f702bac09334cac2d3236aecbDuncan Sands    }
83453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
835687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    assert(VA.isMemLoc());
836687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
837687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    // Create a store off the stack pointer for this argument.
838687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
839687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+StackOffset);
840687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
841687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju    MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
842687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                       MachinePointerInfo(),
843687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju                                       false, false, 0));
844d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
845687ae9606bb983659700b133963f48c9a06aec03Venkatraman Govindaraju
84653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
847d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Emit all stores, make sure the occur before any copies into physregs.
848315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  if (!MemOpChains.empty())
849825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
850315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner                        &MemOpChains[0], MemOpChains.size());
85153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
85253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token
853315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  // chain and flag operands which copy the outgoing args into registers.
8547a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // The InFlag in necessary since all emitted instructions must be
855315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  // stuck together.
856475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InFlag;
857315123fb6a93f26f3660b7cb297ad378ec14c92dChris Lattner  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
8581b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen    unsigned Reg = toCallerWindow(RegsToPass[i].first);
85933c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen    Chain = DAG.getCopyToReg(Chain, dl, Reg, RegsToPass[i].second, InFlag);
860d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    InFlag = Chain.getValue(1);
861d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
862d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
86358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  unsigned SRetArgSize = (hasStructRetAttr)? getSRetArgSize(DAG, Callee):0;
86458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
865d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // If the callee is a GlobalAddress node (quite common, every direct call is)
866d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
867056292fd738924f3f7703725d8f630983794b5a5Bill Wendling  // Likewise ExternalSymbol -> TargetExternalSymbol.
868d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
8690d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
870056292fd738924f3f7703725d8f630983794b5a5Bill Wendling  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
871825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
872d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
8737d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  // Returns a chain & a flag for retval copy to use
8747d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
8757d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  SmallVector<SDValue, 8> Ops;
8767d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  Ops.push_back(Chain);
8777d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  Ops.push_back(Callee);
87858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  if (hasStructRetAttr)
87958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    Ops.push_back(DAG.getTargetConstant(SRetArgSize, MVT::i32));
8801b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
8811b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen    Ops.push_back(DAG.getRegister(toCallerWindow(RegsToPass[i].first),
8821b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen                                  RegsToPass[i].second.getValueType()));
8837d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  if (InFlag.getNode())
8847d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju    Ops.push_back(InFlag);
8857d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju
8867d29ffbe5b091fae03afd264d8c8b0090c7a45f4Venkatraman Govindaraju  Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
887d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  InFlag = Chain.getValue(1);
88853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
889e563bbc312f8b11ecfe12b8187176f667df1dff3Chris Lattner  Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true),
8906e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                             DAG.getIntPtrConstant(0, true), InFlag, dl);
89198949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner  InFlag = Chain.getValue(1);
89253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
89398949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner  // Assign locations to each value returned by this call.
89498949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner  SmallVector<CCValAssign, 16> RVLocs;
895471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(),
89656cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 DAG.getTarget(), RVLocs, *DAG.getContext());
89753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
89898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32);
89953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
90098949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner  // Copy all of the result registers out of their specified physreg.
90198949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner  for (unsigned i = 0; i != RVLocs.size(); ++i) {
9021b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen    Chain = DAG.getCopyFromReg(Chain, dl, toCallerWindow(RVLocs[i].getLocReg()),
90398949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner                               RVLocs[i].getValVT(), InFlag).getValue(1);
90498949a6d2c42e386f36b5fd94cb97008a51b610fChris Lattner    InFlag = Chain.getValue(2);
90598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
906d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
90753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
90898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
909d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
910d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
91158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindarajuunsigned
91258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman GovindarajuSparcTargetLowering::getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const
91358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju{
91458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  const Function *CalleeFn = 0;
91558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
91658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    CalleeFn = dyn_cast<Function>(G->getGlobal());
91758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  } else if (ExternalSymbolSDNode *E =
91858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju             dyn_cast<ExternalSymbolSDNode>(Callee)) {
91958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    const Function *Fn = DAG.getMachineFunction().getFunction();
92058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    const Module *M = Fn->getParent();
92158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    CalleeFn = M->getFunction(E->getSymbol());
92258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  }
92358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
92458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  if (!CalleeFn)
92558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    return 0;
9265a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
92758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  assert(CalleeFn->hasStructRetAttr() &&
92858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju         "Callee does not have the StructRet attribute.");
92958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
930db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  PointerType *Ty = cast<PointerType>(CalleeFn->arg_begin()->getType());
931db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *ElementTy = Ty->getElementType();
9323574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  return getDataLayout()->getTypeAllocSize(ElementTy);
93358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju}
9345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
935ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen
936ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// Fixup floating point arguments in the ... part of a varargs call.
937ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen//
938ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// The SPARC v9 ABI requires that floating point arguments are treated the same
939ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// as integers when calling a varargs function. This does not apply to the
940ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// fixed arguments that are part of the function's prototype.
941ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen//
942ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// This function post-processes a CCValAssign array created by
943ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen// AnalyzeCallOperands().
944ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesenstatic void fixupVariableFloatArgs(SmallVectorImpl<CCValAssign> &ArgLocs,
945ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen                                   ArrayRef<ISD::OutputArg> Outs) {
946ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
947ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    const CCValAssign &VA = ArgLocs[i];
948ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    // FIXME: What about f32 arguments? C promotes them to f64 when calling
949ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    // varargs functions.
950ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    if (!VA.isRegLoc() || VA.getLocVT() != MVT::f64)
951ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      continue;
952ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    // The fixed arguments to a varargs function still go in FP registers.
953ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    if (Outs[VA.getValNo()].IsFixed)
954ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      continue;
955ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen
956ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    // This floating point argument should be reassigned.
957ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    CCValAssign NewVA;
958ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen
959ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    // Determine the offset into the argument array.
960ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    unsigned Offset = 8 * (VA.getLocReg() - SP::D0);
961ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    assert(Offset < 16*8 && "Offset out of range, bad register enum?");
962ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen
963ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    if (Offset < 6*8) {
964ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      // This argument should go in %i0-%i5.
965ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      unsigned IReg = SP::I0 + Offset/8;
966ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      // Full register, just bitconvert into i64.
967ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
968ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen                                  IReg, MVT::i64, CCValAssign::BCvt);
969ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    } else {
970ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      // This needs to go to memory, we're out of integer registers.
971ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen      NewVA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
972ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen                                  Offset, VA.getLocVT(), VA.getLocInfo());
973ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    }
974ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    ArgLocs[i] = NewVA;
975ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen  }
976ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen}
977ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen
97818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen// Lower a call for the 64-bit ABI.
97918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSDValue
98018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund OlesenSparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
98118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                  SmallVectorImpl<SDValue> &InVals) const {
98218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SelectionDAG &DAG = CLI.DAG;
983ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL = CLI.DL;
98418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SDValue Chain = CLI.Chain;
98518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
98618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Analyze operands of the call, assigning locations to each operand.
98718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SmallVector<CCValAssign, 16> ArgLocs;
98818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
98918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                 DAG.getTarget(), ArgLocs, *DAG.getContext());
99018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64);
99118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
99218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Get the size of the outgoing arguments stack space requirement.
99318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // The stack offset computed by CC_Sparc64 includes all arguments.
9946ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen  // Called functions expect 6 argument words to exist in the stack frame, used
9956ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen  // or not.
9966ed9284c2bcfb81fa0303409c6bd4366bc1e822aJakob Stoklund Olesen  unsigned ArgsSize = std::max(6*8u, CCInfo.getNextStackOffset());
99718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
99818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Keep stack frames 16-byte aligned.
99918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  ArgsSize = RoundUpToAlignment(ArgsSize, 16);
100018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
1001ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen  // Varargs calls require special treatment.
1002ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen  if (CLI.IsVarArg)
1003ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen    fixupVariableFloatArgs(ArgLocs, CLI.Outs);
1004ddb14ce76cbdf682d95765aa1e576fafeec180aeJakob Stoklund Olesen
100518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Adjust the stack pointer to make room for the arguments.
100618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
100718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // with more than 6 arguments.
10086e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true),
10096e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                               DL);
101018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
101118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Collect the set of registers to pass to the function and their values.
101218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // This will be emitted as a sequence of CopyToReg nodes glued to the call
101318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // instruction.
101418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
101518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
101618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Collect chains from all the memory opeations that copy arguments to the
101718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // stack. They must follow the stack pointer adjustment above and precede the
101818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // call instruction itself.
101918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SmallVector<SDValue, 8> MemOpChains;
102018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
102118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
102218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    const CCValAssign &VA = ArgLocs[i];
102318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    SDValue Arg = CLI.OutVals[i];
102418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
102518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // Promote the value if needed.
102618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    switch (VA.getLocInfo()) {
102718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    default:
102818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      llvm_unreachable("Unknown location info!");
102918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::Full:
103018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
103118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::SExt:
103218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
103318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
103418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::ZExt:
103518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
103618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
103718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::AExt:
103818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
103918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
104018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::BCvt:
104118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
104218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
104318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    }
104418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
104518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    if (VA.isRegLoc()) {
104618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      // The custom bit on an i32 return value indicates that it should be
104718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      // passed in the high bits of the register.
104818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
104918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen        Arg = DAG.getNode(ISD::SHL, DL, MVT::i64, Arg,
105018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                          DAG.getConstant(32, MVT::i32));
105118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
105218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen        // The next value may go in the low bits of the same register.
105318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen        // Handle both at once.
105418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen        if (i+1 < ArgLocs.size() && ArgLocs[i+1].isRegLoc() &&
105518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen            ArgLocs[i+1].getLocReg() == VA.getLocReg()) {
105618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen          SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64,
105718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                   CLI.OutVals[i+1]);
105818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen          Arg = DAG.getNode(ISD::OR, DL, MVT::i64, Arg, NV);
105918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen          // Skip the next value, it's already done.
106018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen          ++i;
106118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen        }
106218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      }
10631b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen      RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()), Arg));
106418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      continue;
106518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    }
106618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
106718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    assert(VA.isMemLoc());
106818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
106918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // Create a store off the stack pointer for this argument.
107018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy());
107118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // The argument area starts at %fp+BIAS+128 in the callee frame,
107218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // %sp+BIAS+128 in ours.
107318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() +
107418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                           Subtarget->getStackPointerBias() +
107518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                           128);
107618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, PtrOff);
107718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    MemOpChains.push_back(DAG.getStore(Chain, DL, Arg, PtrOff,
107818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                       MachinePointerInfo(),
107918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                       false, false, 0));
108018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  }
108118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
108218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Emit all stores, make sure they occur before the call.
108318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  if (!MemOpChains.empty())
108418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
108518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                        &MemOpChains[0], MemOpChains.size());
108618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
108718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Build a sequence of CopyToReg nodes glued together with token chain and
108818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // glue operands which copy the outgoing args into registers. The InGlue is
108918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // necessary since all emitted instructions must be stuck together in order
109018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // to pass the live physical registers.
109118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SDValue InGlue;
109218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
109318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    Chain = DAG.getCopyToReg(Chain, DL,
109418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                             RegsToPass[i].first, RegsToPass[i].second, InGlue);
109518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    InGlue = Chain.getValue(1);
109618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  }
109718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
109818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // If the callee is a GlobalAddress node (quite common, every direct call is)
109918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
110018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Likewise ExternalSymbol -> TargetExternalSymbol.
110118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SDValue Callee = CLI.Callee;
110218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
110318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy());
110418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
110518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
110618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
110718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Build the operands for the call instruction itself.
110818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SmallVector<SDValue, 8> Ops;
110918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  Ops.push_back(Chain);
111018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  Ops.push_back(Callee);
111118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
111218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
111318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                                  RegsToPass[i].second.getValueType()));
111418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
111518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Make sure the CopyToReg nodes are glued to the call instruction which
111618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // consumes the registers.
111718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  if (InGlue.getNode())
111818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    Ops.push_back(InGlue);
111918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
112018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Now the call itself.
112118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
112218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, &Ops[0], Ops.size());
112318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  InGlue = Chain.getValue(1);
112418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
112518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Revert the stack pointer immediately after the call.
112618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true),
11276e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                             DAG.getIntPtrConstant(0, true), InGlue, DL);
112818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  InGlue = Chain.getValue(1);
112918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
113018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Now extract the return values. This is more or less the same as
113118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // LowerFormalArguments_64.
113218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
113318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Assign locations to each value returned by this call.
113418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  SmallVector<CCValAssign, 16> RVLocs;
113518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
113618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                 DAG.getTarget(), RVLocs, *DAG.getContext());
113718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64);
113818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
113918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  // Copy all of the result registers out of their specified physreg.
114018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  for (unsigned i = 0; i != RVLocs.size(); ++i) {
114118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    CCValAssign &VA = RVLocs[i];
11421b133a478baaec072d937dd577c63094fdfcd4bbJakob Stoklund Olesen    unsigned Reg = toCallerWindow(VA.getLocReg());
114318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
114418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
114518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // reside in the same register in the high and low bits. Reuse the
114618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // CopyFromReg previous node to avoid duplicate copies.
114718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    SDValue RV;
114818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1)))
114918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg)
115018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen        RV = Chain.getValue(0);
115118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
115218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // But usually we'll create a new CopyFromReg for a different register.
115318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    if (!RV.getNode()) {
115418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue);
115518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      Chain = RV.getValue(1);
115618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      InGlue = Chain.getValue(2);
115718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    }
115818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
115918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // Get the high bits for i32 struct elements.
116018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    if (VA.getValVT() == MVT::i32 && VA.needsCustom())
116118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV,
116218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                       DAG.getConstant(32, MVT::i32));
116318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
116418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // The callee promoted the return value, so insert an Assert?ext SDNode so
116518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // we won't promote the value again in this function.
116618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    switch (VA.getLocInfo()) {
116718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::SExt:
116818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV,
116918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                       DAG.getValueType(VA.getValVT()));
117018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
117118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    case CCValAssign::ZExt:
117218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV,
117318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen                       DAG.getValueType(VA.getValVT()));
117418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
117518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    default:
117618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      break;
117718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    }
117818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
117918fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    // Truncate the register down to the return value type.
118018fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    if (VA.isExtInLoc())
118118fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen      RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV);
118218fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
118318fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen    InVals.push_back(RV);
118418fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  }
118518fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
118618fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen  return Chain;
118718fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen}
118818fdb398ea94c7ddee40bec49f63491922c5b110Jakob Stoklund Olesen
11895a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner//===----------------------------------------------------------------------===//
11905a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner// TargetLowering Implementation
11915a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner//===----------------------------------------------------------------------===//
11925a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
11935a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC
11945a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// condition.
11955a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerstatic SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
11965a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  switch (CC) {
1197c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer condition code!");
11985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETEQ:  return SPCC::ICC_E;
11995a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETNE:  return SPCC::ICC_NE;
12005a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETLT:  return SPCC::ICC_L;
12015a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETGT:  return SPCC::ICC_G;
12025a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETLE:  return SPCC::ICC_LE;
12035a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETGE:  return SPCC::ICC_GE;
12045a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETULT: return SPCC::ICC_CS;
12055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETULE: return SPCC::ICC_LEU;
12065a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUGT: return SPCC::ICC_GU;
12075a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUGE: return SPCC::ICC_CC;
12085a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  }
12095a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner}
12105a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12115a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC
12125a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// FCC condition.
12135a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerstatic SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
12145a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  switch (CC) {
1215c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown fp condition code!");
12165a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETEQ:
12175a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETOEQ: return SPCC::FCC_E;
12185a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETNE:
12195a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUNE: return SPCC::FCC_NE;
12205a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETLT:
12215a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETOLT: return SPCC::FCC_L;
12225a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETGT:
12235a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETOGT: return SPCC::FCC_G;
12245a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETLE:
12255a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETOLE: return SPCC::FCC_LE;
12265a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETGE:
12275a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETOGE: return SPCC::FCC_GE;
12285a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETULT: return SPCC::FCC_UL;
12295a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETULE: return SPCC::FCC_ULE;
12305a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUGT: return SPCC::FCC_UG;
12315a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUGE: return SPCC::FCC_UGE;
12325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUO:  return SPCC::FCC_U;
12335a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETO:   return SPCC::FCC_O;
12345a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETONE: return SPCC::FCC_LG;
12355a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case ISD::SETUEQ: return SPCC::FCC_UE;
12365a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  }
12375a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner}
12385a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12395a65b928302494ad2b3051980ce956e8f9e95023Chris LattnerSparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
12405277b22687d3513dd29d5a9c8510cac740f933f6Chris Lattner  : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
1241fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen  Subtarget = &TM.getSubtarget<SparcSubtarget>();
124253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
12435a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Set up the register classes.
1244c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  addRegisterClass(MVT::i32, &SP::IntRegsRegClass);
1245c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
1246c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
1247fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen  if (Subtarget->is64Bit())
1248fcb25e60f514e4dbceecef73ac229c61d6202ed2Jakob Stoklund Olesen    addRegisterClass(MVT::i64, &SP::I64RegsRegClass);
12495a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12505a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Turn FP extload into load/fextend
1251825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
12525a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Sparc doesn't have i1 sign extending load
1253825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
12545a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Turn FP truncstore into trunc + store.
1255825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
12565a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12575a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Custom legalize GlobalAddress nodes into LO/HI parts.
125841d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen  setOperationAction(ISD::GlobalAddress, getPointerTy(), Custom);
125941d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen  setOperationAction(ISD::GlobalTLSAddress, getPointerTy(), Custom);
126041d59c61307002823c246c14589048266a6bf423Jakob Stoklund Olesen  setOperationAction(ISD::ConstantPool, getPointerTy(), Custom);
1261e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju  setOperationAction(ISD::BlockAddress, getPointerTy(), Custom);
126253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
12635a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Sparc doesn't have sext_inreg, replace them with shl/sra
1264825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
1265825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
1266825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
12675a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12685a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Sparc has no REM or DIVREM operations.
1269825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UREM, MVT::i32, Expand);
1270825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SREM, MVT::i32, Expand);
1271825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
1272825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
12735a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12745a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Custom expand fp<->sint
1275825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
1276825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
12775a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
12785a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Expand fp<->uint
1279825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
1280825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
128153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1282bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  setOperationAction(ISD::BITCAST, MVT::f32, Expand);
1283bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  setOperationAction(ISD::BITCAST, MVT::i32, Expand);
128453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
12855a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Sparc has no select or setcc: expand to SELECT_CC.
1286825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT, MVT::i32, Expand);
1287825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT, MVT::f32, Expand);
1288825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT, MVT::f64, Expand);
1289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SETCC, MVT::i32, Expand);
1290825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SETCC, MVT::f32, Expand);
1291825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SETCC, MVT::f64, Expand);
129253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
12935a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Sparc doesn't have BRCOND either, it has BR_CC.
1294825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND, MVT::Other, Expand);
1295825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRIND, MVT::Other, Expand);
1296825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_JT, MVT::Other, Expand);
1297825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC, MVT::i32, Custom);
1298825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC, MVT::f32, Custom);
1299825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC, MVT::f64, Custom);
130053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1301825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
1302825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
1303825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
130453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
13058534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen  if (Subtarget->is64Bit()) {
130689f530ebbfa91d1583a72d86dc6ca2804f4f450dJakob Stoklund Olesen    setOperationAction(ISD::BITCAST, MVT::f64, Expand);
130789f530ebbfa91d1583a72d86dc6ca2804f4f450dJakob Stoklund Olesen    setOperationAction(ISD::BITCAST, MVT::i64, Expand);
1308900622e099054da4a213074581d8501ac27e7ea7Jakob Stoklund Olesen    setOperationAction(ISD::SELECT, MVT::i64, Expand);
1309900622e099054da4a213074581d8501ac27e7ea7Jakob Stoklund Olesen    setOperationAction(ISD::SETCC, MVT::i64, Expand);
13108534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen    setOperationAction(ISD::BR_CC, MVT::i64, Custom);
13110e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen    setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
13128534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen  }
13138534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen
131414648468011c92a4210f8118721d58c25043daf8Eli Friedman  // FIXME: There are instructions available for ATOMIC_FENCE
131514648468011c92a4210f8118721d58c25043daf8Eli Friedman  // on SparcV8 and later.
131614648468011c92a4210f8118721d58c25043daf8Eli Friedman  setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
1317825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
13181799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  if (!Subtarget->isV9()) {
13191799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju    // SparcV8 does not have FNEGD and FABSD.
13201799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju    setOperationAction(ISD::FNEG, MVT::f64, Custom);
13211799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju    setOperationAction(ISD::FABS, MVT::f64, Custom);
13221799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  }
13231799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
1324825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FSIN , MVT::f64, Expand);
1325825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FCOS , MVT::f64, Expand);
13268688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng  setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
1327825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FREM , MVT::f64, Expand);
132833390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich  setOperationAction(ISD::FMA  , MVT::f64, Expand);
1329825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FSIN , MVT::f32, Expand);
1330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FCOS , MVT::f32, Expand);
13318688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng  setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
1332825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FREM , MVT::f32, Expand);
133333390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich  setOperationAction(ISD::FMA  , MVT::f32, Expand);
1334825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP, MVT::i32, Expand);
1335825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ , MVT::i32, Expand);
133663974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
1337825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ , MVT::i32, Expand);
133863974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
1339825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL , MVT::i32, Expand);
1340825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR , MVT::i32, Expand);
1341825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BSWAP, MVT::i32, Expand);
1342825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
1343825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
1344825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FPOW , MVT::f64, Expand);
1345825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FPOW , MVT::f32, Expand);
1346825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
1347825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
1348825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
1349825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
13505a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
13515a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // FIXME: Sparc provides these multiplies, but we don't have them yet.
1352825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
1353825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
135453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1355825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
13565a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
13575a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
1358825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::VASTART           , MVT::Other, Custom);
13595a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // VAARG needs to be lowered to not do unaligned accesses for doubles.
1360825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::VAARG             , MVT::Other, Custom);
136153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
13625a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // Use the default implementation.
1363825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::VACOPY            , MVT::Other, Expand);
1364825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::VAEND             , MVT::Other, Expand);
1365825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::STACKSAVE         , MVT::Other, Expand);
1366825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
1367825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
13685a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
13695a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  // No debug info support yet.
1370825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
137153835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
13725a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  setStackPointerRegisterToSaveRestore(SP::O6);
13735a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
13741799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  if (Subtarget->isV9())
1375825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    setOperationAction(ISD::CTPOP, MVT::i32, Legal);
137653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1377fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setMinFunctionAlignment(2);
1378fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
13795a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  computeRegisterProperties();
13805a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner}
13815a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
13825a65b928302494ad2b3051980ce956e8f9e95023Chris Lattnerconst char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
13835a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  switch (Opcode) {
13845a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  default: return 0;
13855a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::CMPICC:     return "SPISD::CMPICC";
13865a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::CMPFCC:     return "SPISD::CMPFCC";
13875a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::BRICC:      return "SPISD::BRICC";
13888534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen  case SPISD::BRXCC:      return "SPISD::BRXCC";
13895a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::BRFCC:      return "SPISD::BRFCC";
13905a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
13910e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen  case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC";
13925a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
13935a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::Hi:         return "SPISD::Hi";
13945a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::Lo:         return "SPISD::Lo";
13955a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::FTOI:       return "SPISD::FTOI";
13965a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::ITOF:       return "SPISD::ITOF";
13975a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::CALL:       return "SPISD::CALL";
13985a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::RET_FLAG:   return "SPISD::RET_FLAG";
1399860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";
1400fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju  case SPISD::FLUSHW:     return "SPISD::FLUSHW";
14015a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  }
14025a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner}
14035a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
14045a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
14055a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// be zero. Op is expected to be a target specific node. Used by DAG
14065a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner/// combiner.
14071e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindarajuvoid SparcTargetLowering::computeMaskedBitsForTargetNode
14081e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                                (const SDValue Op,
14091e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                                 APInt &KnownZero,
14101e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                                 APInt &KnownOne,
14111e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                                 const SelectionDAG &DAG,
14121e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju                                 unsigned Depth) const {
14135a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  APInt KnownZero2, KnownOne2;
141426c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola  KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0);
141553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
14165a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  switch (Op.getOpcode()) {
14175a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  default: break;
14185a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::SELECT_ICC:
14190e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen  case SPISD::SELECT_XCC:
14205a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  case SPISD::SELECT_FCC:
142126c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola    DAG.ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
142226c8dcc692fb2addd475446cfff24d6a4e958bcaRafael Espindola    DAG.ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
142353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
142453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
142553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
14265a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    // Only known if known in both the LHS and RHS.
14275a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    KnownOne &= KnownOne2;
14285a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    KnownZero &= KnownZero2;
14295a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner    break;
14305a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner  }
14315a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner}
14325a65b928302494ad2b3051980ce956e8f9e95023Chris Lattner
1433d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// Look at LHS/RHS/CC and see if they are a lowered setcc instruction.  If so
1434d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
1435475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
1436d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner                             ISD::CondCode CC, unsigned &SPCC) {
1437f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman  if (isa<ConstantSDNode>(RHS) &&
1438e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman      cast<ConstantSDNode>(RHS)->isNullValue() &&
143953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov      CC == ISD::SETNE &&
14400e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen      (((LHS.getOpcode() == SPISD::SELECT_ICC ||
14410e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen         LHS.getOpcode() == SPISD::SELECT_XCC) &&
1442d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner        LHS.getOperand(3).getOpcode() == SPISD::CMPICC) ||
1443d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner       (LHS.getOpcode() == SPISD::SELECT_FCC &&
1444d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner        LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) &&
1445d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      isa<ConstantSDNode>(LHS.getOperand(0)) &&
1446d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner      isa<ConstantSDNode>(LHS.getOperand(1)) &&
1447e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman      cast<ConstantSDNode>(LHS.getOperand(0))->isOne() &&
1448e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman      cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) {
1449475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue CMPCC = LHS.getOperand(3);
1450f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
1451d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    LHS = CMPCC.getOperand(0);
1452d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    RHS = CMPCC.getOperand(1);
1453d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
1454d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1455d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
14560ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Convert to a target node and set target flags.
14570ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund OlesenSDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF,
14580ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen                                             SelectionDAG &DAG) const {
14590ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen  if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
14600ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen    return DAG.getTargetGlobalAddress(GA->getGlobal(),
1461ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                      SDLoc(GA),
14620ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen                                      GA->getValueType(0),
14630ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen                                      GA->getOffset(), TF);
146426932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen
146526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op))
146626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    return DAG.getTargetConstantPool(CP->getConstVal(),
146726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen                                     CP->getValueType(0),
146826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen                                     CP->getAlignment(),
146926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen                                     CP->getOffset(), TF);
147026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen
1471e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju  if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op))
1472e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju    return DAG.getTargetBlockAddress(BA->getBlockAddress(),
1473e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju                                     Op.getValueType(),
1474e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju                                     0,
1475e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju                                     TF);
1476e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju
147726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op))
147826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    return DAG.getTargetExternalSymbol(ES->getSymbol(),
147926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen                                       ES->getValueType(0), TF);
148026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen
14810ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen  llvm_unreachable("Unhandled address SDNode");
14820ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen}
14830ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen
14840ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Split Op into high and low parts according to HiTF and LoTF.
14850ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen// Return an ADD node combining the parts.
14860ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund OlesenSDValue SparcTargetLowering::makeHiLoPair(SDValue Op,
14870ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen                                          unsigned HiTF, unsigned LoTF,
14880ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen                                          SelectionDAG &DAG) const {
1489ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
14900ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen  EVT VT = Op.getValueType();
14910ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen  SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
14920ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen  SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
14930ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen  return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
14940ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen}
14950ec587e26cd7e048b3150f89fa6d6245d5728cecJakob Stoklund Olesen
149626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
149726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen// or ExternalSymbol SDNode.
149826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund OlesenSDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
1499ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
150087ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  EVT VT = getPointerTy();
150187ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen
150226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  // Handle PIC mode first.
150326932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
150426932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    // This is the pic32 code model, the GOT is known to be smaller than 4GB.
150526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
150626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
150726932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
150826932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen    return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr,
150926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen                       MachinePointerInfo::getGOT(), false, false, false, 0);
151026932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  }
151126932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen
151226932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  // This is one of the absolute code models.
151387ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  switch(getTargetMachine().getCodeModel()) {
151487ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  default:
151587ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen    llvm_unreachable("Unsupported absolute code model");
151687ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  case CodeModel::Small:
1517618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen    // abs32.
151887ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen    return makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
151987ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  case CodeModel::Medium: {
1520618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen    // abs44.
152187ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen    SDValue H44 = makeHiLoPair(Op, SPII::MO_H44, SPII::MO_M44, DAG);
1522d9f88da7b329c54ccb0d2ebd3b3a4b0e4b1e2b06Jakob Stoklund Olesen    H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getConstant(12, MVT::i32));
152387ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen    SDValue L44 = withTargetFlags(Op, SPII::MO_L44, DAG);
152487ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen    L44 = DAG.getNode(SPISD::Lo, DL, VT, L44);
152587ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen    return DAG.getNode(ISD::ADD, DL, VT, H44, L44);
152687ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  }
1527618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen  case CodeModel::Large: {
1528618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen    // abs64.
1529618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen    SDValue Hi = makeHiLoPair(Op, SPII::MO_HH, SPII::MO_HM, DAG);
1530d9f88da7b329c54ccb0d2ebd3b3a4b0e4b1e2b06Jakob Stoklund Olesen    Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(32, MVT::i32));
1531618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen    SDValue Lo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
1532618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen    return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
1533618eda7a60bafff7741a988e27b98bf81d27cb89Jakob Stoklund Olesen  }
153487ce01739b058fd6d929cd8e609ceecf82f919a7Jakob Stoklund Olesen  }
153526932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen}
153626932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen
1537bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op,
1538d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                SelectionDAG &DAG) const {
153926932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  return makeAddress(Op, DAG);
1540d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1541d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1542db486a6d5311944f61b92db9f6074944dbbdb242Chris LattnerSDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
1543d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
154426932106562adbe3f186b8f32fd5057d9f373875Jakob Stoklund Olesen  return makeAddress(Op, DAG);
1545d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1546d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1547e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman GovindarajuSDValue SparcTargetLowering::LowerBlockAddress(SDValue Op,
1548e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju                                               SelectionDAG &DAG) const {
1549e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju  return makeAddress(Op, DAG);
1550e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju}
1551e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju
1552475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
1553ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1554d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Convert the fp value to integer in an FP register.
1555825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(Op.getValueType() == MVT::i32);
1556825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
1557bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
1558d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1559d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1560475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
1561ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1562825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(Op.getOperand(0).getValueType() == MVT::i32);
1563bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Op.getOperand(0));
1564d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Convert the int value to FP in an FP register.
1565b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  return DAG.getNode(SPISD::ITOF, dl, Op.getValueType(), Tmp);
1566d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1567d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1568475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
1569475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = Op.getOperand(0);
1570d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
1571475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = Op.getOperand(2);
1572475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = Op.getOperand(3);
1573475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Dest = Op.getOperand(4);
1574ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1575d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  unsigned Opc, SPCC = ~0U;
157653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1577d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // If this is a br_cc of a "setcc", and if the setcc got lowered into
1578d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1579d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  LookThroughSetCC(LHS, RHS, CC, SPCC);
158053835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1581d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Get the condition flag.
1582475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue CompareFlag;
15838534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen  if (LHS.getValueType().isInteger()) {
158401021a8b93989a3c9e17dea540fe66809bf25403Venkatraman Govindaraju    CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS);
1585d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
15868534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen    // 32-bit compares use the icc flags, 64-bit uses the xcc flags.
15878534e9998c53efae49e4555ba394f39808fb83e0Jakob Stoklund Olesen    Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC;
1588d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  } else {
1589f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
1590d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
1591d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    Opc = SPISD::BRFCC;
1592d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
1593825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest,
1594825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                     DAG.getConstant(SPCC, MVT::i32), CompareFlag);
1595d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1596d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1597475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
1598475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = Op.getOperand(0);
1599475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = Op.getOperand(1);
1600d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1601475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue TrueVal = Op.getOperand(2);
1602475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue FalseVal = Op.getOperand(3);
1603ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1604d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  unsigned Opc, SPCC = ~0U;
160553835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1606d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // If this is a select_cc of a "setcc", and if the setcc got lowered into
1607d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1608d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  LookThroughSetCC(LHS, RHS, CC, SPCC);
160953835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1610475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue CompareFlag;
16110e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen  if (LHS.getValueType().isInteger()) {
161201021a8b93989a3c9e17dea540fe66809bf25403Venkatraman Govindaraju    CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS);
16130e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen    Opc = LHS.getValueType() == MVT::i32 ?
16140e164884423e9f0f22670015a428946ebf178545Jakob Stoklund Olesen          SPISD::SELECT_ICC : SPISD::SELECT_XCC;
1615d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
1616d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  } else {
1617f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
1618d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    Opc = SPISD::SELECT_FCC;
1619d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
1620d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
16213484c09e0da3c05c8a78946e090c7610208d937bDale Johannesen  return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
1622825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                     DAG.getConstant(SPCC, MVT::i32), CompareFlag);
1623d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1624d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1625475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
1626d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                            const SparcTargetLowering &TLI) {
16271e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  MachineFunction &MF = DAG.getMachineFunction();
16281e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
16291e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman
16301e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju  // Need frame address to find the address of VarArgsFrameIndex.
1631a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju  MF.getFrameInfo()->setFrameAddressIsTaken(true);
1632a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju
1633d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // vastart just stores the address of the VarArgsFrameIndex slot into the
1634d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // memory location argument.
1635ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
16361e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  SDValue Offset =
1637da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen    DAG.getNode(ISD::ADD, DL, TLI.getPointerTy(),
1638da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                DAG.getRegister(SP::I6, TLI.getPointerTy()),
1639da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset()));
1640d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1641da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1),
16426229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner                      MachinePointerInfo(SV), false, false, 0);
1643d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1644d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1645475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
1646ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  SDNode *Node = Op.getNode();
1647e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Node->getValueType(0);
1648475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InChain = Node->getOperand(0);
1649475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue VAListPtr = Node->getOperand(1);
1650da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  EVT PtrVT = VAListPtr.getValueType();
1651d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1652ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Node);
1653da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  SDValue VAList = DAG.getLoad(PtrVT, DL, InChain, VAListPtr,
1654d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                               MachinePointerInfo(SV), false, false, false, 0);
1655da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // Increment the pointer, VAList, to the next vaarg.
1656da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  SDValue NextPtr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
1657da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                                DAG.getIntPtrConstant(VT.getSizeInBits()/8));
1658da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // Store the incremented VAList to the legalized pointer.
1659da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  InChain = DAG.getStore(VAList.getValue(1), DL, NextPtr,
16606229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner                         VAListPtr, MachinePointerInfo(SV), false, false, 0);
1661da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // Load the actual argument out of the pointer VAList.
1662da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  // We can't count on greater alignment than the word size.
1663da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen  return DAG.getLoad(VT, DL, InChain, VAList, MachinePointerInfo(),
1664da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                     false, false, false,
1665da8768b2dd31e99679fa898bbce33d6a8bbf9395Jakob Stoklund Olesen                     std::min(PtrVT.getSizeInBits(), VT.getSizeInBits())/8);
1666d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1667d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1668475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) {
1669475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = Op.getOperand(0);  // Legalize the chain.
1670475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Size  = Op.getOperand(1);  // Legalize the size.
1671ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
167253835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1673d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  unsigned SPReg = SP::O6;
1674825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, MVT::i32);
1675825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDValue NewSP = DAG.getNode(ISD::SUB, dl, MVT::i32, SP, Size); // Value
1676a05dca4f9e051fad19fe9b5f6cce2715c1e5d505Dale Johannesen  Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);    // Output chain
167753835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1678d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // The resultant pointer is actually 16 words from the bottom of the stack,
1679d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // to provide a register spill area.
1680825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDValue NewVal = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP,
1681825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 DAG.getConstant(96, MVT::i32));
1682475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { NewVal, Chain };
1683a05dca4f9e051fad19fe9b5f6cce2715c1e5d505Dale Johannesen  return DAG.getMergeValues(Ops, 2, dl);
1684d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1685d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1686d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1687fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindarajustatic SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) {
1688ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1689fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju  SDValue Chain = DAG.getNode(SPISD::FLUSHW,
1690860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                              dl, MVT::Other, DAG.getEntryNode());
1691860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  return Chain;
1692860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju}
1693860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1694860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindarajustatic SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
1695860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
1696860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  MFI->setFrameAddressIsTaken(true);
1697860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1698860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  EVT VT = Op.getValueType();
1699ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1700860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  unsigned FrameReg = SP::I6;
1701860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1702860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  uint64_t depth = Op.getConstantOperandVal(0);
1703860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1704860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  SDValue FrameAddr;
1705fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju  if (depth == 0)
1706860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1707860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  else {
1708860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    // flush first to make sure the windowed registers' values are in stack
1709fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju    SDValue Chain = getFLUSHW(Op, DAG);
1710860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
1711fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju
1712860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    for (uint64_t i = 0; i != depth; ++i) {
1713fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju      SDValue Ptr = DAG.getNode(ISD::ADD,
1714860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                                dl, MVT::i32,
1715860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                                FrameAddr, DAG.getIntPtrConstant(56));
1716fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju      FrameAddr = DAG.getLoad(MVT::i32, dl,
1717fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju                              Chain,
1718860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                              Ptr,
1719d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                              MachinePointerInfo(), false, false, false, 0);
1720860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    }
1721860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  }
1722860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  return FrameAddr;
1723860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju}
1724860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1725860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindarajustatic SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
1726860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
1727860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  MFI->setReturnAddressIsTaken(true);
1728860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1729860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  EVT VT = Op.getValueType();
1730ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1731860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  unsigned RetReg = SP::I7;
1732860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1733860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  uint64_t depth = Op.getConstantOperandVal(0);
1734860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
1735860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  SDValue RetAddr;
1736fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju  if (depth == 0)
1737860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
1738860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  else {
17391e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju    // Need frame address to find return address of the caller.
1740a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju    MFI->setFrameAddressIsTaken(true);
1741a0b34d6c4ab05d0c04905e2aff0c9e6b879908ffVenkatraman Govindaraju
1742860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    // flush first to make sure the windowed registers' values are in stack
1743fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju    SDValue Chain = getFLUSHW(Op, DAG);
1744860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT);
1745fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju
1746860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    for (uint64_t i = 0; i != depth; ++i) {
1747fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju      SDValue Ptr = DAG.getNode(ISD::ADD,
1748860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                                dl, MVT::i32,
1749fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju                                RetAddr,
1750860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                                DAG.getIntPtrConstant((i == depth-1)?60:56));
1751fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju      RetAddr = DAG.getLoad(MVT::i32, dl,
1752fc3faa75cbadd8a1020941ec85adfda1d2f49688Venkatraman Govindaraju                            Chain,
1753860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju                            Ptr,
1754d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                            MachinePointerInfo(), false, false, false, 0);
1755860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju    }
1756860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  }
1757860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  return RetAddr;
1758860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju}
1759860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju
17601799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindarajustatic SDValue LowerF64Op(SDValue Op, SelectionDAG &DAG)
17611799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju{
17621799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  SDLoc dl(Op);
17631799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
17641799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  assert(Op.getValueType() == MVT::f64 && "LowerF64Op called on non-double!");
17651799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  assert(Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS);
17661799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
17671799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  // Lower fneg/fabs on f64 to fneg/fabs on f32.
17681799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  // fneg f64 => fneg f32:sub_even, fmov f32:sub_odd.
17691799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  // fabs f64 => fabs f32:sub_even, fmov f32:sub_odd.
17701799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
17711799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  SDValue SrcReg64 = Op.getOperand(0);
17721799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  SDValue Hi32 = DAG.getTargetExtractSubreg(SP::sub_even, dl, MVT::f32,
17731799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju                                            SrcReg64);
17741799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  SDValue Lo32 = DAG.getTargetExtractSubreg(SP::sub_odd, dl, MVT::f32,
17751799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju                                            SrcReg64);
17761799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
17771799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  Hi32 = DAG.getNode(Op.getOpcode(), dl, MVT::f32, Hi32);
17781799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
17791799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  SDValue DstReg64 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
17801799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju                                                dl, MVT::f64), 0);
17811799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  DstReg64 = DAG.getTargetInsertSubreg(SP::sub_even, dl, MVT::f64,
17821799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju                                       DstReg64, Hi32);
17831799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  DstReg64 = DAG.getTargetInsertSubreg(SP::sub_odd, dl, MVT::f64,
17841799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju                                       DstReg64, Lo32);
17851799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  return DstReg64;
17861799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju}
17871799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
1788475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SparcTargetLowering::
1789d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerOperation(SDValue Op, SelectionDAG &DAG) const {
1790d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  switch (Op.getOpcode()) {
1791c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Should not custom lower this!");
17921799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
17931799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  case ISD::FNEG:
17941799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju  case ISD::FABS:               return LowerF64Op(Op, DAG);
17951799921672835c49f6a29fc27d1840b7c36beabdVenkatraman Govindaraju
1796860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
1797860b64cb1efba110bf81bcc243a6fbaae4c655a4Venkatraman Govindaraju  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
1798d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::GlobalTLSAddress:
1799c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("TLS not implemented for Sparc.");
1800db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
1801e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju  case ISD::BlockAddress:       return LowerBlockAddress(Op, DAG);
1802db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
1803d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::FP_TO_SINT:         return LowerFP_TO_SINT(Op, DAG);
1804d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::SINT_TO_FP:         return LowerSINT_TO_FP(Op, DAG);
1805d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::BR_CC:              return LowerBR_CC(Op, DAG);
1806d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
1807d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::VASTART:            return LowerVASTART(Op, DAG, *this);
1808d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::VAARG:              return LowerVAARG(Op, DAG);
1809d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
1810d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
1811d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
1812d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1813d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris LattnerMachineBasicBlock *
1814d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris LattnerSparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1815af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                                 MachineBasicBlock *BB) const {
1816d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1817d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  unsigned BROpcode;
1818d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  unsigned CC;
1819d552eee4a05789e80ef3298df473edb888471302Dale Johannesen  DebugLoc dl = MI->getDebugLoc();
1820d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Figure out the conditional branch opcode to use for this select_cc.
1821d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  switch (MI->getOpcode()) {
1822c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown SELECT_CC!");
1823d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case SP::SELECT_CC_Int_ICC:
1824d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case SP::SELECT_CC_FP_ICC:
1825d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case SP::SELECT_CC_DFP_ICC:
1826d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    BROpcode = SP::BCOND;
1827d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    break;
1828d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case SP::SELECT_CC_Int_FCC:
1829d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case SP::SELECT_CC_FP_FCC:
1830d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  case SP::SELECT_CC_DFP_FCC:
1831d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    BROpcode = SP::FBCOND;
1832d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    break;
1833d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  }
1834d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner
1835d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  CC = (SPCC::CondCodes)MI->getOperand(3).getImm();
183653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1837d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1838d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // control-flow pattern.  The incoming instruction knows the destination vreg
1839d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // to set, the condition code register to branch on, the true/false values to
1840d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // select between, and a branch opcode to use.
1841d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  const BasicBlock *LLVM_BB = BB->getBasicBlock();
18428e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineFunction::iterator It = BB;
1843d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  ++It;
184453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1845d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //  thisMBB:
1846d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //  ...
1847d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //   TrueVal = ...
1848d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //   [f]bCC copy1MBB
1849d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //   fallthrough --> copy0MBB
1850d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  MachineBasicBlock *thisMBB = BB;
1851d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  MachineFunction *F = BB->getParent();
18528e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
18538e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1854f661277a9b26590648aca585c0572f200470290dVenkatraman Govindaraju  F->insert(It, copy0MBB);
1855f661277a9b26590648aca585c0572f200470290dVenkatraman Govindaraju  F->insert(It, sinkMBB);
185614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
185714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  // Transfer the remainder of BB and its successor edges to sinkMBB.
185814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  sinkMBB->splice(sinkMBB->begin(), BB,
185914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                  llvm::next(MachineBasicBlock::iterator(MI)),
186014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                  BB->end());
186114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
186214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
186314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  // Add the true and fallthrough blocks as its successors.
186414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BB->addSuccessor(copy0MBB);
186514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BB->addSuccessor(sinkMBB);
186614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
1867d552eee4a05789e80ef3298df473edb888471302Dale Johannesen  BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC);
186853835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1869d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //  copy0MBB:
1870d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //   %FalseValue = ...
1871d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //   # fallthrough to sinkMBB
1872d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  BB = copy0MBB;
187353835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1874d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  // Update machine-CFG edges
1875d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  BB->addSuccessor(sinkMBB);
187653835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
1877d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //  sinkMBB:
1878d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1879d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  //  ...
1880d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  BB = sinkMBB;
188114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*BB, BB->begin(), dl, TII.get(SP::PHI), MI->getOperand(0).getReg())
1882d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1883d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
188453835708e1540299eefdbbb70be2ebb1847dd3ebAnton Korobeynikov
188514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
1886d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner  return BB;
1887d23405e6f04135cabcad4d9bd7aa6e4f187bed3aChris Lattner}
18880eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov
18890eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//===----------------------------------------------------------------------===//
18900eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//                         Sparc Inline Assembly Support
18910eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov//===----------------------------------------------------------------------===//
18920eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov
18930eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
18940eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov/// constraint it is for this target.
18950eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::ConstraintType
18960eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::getConstraintType(const std::string &Constraint) const {
18970eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov  if (Constraint.size() == 1) {
18980eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    switch (Constraint[0]) {
18990eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    default:  break;
19000eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    case 'r': return C_RegisterClass;
19010eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    }
19020eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov  }
19030eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov
19040eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
19050eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov}
19060eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov
19070eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
19080eefda1335f5e86f95dbb58352321a43237e1089Anton KorobeynikovSparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
19095b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier                                                  MVT VT) const {
19100eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov  if (Constraint.size() == 1) {
19110eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    switch (Constraint[0]) {
19120eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    case 'r':
1913c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper      return std::make_pair(0U, &SP::IntRegsRegClass);
19140eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov    }
19150eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov  }
19160eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov
19170eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
19180eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov}
19190eefda1335f5e86f95dbb58352321a43237e1089Anton Korobeynikov
19206520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohmanbool
19216520e20e4fb31f2e65e25c38b372b19d33a83df4Dan GohmanSparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
19226520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman  // The Sparc target isn't yet aware of offsets.
19236520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman  return false;
19246520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman}
1925