1b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===-- HexagonISelLowering.cpp - Hexagon DAG Lowering Implementation -----===//
2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//                     The LLVM Compiler Infrastructure
4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source
6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details.
7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
10b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file implements the interfaces that Hexagon uses to lower LLVM code
11b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// into a selection DAG.
12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
14b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonISelLowering.h"
16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonMachineFunctionInfo.h"
17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonSubtarget.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "HexagonTargetMachine.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "HexagonTargetObjectFile.h"
20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/CallingConvLower.h"
21b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFrameInfo.h"
22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunction.h"
23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineInstrBuilder.h"
2479aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "llvm/CodeGen/MachineJumpTableInfo.h"
25b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineRegisterInfo.h"
26b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/SelectionDAGISel.h"
27b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/ValueTypes.h"
280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h"
290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalAlias.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h"
340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h"
35d2f16a292baed68a42f3db8e3c9d84030e3f4d09NAKAMURA Takumi#include "llvm/Support/CommandLine.h"
36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Debug.h"
37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/ErrorHandling.h"
388959393533bfbdcbbfe3c5f336729394896100ceNAKAMURA Takumi#include "llvm/Support/raw_ostream.h"
39d2f16a292baed68a42f3db8e3c9d84030e3f4d09NAKAMURA Takumi
4079aa3417eb6f58d668aadfedf075240a41d35a26Craig Topperusing namespace llvm;
41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumconst unsigned Hexagon_MAX_RET_SIZE = 64;
43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic cl::opt<bool>
45b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumEmitJumpTables("hexagon-emit-jump-tables", cl::init(true), cl::Hidden,
46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum               cl::desc("Control jump table emission on Hexagon target"));
47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumint NumNamedVarArgParams = -1;
49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Implement calling convention for Hexagon.
51b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
52b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCC_Hexagon(unsigned ValNo, MVT ValVT,
53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           MVT LocVT, CCValAssign::LocInfo LocInfo,
54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           ISD::ArgFlagsTy ArgFlags, CCState &State);
55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
57b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCC_Hexagon32(unsigned ValNo, MVT ValVT,
58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             MVT LocVT, CCValAssign::LocInfo LocInfo,
59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             ISD::ArgFlagsTy ArgFlags, CCState &State);
60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
62b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCC_Hexagon64(unsigned ValNo, MVT ValVT,
63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             MVT LocVT, CCValAssign::LocInfo LocInfo,
64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             ISD::ArgFlagsTy ArgFlags, CCState &State);
65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
67b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumRetCC_Hexagon(unsigned ValNo, MVT ValVT,
68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              MVT LocVT, CCValAssign::LocInfo LocInfo,
69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              ISD::ArgFlagsTy ArgFlags, CCState &State);
70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
72b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumRetCC_Hexagon32(unsigned ValNo, MVT ValVT,
73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                MVT LocVT, CCValAssign::LocInfo LocInfo,
74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                ISD::ArgFlagsTy ArgFlags, CCState &State);
75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
77b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumRetCC_Hexagon64(unsigned ValNo, MVT ValVT,
78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                MVT LocVT, CCValAssign::LocInfo LocInfo,
79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                ISD::ArgFlagsTy ArgFlags, CCState &State);
80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
82b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCC_Hexagon_VarArg (unsigned ValNo, MVT ValVT,
83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            MVT LocVT, CCValAssign::LocInfo LocInfo,
84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            ISD::ArgFlagsTy ArgFlags, CCState &State) {
85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // NumNamedVarArgParams can not be zero for a VarArg function.
87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  assert ( (NumNamedVarArgParams > 0) &&
88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           "NumNamedVarArgParams is not bigger than zero.");
89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if ( (int)ValNo < NumNamedVarArgParams ) {
91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Deal with named arguments.
92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return CC_Hexagon(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State);
93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Deal with un-named arguments.
96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned ofst;
97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (ArgFlags.isByVal()) {
98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // If pass-by-value, the size allocated on stack is decided
99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // by ArgFlags.getByValSize(), not by the size of LocVT.
100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    assert ((ArgFlags.getByValSize() > 8) &&
101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            "ByValSize must be bigger than 8 bytes");
102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ofst = State.AllocateStack(ArgFlags.getByValSize(), 4);
103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
106a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma  if (LocVT == MVT::i1 || LocVT == MVT::i8 || LocVT == MVT::i16) {
107a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma    LocVT = MVT::i32;
108a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma    ValVT = MVT::i32;
109a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma    if (ArgFlags.isSExt())
110a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma      LocInfo = CCValAssign::SExt;
111a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma    else if (ArgFlags.isZExt())
112a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma      LocInfo = CCValAssign::ZExt;
113a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma    else
114a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma      LocInfo = CCValAssign::AExt;
115a4dd8d67320d86ca7dfd88cb3d0c189cab713a88Jyotsna Verma  }
1167517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i32 || LocVT == MVT::f32) {
117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ofst = State.AllocateStack(4, 4);
118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1217517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i64 || LocVT == MVT::f64) {
122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ofst = State.AllocateStack(8, 8);
123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  llvm_unreachable(0);
127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool
131b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCC_Hexagon (unsigned ValNo, MVT ValVT,
132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            MVT LocVT, CCValAssign::LocInfo LocInfo,
133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            ISD::ArgFlagsTy ArgFlags, CCState &State) {
134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (ArgFlags.isByVal()) {
136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Passed on stack.
137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    assert ((ArgFlags.getByValSize() > 8) &&
138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            "ByValSize must be bigger than 8 bytes");
139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned Offset = State.AllocateStack(ArgFlags.getByValSize(), 4);
140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (LocVT == MVT::i1 || LocVT == MVT::i8 || LocVT == MVT::i16) {
145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    LocVT = MVT::i32;
146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ValVT = MVT::i32;
147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (ArgFlags.isSExt())
148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocInfo = CCValAssign::SExt;
149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else if (ArgFlags.isZExt())
150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocInfo = CCValAssign::ZExt;
151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocInfo = CCValAssign::AExt;
153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1557517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i32 || LocVT == MVT::f32) {
156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!CC_Hexagon32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))
157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1607517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i64 || LocVT == MVT::f64) {
161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!CC_Hexagon64(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))
162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
164b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;  // CC didn't match.
166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool CC_Hexagon32(unsigned ValNo, MVT ValVT,
170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         MVT LocVT, CCValAssign::LocInfo LocInfo,
171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         ISD::ArgFlagsTy ArgFlags, CCState &State) {
172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
173c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t RegList[] = {
174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Hexagon::R5
176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (unsigned Reg = State.AllocateReg(RegList, 6)) {
178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Offset = State.AllocateStack(4, 4);
183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool CC_Hexagon64(unsigned ValNo, MVT ValVT,
188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         MVT LocVT, CCValAssign::LocInfo LocInfo,
189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         ISD::ArgFlagsTy ArgFlags, CCState &State) {
190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (unsigned Reg = State.AllocateReg(Hexagon::D0)) {
192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
196c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t RegList1[] = {
197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Hexagon::D1, Hexagon::D2
198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
199c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t RegList2[] = {
200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Hexagon::R1, Hexagon::R3
201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (unsigned Reg = State.AllocateReg(RegList1, RegList2, 2)) {
203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Offset = State.AllocateStack(8, 8, Hexagon::D2);
208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
211b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
212b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool RetCC_Hexagon(unsigned ValNo, MVT ValVT,
213b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                          MVT LocVT, CCValAssign::LocInfo LocInfo,
214b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                          ISD::ArgFlagsTy ArgFlags, CCState &State) {
215b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
216b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
217b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (LocVT == MVT::i1 ||
218b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocVT == MVT::i8 ||
219b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocVT == MVT::i16) {
220b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    LocVT = MVT::i32;
221b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ValVT = MVT::i32;
222b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (ArgFlags.isSExt())
223b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocInfo = CCValAssign::SExt;
224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else if (ArgFlags.isZExt())
225b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocInfo = CCValAssign::ZExt;
226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      LocInfo = CCValAssign::AExt;
228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
2307517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i32 || LocVT == MVT::f32) {
231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!RetCC_Hexagon32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))
232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
2357517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i64 || LocVT == MVT::f64) {
236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!RetCC_Hexagon64(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))
237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
239b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;  // CC didn't match.
241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool RetCC_Hexagon32(unsigned ValNo, MVT ValVT,
244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            MVT LocVT, CCValAssign::LocInfo LocInfo,
245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            ISD::ArgFlagsTy ArgFlags, CCState &State) {
246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
2477517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i32 || LocVT == MVT::f32) {
248b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (unsigned Reg = State.AllocateReg(Hexagon::R0)) {
249b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
253b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
254b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Offset = State.AllocateStack(4, 4);
255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
258b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
259b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool RetCC_Hexagon64(unsigned ValNo, MVT ValVT,
260b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            MVT LocVT, CCValAssign::LocInfo LocInfo,
261b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            ISD::ArgFlagsTy ArgFlags, CCState &State) {
2627517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (LocVT == MVT::i64 || LocVT == MVT::f64) {
263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (unsigned Reg = State.AllocateReg(Hexagon::D0)) {
264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
268b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Offset = State.AllocateStack(8, 8);
270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
274b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
275b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG)
276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumconst {
277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return SDValue();
278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// by "Src" to address "Dst" of size "Size".  Alignment information is
282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// specified by the specific parameter attribute. The copy will be passed as
283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// a byval function parameter.  Sometimes what we are copying is the end of a
284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// larger object, the part that does not fit in registers.
285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic SDValue
286b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                          ISD::ArgFlagsTy Flags, SelectionDAG &DAG,
288ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                          SDLoc dl) {
289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32);
291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(),
292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       /*isVolatile=*/false, /*AlwaysInline=*/false,
293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       MachinePointerInfo(), MachinePointerInfo());
294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// LowerReturn - Lower ISD::RET. If a struct is larger than 8 bytes and is
298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// passed by value, the function prototype is modified to return void and
299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// the value is stored in memory pointed by a pointer passed by caller.
300b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
301b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerReturn(SDValue Chain,
302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   CallingConv::ID CallConv, bool isVarArg,
303b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   const SmallVectorImpl<ISD::OutputArg> &Outs,
304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   const SmallVectorImpl<SDValue> &OutVals,
305ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                   SDLoc dl, SelectionDAG &DAG) const {
306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
307b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // CCValAssign - represent the assignment of the return value to locations.
308b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<CCValAssign, 16> RVLocs;
309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // CCState - Info about the registers and stack slot.
311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
31256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Analyze return values of ISD::RET
315b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCInfo.AnalyzeReturn(Outs, RetCC_Hexagon);
316b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Flag;
31887b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
31987b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen
320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Copy the result values into the output registers.
321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0; i != RVLocs.size(); ++i) {
322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CCValAssign &VA = RVLocs[i];
323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag);
325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Guarantee that all emitted copies are stuck together with flags.
327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Flag = Chain.getValue(1);
32887b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
33187b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
33287b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen
33387b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen  // Add the flag if we have it.
334b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Flag.getNode())
33587b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen    RetOps.push_back(Flag);
336b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
33787b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen  return DAG.getNode(HexagonISD::RET_FLAG, dl, MVT::Other,
33887b87ad8fb8671efb5577dbfd40c02248862cc8dJakob Stoklund Olesen                     &RetOps[0], RetOps.size());
339b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
340b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
341b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
342b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
343b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
344b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// LowerCallResult - Lower the result values of an ISD::CALL into the
345b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// appropriate copies out of appropriate physical registers.  This assumes that
346b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call
347b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// being lowered. Returns a SDNode with the same number of values as the
348b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// ISD::CALL.
349b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
350b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
351b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       CallingConv::ID CallConv, bool isVarArg,
352b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       const
353b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       SmallVectorImpl<ISD::InputArg> &Ins,
354ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                       SDLoc dl, SelectionDAG &DAG,
355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       SmallVectorImpl<SDValue> &InVals,
356b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       const SmallVectorImpl<SDValue> &OutVals,
357b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       SDValue Callee) const {
358b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
359b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Assign locations to each value returned by this call.
360b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<CCValAssign, 16> RVLocs;
361b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
362b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
36356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
364b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
365b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCInfo.AnalyzeCallResult(Ins, RetCC_Hexagon);
366b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
367b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Copy all of the result registers out of their specified physreg.
368b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0; i != RVLocs.size(); ++i) {
369b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Chain = DAG.getCopyFromReg(Chain, dl,
370b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               RVLocs[i].getLocReg(),
371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               RVLocs[i].getValVT(), InFlag).getValue(1);
372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InFlag = Chain.getValue(2);
373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InVals.push_back(Chain.getValue(0));
374b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
375b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
376b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Chain;
377b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
378b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
379b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// LowerCall - Functions arguments are copied from virtual regs to
380b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
381b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
382d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiHexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
383b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 SmallVectorImpl<SDValue> &InVals) const {
384d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
385a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SDLoc &dl                             = CLI.DL;
386a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
387a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
388a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
389d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
390d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
391d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
392d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
393d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
394b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
395b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool IsStructRet    = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
396b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
397b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Analyze operands of the call, assigning locations to each operand.
398b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<CCValAssign, 16> ArgLocs;
399b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
40056cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
401b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
402b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Check for varargs.
403b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  NumNamedVarArgParams = -1;
404b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Callee))
405b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  {
406b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const Function* CalleeFn = NULL;
407b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Callee = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, MVT::i32);
408b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if ((CalleeFn = dyn_cast<Function>(GA->getGlobal())))
409b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    {
410b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // If a function has zero args and is a vararg function, that's
411b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // disallowed so it must be an undeclared function.  Do not assume
412b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // varargs if the callee is undefined.
413b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (CalleeFn->isVarArg() &&
414b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          CalleeFn->getFunctionType()->getNumParams() != 0) {
415b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        NumNamedVarArgParams = CalleeFn->getFunctionType()->getNumParams();
416b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
417b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
418b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
419b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
420b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (NumNamedVarArgParams > 0)
421b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_VarArg);
422b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  else
423b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon);
424b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
425b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
426b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if(isTailCall) {
427b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool StructAttrFlag =
428b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      DAG.getMachineFunction().getFunction()->hasStructRetAttr();
429b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
430b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                   isVarArg, IsStructRet,
431b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                   StructAttrFlag,
432b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                   Outs, OutVals, Ins, DAG);
433b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i){
434b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      CCValAssign &VA = ArgLocs[i];
435b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (VA.isMemLoc()) {
436b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        isTailCall = false;
437b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        break;
438b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
439b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
440b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (isTailCall) {
441b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      DEBUG(dbgs () << "Eligible for Tail Call\n");
442b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
443b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      DEBUG(dbgs () <<
444b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            "Argument must be passed on stack. Not eligible for Tail Call\n");
445b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
446b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
447b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Get a count of how many bytes are to be pushed on the stack.
448b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumBytes = CCInfo.getNextStackOffset();
449b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<std::pair<unsigned, SDValue>, 16> RegsToPass;
450b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<SDValue, 8> MemOpChains;
451b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
452b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue StackPtr =
453b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    DAG.getCopyFromReg(Chain, dl, TM.getRegisterInfo()->getStackRegister(),
454b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       getPointerTy());
455b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
456b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Walk the register/memloc assignments, inserting copies/loads.
457b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
458b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CCValAssign &VA = ArgLocs[i];
459b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    SDValue Arg = OutVals[i];
460b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy Flags = Outs[i].Flags;
461b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
462b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Promote the value if needed.
463b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    switch (VA.getLocInfo()) {
464b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      default:
465b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // Loc info must be one of Full, SExt, ZExt, or AExt.
466bc2198133a1836598b54b943420748e75d5dea94Craig Topper        llvm_unreachable("Unknown loc info!");
467b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      case CCValAssign::Full:
468b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        break;
469b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      case CCValAssign::SExt:
470b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
471b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        break;
472b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      case CCValAssign::ZExt:
473b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
474b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        break;
475b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      case CCValAssign::AExt:
476b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
477b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        break;
478b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
479b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
480b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (VA.isMemLoc()) {
481b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned LocMemOffset = VA.getLocMemOffset();
482b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      SDValue PtrOff = DAG.getConstant(LocMemOffset, StackPtr.getValueType());
483b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
484b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
485b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (Flags.isByVal()) {
486b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // The argument is a struct passed by value. According to LLVM, "Arg"
487b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // is is pointer.
488b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        MemOpChains.push_back(CreateCopyOfByValArgument(Arg, PtrOff, Chain,
489b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                        Flags, DAG, dl));
490b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
491b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // The argument is not passed by value. "Arg" is a buildin type. It is
492b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // not a pointer.
493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
494b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                           MachinePointerInfo(),false, false,
495b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                           0));
496b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      continue;
498b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
499b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
500b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Arguments that can be passed on register must be kept at RegsToPass
501b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // vector.
502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (VA.isRegLoc()) {
503b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
504b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
505b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
507b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Transform all store nodes into one single node because all store
508b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // nodes are independent of each other.
509b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!MemOpChains.empty()) {
510b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOpChains[0],
511b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                        MemOpChains.size());
512b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
513b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
514b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!isTailCall)
515b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes,
5166e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                                                        getPointerTy(), true),
5176e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                                 dl);
518b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
519b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Build a sequence of copy-to-reg nodes chained together with token
520b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // chain and flag operands which copy the outgoing args into registers.
521d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer  // The InFlag in necessary since all emitted instructions must be
522b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // stuck together.
523b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue InFlag;
524b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!isTailCall) {
525b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
526b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
527b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               RegsToPass[i].second, InFlag);
528b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      InFlag = Chain.getValue(1);
529b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
530b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
531b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
532b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For tail calls lower the arguments to the 'real' stack slot.
533b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isTailCall) {
534b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Force all the incoming stack arguments to be loaded from the stack
535b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // before any new outgoing arguments are stored to the stack, because the
536b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // outgoing stack slots may alias the incoming argument stack slots, and
537b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // the alias isn't otherwise explicit. This is slightly more conservative
538b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // than necessary, because it means that each store effectively depends
539b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // on every argument instead of just those arguments it would clobber.
540b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
541d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    // Do not flag preceding copytoreg stuff together with the following stuff.
542b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InFlag = SDValue();
543b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
544b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
545b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               RegsToPass[i].second, InFlag);
546b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      InFlag = Chain.getValue(1);
547b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
548b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InFlag =SDValue();
549b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
550b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
551b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
552b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
553b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // node so that legalize doesn't hack it.
554b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (flag_aligned_memcpy) {
555b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const char *MemcpyName =
556b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
557b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Callee =
558b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      DAG.getTargetExternalSymbol(MemcpyName, getPointerTy());
559b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    flag_aligned_memcpy = false;
560b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
561b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, getPointerTy());
562b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (ExternalSymbolSDNode *S =
563b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             dyn_cast<ExternalSymbolSDNode>(Callee)) {
564b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
565b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
566b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
567b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Returns a chain & a flag for retval copy to use.
568b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
569b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<SDValue, 8> Ops;
570b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  Ops.push_back(Chain);
571b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  Ops.push_back(Callee);
572b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
573b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Add argument registers to the end of the list so that they are
574b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // known live into the call.
575b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
576b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
577b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                  RegsToPass[i].second.getValueType()));
578b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
579b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
580b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (InFlag.getNode()) {
581b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Ops.push_back(InFlag);
582b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
583b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
584b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isTailCall)
585b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return DAG.getNode(HexagonISD::TC_RETURN, dl, NodeTys, &Ops[0], Ops.size());
586b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
587b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  Chain = DAG.getNode(HexagonISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
588b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  InFlag = Chain.getValue(1);
589b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
590b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Create the CALLSEQ_END node.
591b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
5926e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                             DAG.getIntPtrConstant(0, true), InFlag, dl);
593b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  InFlag = Chain.getValue(1);
594b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
595b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Handle result values, copying them out of physregs into vregs that we
596b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // return.
597b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, DAG,
598b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         InVals, OutVals, Callee);
599b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
600b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
601b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool getIndexedAddressParts(SDNode *Ptr, EVT VT,
602b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   bool isSEXTLoad, SDValue &Base,
603b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   SDValue &Offset, bool &isInc,
604b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   SelectionDAG &DAG) {
605b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Ptr->getOpcode() != ISD::ADD)
606b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
607b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
608b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (VT == MVT::i64 || VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) {
609b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    isInc = (Ptr->getOpcode() == ISD::ADD);
610b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Base = Ptr->getOperand(0);
611b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Offset = Ptr->getOperand(1);
612b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Ensure that Offset is a constant.
613b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return (isa<ConstantSDNode>(Offset));
614b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
615b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
616b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
617b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
618b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
619b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// TODO: Put this function along with the other isS* functions in
620b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// HexagonISelDAGToDAG.cpp into a common file. Or better still, use the
6216ee1e0867d24dff28683ec3525e61472c597b6afRafael Espindola// functions defined in HexagonOperands.td.
622b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool Is_PostInc_S4_Offset(SDNode * S, int ShiftAmount) {
623b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  ConstantSDNode *N = cast<ConstantSDNode>(S);
624b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
625b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // immS4 predicate - True if the immediate fits in a 4-bit sign extended.
626b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // field.
627b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  int64_t v = (int64_t)N->getSExtValue();
628b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  int64_t m = 0;
629b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (ShiftAmount > 0) {
630b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    m = v % ShiftAmount;
631b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    v = v >> ShiftAmount;
632b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
633b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return (v <= 7) && (v >= -8) && (m == 0);
634b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
635b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
636b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// getPostIndexedAddressParts - returns true by value, base pointer and
637b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// offset pointer and addressing mode by reference if this node can be
638b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// combined with a load / store to form a post-indexed load / store.
639b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
640b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                       SDValue &Base,
641b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                       SDValue &Offset,
642b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                       ISD::MemIndexedMode &AM,
643b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                       SelectionDAG &DAG) const
644b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum{
645b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  EVT VT;
646b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Ptr;
647b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool isSEXTLoad = false;
648b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
649b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
650b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    VT  = LD->getMemoryVT();
651b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
652b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
653b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    VT  = ST->getMemoryVT();
654b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (ST->getValue().getValueType() == MVT::i64 && ST->isTruncatingStore()) {
655b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
656b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
657b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else {
658b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
659b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
660b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
6616da0ef9ca408ac39ba3af76f5571756792511134Chad Rosier  bool isInc = false;
662b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool isLegal = getIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
663b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        isInc, DAG);
664b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // ShiftAmount = number of left-shifted bits in the Hexagon instruction.
665b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  int ShiftAmount = VT.getSizeInBits() / 16;
666b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isLegal && Is_PostInc_S4_Offset(Offset.getNode(), ShiftAmount)) {
667b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
668b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return true;
669b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
670b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
671b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
672b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
673b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
674b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue HexagonTargetLowering::LowerINLINEASM(SDValue Op,
675b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                              SelectionDAG &DAG) const {
676b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDNode *Node = Op.getNode();
677b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction &MF = DAG.getMachineFunction();
678b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  HexagonMachineFunctionInfo *FuncInfo =
679b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MF.getInfo<HexagonMachineFunctionInfo>();
680b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  switch (Node->getOpcode()) {
681b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::INLINEASM: {
682b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned NumOps = Node->getNumOperands();
683b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue)
684b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        --NumOps;  // Ignore the flag operand.
685b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
686b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
687b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        if (FuncInfo->hasClobberLR())
688b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          break;
689b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        unsigned Flags =
690b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
691b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
692b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        ++i;  // Skip the ID value.
693b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
694b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        switch (InlineAsm::getKind(Flags)) {
695b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        default: llvm_unreachable("Bad flags!");
696b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          case InlineAsm::Kind_RegDef:
697b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          case InlineAsm::Kind_RegUse:
698b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          case InlineAsm::Kind_Imm:
699b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          case InlineAsm::Kind_Clobber:
700b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          case InlineAsm::Kind_Mem: {
701b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            for (; NumVals; --NumVals, ++i) {}
702b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            break;
703b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          }
704b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          case InlineAsm::Kind_RegDefEarlyClobber: {
705b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            for (; NumVals; --NumVals, ++i) {
706b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              unsigned Reg =
707b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                cast<RegisterSDNode>(Node->getOperand(i))->getReg();
708b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
709b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              // Check it to be lr
710b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              if (Reg == TM.getRegisterInfo()->getRARegister()) {
711b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                FuncInfo->setHasClobberLR(true);
712b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                break;
713b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              }
714b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            }
715b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            break;
716b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          }
717b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        }
718b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
719b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
720b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } // Node->getOpcode
721b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Op;
722b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
723b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
724b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
725b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
726b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Taken from the XCore backend.
727b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
728b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue HexagonTargetLowering::
729b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumLowerBR_JT(SDValue Op, SelectionDAG &DAG) const
730b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum{
731b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Chain = Op.getOperand(0);
732b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Table = Op.getOperand(1);
733b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Index = Op.getOperand(2);
734ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
735b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
736b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned JTI = JT->getIndex();
737b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction &MF = DAG.getMachineFunction();
738b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
739b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
740b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
741b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Mark all jump table targets as address taken.
742b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const std::vector<MachineJumpTableEntry> &JTE = MJTI->getJumpTables();
743b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const std::vector<MachineBasicBlock*> &JTBBs = JTE[JTI].MBBs;
744b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
745b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock *MBB = JTBBs[i];
746b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MBB->setHasAddressTaken();
747b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // This line is needed to set the hasAddressTaken flag on the BasicBlock
748b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // object.
749b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BlockAddress::get(const_cast<BasicBlock *>(MBB->getBasicBlock()));
750b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
751b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
752b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue JumpTableBase = DAG.getNode(HexagonISD::WrapperJT, dl,
753b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      getPointerTy(), TargetJT);
754b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue ShiftIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index,
755b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   DAG.getConstant(2, MVT::i32));
756b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue JTAddress = DAG.getNode(ISD::ADD, dl, MVT::i32, JumpTableBase,
757b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                  ShiftIndex);
758b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue LoadTarget = DAG.getLoad(MVT::i32, dl, Chain, JTAddress,
759b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   MachinePointerInfo(), false, false, false,
760b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   0);
761b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return DAG.getNode(HexagonISD::BR_JT, dl, MVT::Other, Chain, LoadTarget);
762b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
763b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
764b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
765b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
766b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
767b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                               SelectionDAG &DAG) const {
768b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Chain = Op.getOperand(0);
769b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Size = Op.getOperand(1);
770ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
771b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
772b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned SPReg = getStackPointerRegisterToSaveRestore();
773b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
774b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Get a reference to the stack pointer.
775b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue StackPointer = DAG.getCopyFromReg(Chain, dl, SPReg, MVT::i32);
776b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
777b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Subtract the dynamic size from the actual stack size to
778b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // obtain the new stack size.
779b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Sub = DAG.getNode(ISD::SUB, dl, MVT::i32, StackPointer, Size);
780b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
781b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
782b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For Hexagon, the outgoing memory arguments area should be on top of the
783b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // alloca area on the stack i.e., the outgoing memory arguments should be
784b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // at a lower address than the alloca area. Move the alloca area down the
785b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // stack by adding back the space reserved for outgoing arguments to SP
786b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // here.
787b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
788b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // We do not know what the size of the outgoing args is at this point.
789b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
790b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // stack pointer. We patch this instruction with the correct, known
791b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // offset in emitPrologue().
792b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
793b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Use a placeholder immediate (zero) for now. This will be patched up
794b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // by emitPrologue().
795b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue ArgAdjust = DAG.getNode(HexagonISD::ADJDYNALLOC, dl,
796b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                  MVT::i32,
797b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                  Sub,
798b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                  DAG.getConstant(0, MVT::i32));
799b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
800b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // The Sub result contains the new stack start address, so it
801b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // must be placed in the stack pointer register.
802b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue CopyChain = DAG.getCopyToReg(Chain, dl,
803b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       TM.getRegisterInfo()->getStackRegister(),
804b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       Sub);
805b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
806b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Ops[2] = { ArgAdjust, CopyChain };
807b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return DAG.getMergeValues(Ops, 2, dl);
808b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
809b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
810b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
811b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerFormalArguments(SDValue Chain,
812b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            CallingConv::ID CallConv,
813b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            bool isVarArg,
814b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            const
815b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            SmallVectorImpl<ISD::InputArg> &Ins,
816ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                            SDLoc dl, SelectionDAG &DAG,
817b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            SmallVectorImpl<SDValue> &InVals)
818b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumconst {
819b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
820b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction &MF = DAG.getMachineFunction();
821b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFrameInfo *MFI = MF.getFrameInfo();
822b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineRegisterInfo &RegInfo = MF.getRegInfo();
823b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  HexagonMachineFunctionInfo *FuncInfo =
824b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MF.getInfo<HexagonMachineFunctionInfo>();
825b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
826b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
827b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Assign locations to all of the incoming arguments.
828b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<CCValAssign, 16> ArgLocs;
829b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
83056cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
831b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
832b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon);
833b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
834b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For LLVM, in the case when returning a struct by value (>8byte),
835b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the first argument is a pointer that points to the location on caller's
836b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // stack where the return value will be stored. For Hexagon, the location on
837b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // caller's stack is passed only when the struct size is smaller than (and
838b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // equal to) 8 bytes. If not, no address will be passed into callee and
839b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // callee return the result direclty through R0/R1.
840b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
841b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallVector<SDValue, 4> MemOps;
842b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
843b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
844b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CCValAssign &VA = ArgLocs[i];
845b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy Flags = Ins[i].Flags;
846b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned ObjSize;
847b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned StackLocation;
848b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int FI;
849b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
850b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (   (VA.isRegLoc() && !Flags.isByVal())
851b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        || (VA.isRegLoc() && Flags.isByVal() && Flags.getByValSize() > 8)) {
852b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Arguments passed in registers
853b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // 1. int, long long, ptr args that get allocated in register.
854b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // 2. Large struct that gets an register to put its address in.
855b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      EVT RegVT = VA.getLocVT();
8567517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      if (RegVT == MVT::i8 || RegVT == MVT::i16 ||
8577517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande          RegVT == MVT::i32 || RegVT == MVT::f32) {
858b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        unsigned VReg =
859420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper          RegInfo.createVirtualRegister(&Hexagon::IntRegsRegClass);
860b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        RegInfo.addLiveIn(VA.getLocReg(), VReg);
861b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT));
86237097623bbde5420f81ab8d1d056700f8f258025Chandler Carruth      } else if (RegVT == MVT::i64) {
863b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        unsigned VReg =
864420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper          RegInfo.createVirtualRegister(&Hexagon::DoubleRegsRegClass);
865b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        RegInfo.addLiveIn(VA.getLocReg(), VReg);
866b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT));
867b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
868b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        assert (0);
869b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
870b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else if (VA.isRegLoc() && Flags.isByVal() && Flags.getByValSize() <= 8) {
871b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert (0 && "ByValSize must be bigger than 8 bytes");
872b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
873b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Sanity check.
874b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert(VA.isMemLoc());
875b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
876b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (Flags.isByVal()) {
877b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // If it's a byval parameter, then we need to compute the
878b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // "real" size, not the size of the pointer.
879b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        ObjSize = Flags.getByValSize();
880b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
881b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        ObjSize = VA.getLocVT().getStoreSizeInBits() >> 3;
882b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
883b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
884b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      StackLocation = HEXAGON_LRFP_SIZE + VA.getLocMemOffset();
885b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Create the frame index object for this incoming parameter...
886b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      FI = MFI->CreateFixedObject(ObjSize, StackLocation, true);
887b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
888b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Create the SelectionDAG nodes cordl, responding to a load
889b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // from this parameter.
890b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
891b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
892b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (Flags.isByVal()) {
893b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // If it's a pass-by-value aggregate, then do not dereference the stack
894b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // location. Instead, we should generate a reference to the stack
895b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // location.
896b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        InVals.push_back(FIN);
897b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
898b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
899b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     MachinePointerInfo(), false, false,
900b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     false, 0));
901b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
902b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
903b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
904b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
905b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!MemOps.empty())
906b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOps[0],
907b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                        MemOps.size());
908b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
909b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isVarArg) {
910b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // This will point to the next argument passed via stack.
911b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int FrameIndex = MFI->CreateFixedObject(Hexagon_PointerSize,
912b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            HEXAGON_LRFP_SIZE +
913b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            CCInfo.getNextStackOffset(),
914b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            true);
915b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    FuncInfo->setVarArgsFrameIndex(FrameIndex);
916b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
917b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
918b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Chain;
919b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
920b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
921b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
922b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
923b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // VASTART stores the address of the VarArgsFrameIndex slot into the
924b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // memory location argument.
925b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction &MF = DAG.getMachineFunction();
926b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  HexagonMachineFunctionInfo *QFI = MF.getInfo<HexagonMachineFunctionInfo>();
927b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Addr = DAG.getFrameIndex(QFI->getVarArgsFrameIndex(), MVT::i32);
928b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
929ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getStore(Op.getOperand(0), SDLoc(Op), Addr,
930b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                      Op.getOperand(1), MachinePointerInfo(SV), false,
931b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                      false, 0);
932b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
933b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
934b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
935b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
9367517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue LHS = Op.getOperand(0);
9377517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue RHS = Op.getOperand(1);
9387517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue CC = Op.getOperand(4);
9397517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue TrueVal = Op.getOperand(2);
9407517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue FalseVal = Op.getOperand(3);
941ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
942b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDNode* OpNode = Op.getNode();
9437517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  EVT SVT = OpNode->getValueType(0);
9447517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
9457517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue Cond = DAG.getNode(ISD::SETCC, dl, MVT::i1, LHS, RHS, CC);
9467517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  return DAG.getNode(ISD::SELECT, dl, SVT, Cond, TrueVal, FalseVal);
9477517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande}
9487517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
9497517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish PandeSDValue
9507517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish PandeHexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
9517517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  EVT ValTy = Op.getValueType();
952ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
9537517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
9547517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  SDValue Res;
9557517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  if (CP->isMachineConstantPoolEntry())
9567517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), ValTy,
9577517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande                                    CP->getAlignment());
9587517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  else
9597517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    Res = DAG.getTargetConstantPool(CP->getConstVal(), ValTy,
9607517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande                                    CP->getAlignment());
9617517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  return DAG.getNode(HexagonISD::CONST32, dl, ValTy, Res);
962b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
963b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
964b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
965b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
966b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const TargetRegisterInfo *TRI = TM.getRegisterInfo();
967b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction &MF = DAG.getMachineFunction();
968b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFrameInfo *MFI = MF.getFrameInfo();
969b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MFI->setReturnAddressIsTaken(true);
970b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
971b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  EVT VT = Op.getValueType();
972ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
973b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
974b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Depth) {
975b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
976b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    SDValue Offset = DAG.getConstant(4, MVT::i32);
977b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return DAG.getLoad(VT, dl, DAG.getEntryNode(),
978b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
979b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       MachinePointerInfo(), false, false, false, 0);
980b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
981b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
982b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Return LR, which contains the return address. Mark it an implicit live-in.
983b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Reg = MF.addLiveIn(TRI->getRARegister(), getRegClassFor(MVT::i32));
984b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
985b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
986b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
987b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
988b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
989b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const HexagonRegisterInfo  *TRI = TM.getRegisterInfo();
990b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
991b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MFI->setFrameAddressIsTaken(true);
992b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
993b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  EVT VT = Op.getValueType();
994ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
995b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
996b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
997b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                         TRI->getFrameRegister(), VT);
998b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  while (Depth--)
999b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1000b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            MachinePointerInfo(),
1001b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            false, false, false, 0);
1002b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return FrameAddr;
1003b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1004b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1005b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op,
1006b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                 SelectionDAG& DAG) const {
1007ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1008b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
1009b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1010b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1011b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1012b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op,
1013b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                  SelectionDAG &DAG) const {
1014b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SDValue Result;
1015b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1016b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1017ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1018b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), Offset);
1019b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1020510db8bcb959fa69a93c42b58cb3e0ab28d03825Dmitri Gribenko  const HexagonTargetObjectFile &TLOF =
1021510db8bcb959fa69a93c42b58cb3e0ab28d03825Dmitri Gribenko      static_cast<const HexagonTargetObjectFile &>(getObjFileLowering());
1022b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) {
1023b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return DAG.getNode(HexagonISD::CONST32_GP, dl, getPointerTy(), Result);
1024b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1025b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1026b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return DAG.getNode(HexagonISD::CONST32, dl, getPointerTy(), Result);
1027b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1028b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1029b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna VermaSDValue
1030b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna VermaHexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
1031b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1032b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma  SDValue BA_SD =  DAG.getTargetBlockAddress(BA, MVT::i32);
1033ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1034b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma  return DAG.getNode(HexagonISD::CONST32_GP, dl, getPointerTy(), BA_SD);
1035b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma}
1036b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma
1037b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
1038b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// TargetLowering Implementation
1039b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
1040b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1041b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
1042b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                             &targetmachine)
1043b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  : TargetLowering(targetmachine, new HexagonTargetObjectFile()),
1044b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    TM(targetmachine) {
1045b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
10467517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    const HexagonRegisterInfo* QRI = TM.getRegisterInfo();
10477517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
1048b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Set up the register classes.
1049420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    addRegisterClass(MVT::i32, &Hexagon::IntRegsRegClass);
1050420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    addRegisterClass(MVT::i64, &Hexagon::DoubleRegsRegClass);
1051b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
10527517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    if (QRI->Subtarget.hasV5TOps()) {
10537517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      addRegisterClass(MVT::f32, &Hexagon::IntRegsRegClass);
10547517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      addRegisterClass(MVT::f64, &Hexagon::DoubleRegsRegClass);
10557517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    }
10567517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
1057420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    addRegisterClass(MVT::i1, &Hexagon::PredRegsRegClass);
1058b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1059b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    computeRegisterProperties();
1060b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1061b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Align loop entry
1062b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setPrefLoopAlignment(4);
1063b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1064b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Limits for inline expansion of memcpy/memmove
10653450f800aa65c91f0496816ba6061a422a74c1feJim Grosbach    MaxStoresPerMemcpy = 6;
10663450f800aa65c91f0496816ba6061a422a74c1feJim Grosbach    MaxStoresPerMemmove = 6;
1067b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1068b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
1069b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Library calls for unsupported operations
1070b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
1071b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1072b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::SINTTOFP_I128_F64, "__hexagon_floattidf");
1073b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::SINTTOFP_I128_F32, "__hexagon_floattisf");
1074b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1075b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::FPTOUINT_F32_I128, "__hexagon_fixunssfti");
1076b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::FPTOUINT_F64_I128, "__hexagon_fixunsdfti");
1077b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1078b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::FPTOSINT_F32_I128, "__hexagon_fixsfti");
1079b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::FPTOSINT_F64_I128, "__hexagon_fixdfti");
1080b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1081b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::SDIV_I32, "__hexagon_divsi3");
1082b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SDIV,  MVT::i32, Expand);
1083b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::SREM_I32, "__hexagon_umodsi3");
1084b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SREM,  MVT::i32, Expand);
1085b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1086b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::SDIV_I64, "__hexagon_divdi3");
1087b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SDIV,  MVT::i64, Expand);
1088b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::SREM_I64, "__hexagon_moddi3");
1089b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SREM,  MVT::i64, Expand);
1090b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1091b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::UDIV_I32, "__hexagon_udivsi3");
1092b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UDIV,  MVT::i32, Expand);
1093b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1094b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::UDIV_I64, "__hexagon_udivdi3");
1095b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UDIV,  MVT::i64, Expand);
1096b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1097b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::UREM_I32, "__hexagon_umodsi3");
1098b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UREM,  MVT::i32, Expand);
1099b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::UREM_I64, "__hexagon_umoddi3");
1101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UREM,  MVT::i64, Expand);
1102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::DIV_F32, "__hexagon_divsf3");
1104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FDIV,  MVT::f32, Expand);
1105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLibcallName(RTLIB::DIV_F64, "__hexagon_divdf3");
1107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FDIV,  MVT::f64, Expand);
1108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
11097517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    setOperationAction(ISD::FSQRT,  MVT::f32, Expand);
11107517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    setOperationAction(ISD::FSQRT,  MVT::f64, Expand);
11117517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    setOperationAction(ISD::FSIN,  MVT::f32, Expand);
11127517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    setOperationAction(ISD::FSIN,  MVT::f64, Expand);
11137517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11147517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    if (QRI->Subtarget.hasV5TOps()) {
11157517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // Hexagon V5 Support.
11167517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FADD,       MVT::f32, Legal);
11177517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FADD,       MVT::f64, Legal);
11187517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_EXTEND,  MVT::f32, Legal);
11197517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOEQ,      MVT::f32, Legal);
11207517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOEQ,      MVT::f64, Legal);
11217517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUEQ,      MVT::f32, Legal);
11227517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUEQ,      MVT::f64, Legal);
11237517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11247517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGE,      MVT::f32, Legal);
11257517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGE,      MVT::f64, Legal);
11267517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUGE,      MVT::f32, Legal);
11277517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUGE,      MVT::f64, Legal);
11287517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11297517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGT,      MVT::f32, Legal);
11307517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGT,      MVT::f64, Legal);
11317517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUGT,      MVT::f32, Legal);
11327517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUGT,      MVT::f64, Legal);
11337517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11347517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLE,      MVT::f32, Legal);
11357517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLE,      MVT::f64, Legal);
11367517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLT,      MVT::f32, Legal);
11377517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLT,      MVT::f64, Legal);
11387517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11397517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::ConstantFP,  MVT::f32, Legal);
11407517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::ConstantFP,  MVT::f64, Legal);
11417517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11427517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_UINT, MVT::i1, Promote);
11437517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::i1, Promote);
11447517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::UINT_TO_FP, MVT::i1, Promote);
11457517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SINT_TO_FP, MVT::i1, Promote);
11467517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11477517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_UINT, MVT::i8, Promote);
11487517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::i8, Promote);
11497517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
11507517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
11517517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11527517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_UINT, MVT::i16, Promote);
11537517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote);
11547517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
11557517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
11567517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11577517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
11587517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
11597517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
11607517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
11617517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11627517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_UINT, MVT::i64, Legal);
11637517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::i64, Legal);
11647517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::UINT_TO_FP, MVT::i64, Legal);
11657517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SINT_TO_FP, MVT::i64, Legal);
11667517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11677517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FABS,  MVT::f32, Legal);
11687517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FABS,  MVT::f64, Expand);
11697517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
11707517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FNEG,  MVT::f32, Legal);
11717517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FNEG,  MVT::f64, Expand);
11727517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    } else {
1173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
11747517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // Expand fp<->uint.
11757517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT,  MVT::i32, Expand);
11767517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_UINT,  MVT::i32, Expand);
1177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
11787517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SINT_TO_FP,  MVT::i32, Expand);
11797517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::UINT_TO_FP,  MVT::i32, Expand);
1180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
11817517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::SINTTOFP_I64_F32, "__hexagon_floatdisf");
11827517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UINTTOFP_I64_F32, "__hexagon_floatundisf");
118387eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
11847517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UINTTOFP_I32_F32, "__hexagon_floatunsisf");
11857517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::SINTTOFP_I32_F32, "__hexagon_floatsisf");
118687eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
11877517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::SINTTOFP_I64_F64, "__hexagon_floatdidf");
11887517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UINTTOFP_I64_F64, "__hexagon_floatundidf");
118987eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
11907517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UINTTOFP_I32_F64, "__hexagon_floatunsidf");
11917517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::SINTTOFP_I32_F64, "__hexagon_floatsidf");
119287eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
11937517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOUINT_F32_I32, "__hexagon_fixunssfsi");
11947517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOUINT_F32_I64, "__hexagon_fixunssfdi");
1195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
11967517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOSINT_F64_I64, "__hexagon_fixdfdi");
11977517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOSINT_F32_I64, "__hexagon_fixsfdi");
1198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
11997517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOUINT_F64_I32, "__hexagon_fixunsdfsi");
12007517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOUINT_F64_I64, "__hexagon_fixunsdfdi");
120115e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12027517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::ADD_F64, "__hexagon_adddf3");
12037517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FADD,  MVT::f64, Expand);
120415e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12057517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::ADD_F32, "__hexagon_addsf3");
12067517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FADD,  MVT::f32, Expand);
120715e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12087517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPEXT_F32_F64, "__hexagon_extendsfdf2");
12097517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_EXTEND,  MVT::f32, Expand);
121015e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12117517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OEQ_F32, "__hexagon_eqsf2");
12127517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);
121315e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12147517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OEQ_F64, "__hexagon_eqdf2");
12157517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);
1216b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12177517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OGE_F32, "__hexagon_gesf2");
12187517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGE, MVT::f32, Expand);
1219b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12207517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OGE_F64, "__hexagon_gedf2");
12217517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGE, MVT::f64, Expand);
12227517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12237517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OGT_F32, "__hexagon_gtsf2");
12247517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGT, MVT::f32, Expand);
12257517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12267517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OGT_F64, "__hexagon_gtdf2");
12277517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOGT, MVT::f64, Expand);
12287517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12297517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOSINT_F64_I32, "__hexagon_fixdfsi");
12307517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::f64, Expand);
12317517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12327517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPTOSINT_F32_I32, "__hexagon_fixsfsi");
12337517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_TO_SINT, MVT::f32, Expand);
12347517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12357517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OLE_F64, "__hexagon_ledf2");
12367517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLE, MVT::f64, Expand);
1237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12387517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OLE_F32, "__hexagon_lesf2");
12397517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLE, MVT::f32, Expand);
1240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12417517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OLT_F64, "__hexagon_ltdf2");
12427517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLT, MVT::f64, Expand);
1243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12447517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::OLT_F32, "__hexagon_ltsf2");
12457517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETOLT, MVT::f32, Expand);
1246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12477517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::MUL_F64, "__hexagon_muldf3");
12487517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FMUL, MVT::f64, Expand);
1249b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12507517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::MUL_F32, "__hexagon_mulsf3");
12517517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::MUL, MVT::f32, Expand);
1252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12537517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UNE_F64, "__hexagon_nedf2");
12547517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUNE, MVT::f64, Expand);
1255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
12567517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UNE_F32, "__hexagon_nesf2");
125787eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
12587517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::SUB_F64, "__hexagon_subdf3");
12597517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SUB, MVT::f64, Expand);
126087eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
12617517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::SUB_F32, "__hexagon_subsf3");
12627517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SUB, MVT::f32, Expand);
126387eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
12647517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::FPROUND_F64_F32, "__hexagon_truncdfsf2");
12657517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FP_ROUND, MVT::f64, Expand);
126687eb92d913c2e3cdeb08b0a22250cd6c3214a3ffSirish Pande
12677517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UO_F64, "__hexagon_unorddf2");
12687517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUO, MVT::f64, Expand);
126915e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12707517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::O_F64, "__hexagon_unorddf2");
12717517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETO, MVT::f64, Expand);
127215e56ad8855ff2d135a79efa71b540852acf3b97Sirish Pande
12737517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::O_F32, "__hexagon_unordsf2");
12747517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETO, MVT::f32, Expand);
12757517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12767517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setLibcallName(RTLIB::UO_F32, "__hexagon_unordsf2");
12777517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setCondCodeAction(ISD::SETUO, MVT::f32, Expand);
12787517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12797517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FABS,  MVT::f32, Expand);
12807517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FABS,  MVT::f64, Expand);
12817517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FNEG,  MVT::f32, Expand);
12827517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::FNEG,  MVT::f64, Expand);
12837517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    }
12847517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
12857517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    setLibcallName(RTLIB::SREM_I32, "__hexagon_modsi3");
12867517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    setOperationAction(ISD::SREM, MVT::i32, Expand);
1287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
1289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
1290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedLoadAction(ISD::POST_INC, MVT::i32, Legal);
1291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedLoadAction(ISD::POST_INC, MVT::i64, Legal);
1292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedStoreAction(ISD::POST_INC, MVT::i8, Legal);
1294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedStoreAction(ISD::POST_INC, MVT::i16, Legal);
1295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedStoreAction(ISD::POST_INC, MVT::i32, Legal);
1296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setIndexedStoreAction(ISD::POST_INC, MVT::i64, Legal);
1297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
1299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Turn FP extload into load/fextend.
1301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
1302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Hexagon has a i1 sign extending load.
1303b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Expand);
1304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Turn FP truncstore into trunc + store.
1305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
1306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1307b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Custom legalize GlobalAddress nodes into CONST32.
1308b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
1309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
1310b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma    setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
1311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Truncate action?
1312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::TRUNCATE, MVT::i64, Expand);
1313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Hexagon doesn't have sext_inreg, replace them with shl/sra.
1315b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
1316b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Hexagon has no REM or DIVREM operations.
1318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UREM, MVT::i32, Expand);
1319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SREM, MVT::i32, Expand);
1320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
1321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
1322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SREM, MVT::i64, Expand);
1323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
1324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
1325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::BSWAP, MVT::i64, Expand);
1327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1328b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Lower SELECT_CC to SETCC and SELECT.
1329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SELECT_CC, MVT::i32,   Custom);
1330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SELECT_CC, MVT::i64,   Custom);
13317517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13327517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    if (QRI->Subtarget.hasV5TOps()) {
13337517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13347517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // We need to make the operation type of SELECT node to be Custom,
13357517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // such that we don't go into the infinite loop of
13367517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // select ->  setcc -> select_cc -> select loop.
13377517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT, MVT::f32, Custom);
13387517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT, MVT::f64, Custom);
13397517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13407517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
13417517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
13427517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
13437517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13447517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    } else {
13457517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13467517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // Hexagon has no select or setcc: expand to SELECT_CC.
13477517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT, MVT::f32, Expand);
13487517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT, MVT::f64, Expand);
13497517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13507517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // This is a workaround documented in DAGCombiner.cpp:2892 We don't
13517517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      // support SELECT_CC on every type.
13527517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande      setOperationAction(ISD::SELECT_CC, MVT::Other,   Expand);
13537517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
13547517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    }
1355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1356b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (EmitJumpTables) {
1357b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      setOperationAction(ISD::BR_JT, MVT::Other, Custom);
1358b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
1359b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      setOperationAction(ISD::BR_JT, MVT::Other, Expand);
1360b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
13611a37d7e807ad6cc71fe3cffdf6674644c46a60ebSebastian Pop    // Increase jump tables cutover to 5, was 4.
13621a37d7e807ad6cc71fe3cffdf6674644c46a60ebSebastian Pop    setMinimumJumpTableEntries(5);
1363b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
13643ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard    setOperationAction(ISD::BR_CC, MVT::f32, Expand);
13653ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard    setOperationAction(ISD::BR_CC, MVT::f64, Expand);
13663ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard    setOperationAction(ISD::BR_CC, MVT::i1,  Expand);
1367b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::BR_CC, MVT::i32, Expand);
13680e58d92628486aee7e4745d451c37a9b409adf7aJyotsna Verma    setOperationAction(ISD::BR_CC, MVT::i64, Expand);
1369b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1370b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
1371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FSIN , MVT::f64, Expand);
1373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FCOS , MVT::f64, Expand);
1374b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FREM , MVT::f64, Expand);
1375b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FSIN , MVT::f32, Expand);
1376b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FCOS , MVT::f32, Expand);
1377b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FREM , MVT::f32, Expand);
13788688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng    setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
13798688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng    setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
138018daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma
138118daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    // In V4, we have double word add/sub with carry. The problem with
138218daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    // modelling this instruction is that it produces 2 results - Rdd and Px.
138318daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    // To model update of Px, we will have to use Defs[p0..p3] which will
138418daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    // cause any predicate live range to spill. So, we pretend we dont't
138518daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    // have these instructions.
138618daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDE, MVT::i8, Expand);
138718daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDE, MVT::i16, Expand);
138818daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDE, MVT::i32, Expand);
138918daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDE, MVT::i64, Expand);
139018daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBE, MVT::i8, Expand);
139118daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBE, MVT::i16, Expand);
139218daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBE, MVT::i32, Expand);
139318daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBE, MVT::i64, Expand);
139418daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDC, MVT::i8, Expand);
139518daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDC, MVT::i16, Expand);
139618daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDC, MVT::i32, Expand);
139718daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::ADDC, MVT::i64, Expand);
139818daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBC, MVT::i8, Expand);
139918daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBC, MVT::i16, Expand);
140018daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBC, MVT::i32, Expand);
140118daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma    setOperationAction(ISD::SUBC, MVT::i64, Expand);
140218daead3ff41902a61ff3344cfa77ac8aba5586dJyotsna Verma
1403b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::CTPOP, MVT::i32, Expand);
14046585d3b64b04b788faad79ba6cf4e592ebf4658dAnshuman Dasgupta    setOperationAction(ISD::CTPOP, MVT::i64, Expand);
1405b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::CTTZ , MVT::i32, Expand);
14066585d3b64b04b788faad79ba6cf4e592ebf4658dAnshuman Dasgupta    setOperationAction(ISD::CTTZ , MVT::i64, Expand);
140763974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth    setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
14086585d3b64b04b788faad79ba6cf4e592ebf4658dAnshuman Dasgupta    setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);
1409b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::CTLZ , MVT::i32, Expand);
14106585d3b64b04b788faad79ba6cf4e592ebf4658dAnshuman Dasgupta    setOperationAction(ISD::CTLZ , MVT::i64, Expand);
141163974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
14126585d3b64b04b788faad79ba6cf4e592ebf4658dAnshuman Dasgupta    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Expand);
1413b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::ROTL , MVT::i32, Expand);
1414b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::ROTR , MVT::i32, Expand);
1415b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::BSWAP, MVT::i32, Expand);
1416b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
1417b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
1418b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FPOW , MVT::f64, Expand);
1419b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::FPOW , MVT::f32, Expand);
1420b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1421b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
1422b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
1423b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
1424b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1425b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
1426b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
1427b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1428b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
1429b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
1430b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
14316ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma    setOperationAction(ISD::EH_RETURN,     MVT::Other, Custom);
1432b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1433b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (TM.getSubtargetImpl()->isSubtargetV2()) {
1434b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      setExceptionPointerRegister(Hexagon::R20);
1435b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      setExceptionSelectorRegister(Hexagon::R21);
1436b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
1437b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      setExceptionPointerRegister(Hexagon::R0);
1438b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      setExceptionSelectorRegister(Hexagon::R1);
1439b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
1440b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1441b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
1442b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::VASTART           , MVT::Other, Custom);
1443b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1444b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Use the default implementation.
1445b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::VAARG             , MVT::Other, Expand);
1446b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::VACOPY            , MVT::Other, Expand);
1447b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::VAEND             , MVT::Other, Expand);
1448b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::STACKSAVE         , MVT::Other, Expand);
1449b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
1450b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1451b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1452b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
1453b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setOperationAction(ISD::INLINEASM         , MVT::Other, Custom);
1454b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1455b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setMinFunctionAlignment(2);
1456b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1457b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Needed for DYNAMIC_STACKALLOC expansion.
1458b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned StackRegister = TM.getRegisterInfo()->getStackRegister();
1459b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    setStackPointerRegisterToSaveRestore(StackRegister);
1460ee498d3254b86bceb4f441741e9f442990647ce6Andrew Trick    setSchedulingPreference(Sched::VLIW);
1461b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1462b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1463b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1464b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumconst char*
1465b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
1466b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  switch (Opcode) {
1467b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    default: return 0;
14687517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::CONST32:     return "HexagonISD::CONST32";
1469b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma    case HexagonISD::CONST32_GP: return "HexagonISD::CONST32_GP";
1470b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma    case HexagonISD::CONST32_Int_Real: return "HexagonISD::CONST32_Int_Real";
1471b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case HexagonISD::ADJDYNALLOC: return "HexagonISD::ADJDYNALLOC";
14727517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::CMPICC:      return "HexagonISD::CMPICC";
14737517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::CMPFCC:      return "HexagonISD::CMPFCC";
14747517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::BRICC:       return "HexagonISD::BRICC";
14757517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::BRFCC:       return "HexagonISD::BRFCC";
14767517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::SELECT_ICC:  return "HexagonISD::SELECT_ICC";
14777517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::SELECT_FCC:  return "HexagonISD::SELECT_FCC";
14787517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::Hi:          return "HexagonISD::Hi";
14797517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::Lo:          return "HexagonISD::Lo";
14807517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::FTOI:        return "HexagonISD::FTOI";
14817517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::ITOF:        return "HexagonISD::ITOF";
14827517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::CALL:        return "HexagonISD::CALL";
14837517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::RET_FLAG:    return "HexagonISD::RET_FLAG";
14847517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::BR_JT:       return "HexagonISD::BR_JT";
14857517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case HexagonISD::TC_RETURN:   return "HexagonISD::TC_RETURN";
14866ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  case HexagonISD::EH_RETURN: return "HexagonISD::EH_RETURN";
1487b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1488b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1489b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1490b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool
1491b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
1492b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  EVT MTy1 = EVT::getEVT(Ty1);
1493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  EVT MTy2 = EVT::getEVT(Ty2);
1494b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!MTy1.isSimple() || !MTy2.isSimple()) {
1495b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1496b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return ((MTy1.getSimpleVT() == MVT::i64) && (MTy2.getSimpleVT() == MVT::i32));
1498b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1499b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1500b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
1501b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!VT1.isSimple() || !VT2.isSimple()) {
1502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1503b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1504b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return ((VT1.getSimpleVT() == MVT::i64) && (VT2.getSimpleVT() == MVT::i32));
1505b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1507d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northoverbool
1508d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim NorthoverHexagonTargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const {
1509d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  // Assuming the caller does not have either a signext or zeroext modifier, and
1510d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  // only one value is accepted, any reasonable truncation is allowed.
1511d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1512d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover    return false;
1513d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover
1514d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  // FIXME: in principle up to 64-bit could be made safe, but it would be very
1515d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  // fragile at the moment: any support for multiple value returns would be
1516d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  // liable to disallow tail calls involving i64 -> iN truncation in many cases.
1517d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover  return Ty1->getPrimitiveSizeInBits() <= 32;
1518d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover}
1519d113448c1dd5f40522c3c02db96e87a9eb59eaf4Tim Northover
1520b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDValue
15216ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna VermaHexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
15226ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  SDValue Chain     = Op.getOperand(0);
15236ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  SDValue Offset    = Op.getOperand(1);
15246ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  SDValue Handler   = Op.getOperand(2);
1525ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
15266ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma
15276ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  // Mark function as containing a call to EH_RETURN.
15286ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  HexagonMachineFunctionInfo *FuncInfo =
15296ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma    DAG.getMachineFunction().getInfo<HexagonMachineFunctionInfo>();
15306ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  FuncInfo->setHasEHReturn();
15316ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma
15326ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  unsigned OffsetReg = Hexagon::R28;
15336ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma
15346ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  SDValue StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(),
15356ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma                                  DAG.getRegister(Hexagon::R30, getPointerTy()),
15366ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma                                  DAG.getIntPtrConstant(4));
15376ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo(),
15386ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma                       false, false, 0);
15396ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset);
15406ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma
15416ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  // Not needed we already use it as explict input to EH_RETURN.
15426ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  // MF.getRegInfo().addLiveOut(OffsetReg);
15436ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma
15446ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma  return DAG.getNode(HexagonISD::EH_RETURN, dl, MVT::Other, Chain);
15456ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma}
15466ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma
15476ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna VermaSDValue
1548b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1549b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  switch (Op.getOpcode()) {
1550bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Should not custom lower this!");
15517517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
15526ea706e40e841c148bc47bcac4dcca5e0f0245ebJyotsna Verma    case ISD::EH_RETURN:          return LowerEH_RETURN(Op, DAG);
1553b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Frame & Return address.  Currently unimplemented.
15547517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
15557517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
1556b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::GlobalTLSAddress:
1557bc2198133a1836598b54b943420748e75d5dea94Craig Topper                          llvm_unreachable("TLS not implemented for Hexagon.");
1558b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::ATOMIC_FENCE:       return LowerATOMIC_FENCE(Op, DAG);
1559b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::GlobalAddress:      return LowerGLOBALADDRESS(Op, DAG);
1560b6716187ca8cc33817fb7446d9d9bdcb708c3f35Jyotsna Verma    case ISD::BlockAddress:       return LowerBlockAddress(Op, DAG);
1561b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::VASTART:            return LowerVASTART(Op, DAG);
1562b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::BR_JT:              return LowerBR_JT(Op, DAG);
1563b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1564b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
15657517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
15667517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case ISD::SELECT:             return Op;
1567b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
15687517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande    case ISD::INLINEASM:          return LowerINLINEASM(Op, DAG);
1569b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1570b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1571b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1572b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1573b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1574b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1575b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
1576b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//                           Hexagon Scheduler Hooks
1577b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
1578b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumMachineBasicBlock *
1579b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1580b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                   MachineBasicBlock *BB)
1581b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumconst {
1582b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  switch (MI->getOpcode()) {
1583b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case Hexagon::ADJDYNALLOC: {
1584b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MachineFunction *MF = BB->getParent();
1585b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      HexagonMachineFunctionInfo *FuncInfo =
1586b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        MF->getInfo<HexagonMachineFunctionInfo>();
1587b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      FuncInfo->addAllocaAdjustInst(MI);
1588b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return BB;
1589b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
1590bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unexpected instr type to insert");
1591b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } // switch
1592b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1593b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1594b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
1595b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Inline Assembly Support
1596b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
1597b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1598b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstd::pair<unsigned, const TargetRegisterClass*>
1599b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonTargetLowering::getRegForInlineAsmConstraint(const
1600b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                    std::string &Constraint,
16015b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier                                                    MVT VT) const {
1602b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Constraint.size() == 1) {
1603b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    switch (Constraint[0]) {
1604b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case 'r':   // R0-R31
16055b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier       switch (VT.SimpleTy) {
1606b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       default:
1607bc2198133a1836598b54b943420748e75d5dea94Craig Topper         llvm_unreachable("getRegForInlineAsmConstraint Unhandled data type");
1608b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       case MVT::i32:
1609b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       case MVT::i16:
1610b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       case MVT::i8:
16117517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande       case MVT::f32:
1612420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper         return std::make_pair(0U, &Hexagon::IntRegsRegClass);
1613b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       case MVT::i64:
16147517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande       case MVT::f64:
1615420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper         return std::make_pair(0U, &Hexagon::DoubleRegsRegClass);
1616b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
1617b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    default:
1618bc2198133a1836598b54b943420748e75d5dea94Craig Topper      llvm_unreachable("Unknown asm register class");
1619b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
1620b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1621b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1622b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
1623b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1624b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
16257517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande/// isFPImmLegal - Returns true if the target can instruction select the
16267517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande/// specified FP immediate natively. If false, the legalizer will
16277517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande/// materialize the FP immediate as a load from a constant pool.
16287517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pandebool HexagonTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
16297517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  const HexagonRegisterInfo* QRI = TM.getRegisterInfo();
16307517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande  return QRI->Subtarget.hasV5TOps();
16317517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande}
16327517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande
1633b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// isLegalAddressingMode - Return true if the addressing mode represented by
1634b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AM is legal for this target, for a load/store of the specified type.
1635b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonTargetLowering::isLegalAddressingMode(const AddrMode &AM,
1636b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                  Type *Ty) const {
1637b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Allows a signed-extended 11-bit immediate field.
1638b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (AM.BaseOffs <= -(1LL << 13) || AM.BaseOffs >= (1LL << 13)-1) {
1639b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1640b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1641b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1642b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // No global is ever allowed as a base.
1643b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (AM.BaseGV) {
1644b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1645b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1646b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1647b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  int Scale = AM.Scale;
1648b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Scale < 0) Scale = -Scale;
1649b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  switch (Scale) {
1650b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case 0:  // No scale reg, "r+i", "r", or just "i".
1651b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    break;
1652b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  default: // No scaled addressing mode.
1653b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1654b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1655b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;
1656b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1657b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1658b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// isLegalICmpImmediate - Return true if the specified immediate is legal
1659b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// icmp immediate, that is the target has icmp instructions which can compare
1660b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// a register against the immediate without having to materialize the
1661b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// immediate into a register.
1662b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
1663b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Imm >= -512 && Imm <= 511;
1664b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1665b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1666b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// IsEligibleForTailCallOptimization - Check whether the call is eligible
1667b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// for tail call optimization. Targets which want to do tail call
1668b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// optimization should implement this function.
1669b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonTargetLowering::IsEligibleForTailCallOptimization(
1670b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 SDValue Callee,
1671b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 CallingConv::ID CalleeCC,
1672b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 bool isVarArg,
1673b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 bool isCalleeStructRet,
1674b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 bool isCallerStructRet,
1675b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 const SmallVectorImpl<ISD::OutputArg> &Outs,
1676b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 const SmallVectorImpl<SDValue> &OutVals,
1677b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 const SmallVectorImpl<ISD::InputArg> &Ins,
1678b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 SelectionDAG& DAG) const {
1679b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const Function *CallerF = DAG.getMachineFunction().getFunction();
1680b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CallingConv::ID CallerCC = CallerF->getCallingConv();
1681b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool CCMatch = CallerCC == CalleeCC;
1682b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1683b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // ***************************************************************************
1684b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  Look for obvious safe cases to perform tail call optimization that do not
1685b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  require ABI changes.
1686b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // ***************************************************************************
1687b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1688b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If this is a tail call via a function pointer, then don't do it!
1689b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!(dyn_cast<GlobalAddressSDNode>(Callee))
1690b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      && !(dyn_cast<ExternalSymbolSDNode>(Callee))) {
1691b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1692b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
1693b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1694b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Do not optimize if the calling conventions do not match.
1695b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!CCMatch)
1696b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1697b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1698b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Do not tail call optimize vararg calls.
1699b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isVarArg)
1700b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1701b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1702b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Also avoid tail call optimization if either caller or callee uses struct
1703b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // return semantics.
1704b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isCalleeStructRet || isCallerStructRet)
1705b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
1706b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
1707b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // In addition to the cases above, we also disable Tail Call Optimization if
1708b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the calling convention code that at least one outgoing argument needs to
1709b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // go on the stack. We cannot check that here because at this point that
1710b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // information is not available.
1711b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;
1712b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
1713