1b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===-- llvm/CallingConvLower.cpp - Calling Convention lowering -----------===//
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 Hexagon_CCState class, used for lowering and
11b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// implementing calling conventions. Adapted from the machine independent
12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// version of the class (CCState) but this handles calls to varargs functions
13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
14b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonCallingConvLower.h"
1779aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "Hexagon.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
19b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Debug.h"
20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/ErrorHandling.h"
21b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/raw_ostream.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h"
24b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm;
25b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
26b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
27b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 const TargetMachine &tm,
28b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 SmallVector<CCValAssign, 16> &locs,
29b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 LLVMContext &c)
30b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  : CallingConv(CC), IsVarArg(isVarArg), TM(tm),
31b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    TRI(*TM.getRegisterInfo()), Locs(locs), Context(c) {
32b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // No stack is used.
33b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  StackOffset = 0;
34b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
35b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  UsedRegs.resize((TRI.getNumRegs()+31)/32);
36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// HandleByVal - Allocate a stack slot large enough to pass an argument by
39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// value. The size and alignment information of the argument is encoded in its
40b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// parameter attribute.
41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid Hexagon_CCState::HandleByVal(unsigned ValNo, EVT ValVT,
42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                EVT LocVT, CCValAssign::LocInfo LocInfo,
43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                int MinSize, int MinAlign,
44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                ISD::ArgFlagsTy ArgFlags) {
45b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Align = ArgFlags.getByValAlign();
46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Size  = ArgFlags.getByValSize();
47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MinSize > (int)Size)
48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Size = MinSize;
49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MinAlign > (int)Align)
50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Align = MinAlign;
51b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Offset = AllocateStack(Size, Align);
52b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset,
54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                             LocVT.getSimpleVT(), LocInfo));
55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
57b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// MarkAllocated - Mark a register and all of its aliases as allocated.
58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid Hexagon_CCState::MarkAllocated(unsigned Reg) {
59f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen  for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
60f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen    UsedRegs[*AI/32] |= 1 << (*AI&31);
61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node,
64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// incorporating info about the formals into this state.
65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
66b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg>
67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        &Ins,
68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        Hexagon_CCAssignFn Fn,
69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        unsigned SretValueInRegs) {
70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumArgs = Ins.size();
71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned i = 0;
72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If the function returns a small struct in registers, skip
74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // over the first (dummy) argument.
75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (SretValueInRegs != 0) {
76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ++i;
77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (; i != NumArgs; ++i) {
81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT ArgVT = Ins[i].VT;
82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this, 0, 0, false)) {
84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Formal argument #" << i << " has unhandled type "
85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             << ArgVT.getEVTString() << "\n";
86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeReturn - Analyze the returned values of an ISD::RET node,
92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// incorporating info about the result values into this state.
93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
94b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               Hexagon_CCAssignFn Fn,
96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               unsigned SretValueInRegs) {
97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For Hexagon, Return small structures in registers.
99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (SretValueInRegs != 0) {
100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (SretValueInRegs <= 32) {
101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned Reg = Hexagon::R0;
102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      addLoc(CCValAssign::getReg(0, MVT::i32, Reg, MVT::i32,
103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 CCValAssign::Full));
104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return;
105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (SretValueInRegs <= 64) {
107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned Reg = Hexagon::D0;
108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      addLoc(CCValAssign::getReg(0, MVT::i64, Reg, MVT::i64,
109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 CCValAssign::Full));
110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return;
111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Determine which register each value should be copied into.
116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT VT = Outs[i].VT;
118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this, -1, -1, false)){
120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Return operand #" << i << " has unhandled type "
121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           << VT.getEVTString() << "\n";
122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info
129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// about the passed values into this state.
130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
131b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg>
132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     &Outs,
133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     Hexagon_CCAssignFn Fn,
134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     int NonVarArgsParams,
135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     unsigned SretValueSize) {
136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumOps = Outs.size();
137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned i = 0;
139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If the called function returns a small struct in registers, skip
140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the first actual parameter. We do not want to pass a pointer to
141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the stack location.
142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (SretValueSize != 0) {
143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ++i;
144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (; i != NumOps; ++i) {
147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT ArgVT = Outs[i].VT;
148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this,
150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           NonVarArgsParams, i+1, false)) {
151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Call operand #" << i << " has unhandled type "
152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           << ArgVT.getEVTString() << "\n";
153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallOperands - Same as above except it takes vectors of types
159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// and argument flags.
160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
161b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeCallOperands(SmallVectorImpl<EVT> &ArgVTs,
162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     Hexagon_CCAssignFn Fn) {
164b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumOps = ArgVTs.size();
165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0; i != NumOps; ++i) {
166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT ArgVT = ArgVTs[i];
167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Flags[i];
168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this, -1, -1,
169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           false)) {
170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Call operand #" << i << " has unhandled type "
171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           << ArgVT.getEVTString() << "\n";
172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallResult - Analyze the return values of an ISD::CALL node,
178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// incorporating info about the passed values into this state.
179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
180b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   Hexagon_CCAssignFn Fn,
182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   unsigned SretValueInRegs) {
183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT VT = Ins[i].VT;
186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this, -1, -1, false)) {
188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        dbgs() << "Call result #" << i << " has unhandled type "
189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum               << VT.getEVTString() << "\n";
190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallResult - Same as above except it's specialized for calls which
196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// produce a single value.
197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid Hexagon_CCState::AnalyzeCallResult(EVT VT, Hexagon_CCAssignFn Fn) {
198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this, -1, -1,
199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         false)) {
200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    dbgs() << "Call result has unhandled type "
201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         << VT.getEVTString() << "\n";
202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    abort();
203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
205