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"
18b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetRegisterInfo.h"
19b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetData.h"
20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetMachine.h"
21b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Debug.h"
22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/ErrorHandling.h"
23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/raw_ostream.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) {
59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  UsedRegs[Reg/32] |= 1 << (Reg&31);
60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
61e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper  if (const uint16_t *RegAliases = TRI.getAliasSet(Reg))
62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    for (; (Reg = *RegAliases); ++RegAliases)
63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      UsedRegs[Reg/32] |= 1 << (Reg&31);
64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node,
67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// incorporating info about the formals into this state.
68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
69b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg>
70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        &Ins,
71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        Hexagon_CCAssignFn Fn,
72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        unsigned SretValueInRegs) {
73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumArgs = Ins.size();
74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned i = 0;
75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If the function returns a small struct in registers, skip
77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // over the first (dummy) argument.
78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (SretValueInRegs != 0) {
79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ++i;
80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (; i != NumArgs; ++i) {
84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT ArgVT = Ins[i].VT;
85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this, 0, 0, false)) {
87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Formal argument #" << i << " has unhandled type "
88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             << ArgVT.getEVTString() << "\n";
89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeReturn - Analyze the returned values of an ISD::RET node,
95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// incorporating info about the result values into this state.
96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
97b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               Hexagon_CCAssignFn Fn,
99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               unsigned SretValueInRegs) {
100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For Hexagon, Return small structures in registers.
102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (SretValueInRegs != 0) {
103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (SretValueInRegs <= 32) {
104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned Reg = Hexagon::R0;
105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      addLoc(CCValAssign::getReg(0, MVT::i32, Reg, MVT::i32,
106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 CCValAssign::Full));
107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return;
108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (SretValueInRegs <= 64) {
110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned Reg = Hexagon::D0;
111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      addLoc(CCValAssign::getReg(0, MVT::i64, Reg, MVT::i64,
112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                 CCValAssign::Full));
113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return;
114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Determine which register each value should be copied into.
119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT VT = Outs[i].VT;
121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this, -1, -1, false)){
123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Return operand #" << i << " has unhandled type "
124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           << VT.getEVTString() << "\n";
125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info
132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// about the passed values into this state.
133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
134b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg>
135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     &Outs,
136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     Hexagon_CCAssignFn Fn,
137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     int NonVarArgsParams,
138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     unsigned SretValueSize) {
139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumOps = Outs.size();
140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned i = 0;
142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If the called function returns a small struct in registers, skip
143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the first actual parameter. We do not want to pass a pointer to
144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the stack location.
145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (SretValueSize != 0) {
146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ++i;
147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (; i != NumOps; ++i) {
150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT ArgVT = Outs[i].VT;
151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this,
153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           NonVarArgsParams, i+1, false)) {
154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Call operand #" << i << " has unhandled type "
155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           << ArgVT.getEVTString() << "\n";
156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallOperands - Same as above except it takes vectors of types
162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// and argument flags.
163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
164b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeCallOperands(SmallVectorImpl<EVT> &ArgVTs,
165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     Hexagon_CCAssignFn Fn) {
167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned NumOps = ArgVTs.size();
168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0; i != NumOps; ++i) {
169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT ArgVT = ArgVTs[i];
170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy ArgFlags = Flags[i];
171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this, -1, -1,
172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           false)) {
173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      dbgs() << "Call operand #" << i << " has unhandled type "
174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           << ArgVT.getEVTString() << "\n";
175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallResult - Analyze the return values of an ISD::CALL node,
181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// incorporating info about the passed values into this state.
182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid
183b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagon_CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   Hexagon_CCAssignFn Fn,
185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   unsigned SretValueInRegs) {
186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    EVT VT = Ins[i].VT;
189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this, -1, -1, false)) {
191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        dbgs() << "Call result #" << i << " has unhandled type "
192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum               << VT.getEVTString() << "\n";
193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      abort();
194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// AnalyzeCallResult - Same as above except it's specialized for calls which
199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// produce a single value.
200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid Hexagon_CCState::AnalyzeCallResult(EVT VT, Hexagon_CCAssignFn Fn) {
201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this, -1, -1,
202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         false)) {
203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    dbgs() << "Call result has unhandled type "
204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         << VT.getEVTString() << "\n";
205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    abort();
206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
208