1210006Srdivacky//===-- CallingConvLower.cpp - Calling Conventions ------------------------===//
2210006Srdivacky//
3210006Srdivacky//                     The LLVM Compiler Infrastructure
4210006Srdivacky//
5210006Srdivacky// This file is distributed under the University of Illinois Open Source
6210006Srdivacky// License. See LICENSE.TXT for details.
7210006Srdivacky//
8210006Srdivacky//===----------------------------------------------------------------------===//
9210006Srdivacky//
10210006Srdivacky// This file implements the CCState class, used for lowering and implementing
11210006Srdivacky// calling conventions.
12210006Srdivacky//
13210006Srdivacky//===----------------------------------------------------------------------===//
14210006Srdivacky
15210006Srdivacky#include "llvm/CodeGen/CallingConvLower.h"
16223017Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
17249423Sdim#include "llvm/IR/DataLayout.h"
18210006Srdivacky#include "llvm/Support/Debug.h"
19210006Srdivacky#include "llvm/Support/ErrorHandling.h"
20210006Srdivacky#include "llvm/Support/raw_ostream.h"
21249423Sdim#include "llvm/Target/TargetLowering.h"
22249423Sdim#include "llvm/Target/TargetMachine.h"
23210006Srdivacky#include "llvm/Target/TargetRegisterInfo.h"
24210006Srdivackyusing namespace llvm;
25210006Srdivacky
26223017SdimCCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf,
27263508Sdim                 const TargetMachine &tm, SmallVectorImpl<CCValAssign> &locs,
28223017Sdim                 LLVMContext &C)
29223017Sdim  : CallingConv(CC), IsVarArg(isVarArg), MF(mf), TM(tm),
30221345Sdim    TRI(*TM.getRegisterInfo()), Locs(locs), Context(C),
31223017Sdim    CallOrPrologue(Unknown) {
32210006Srdivacky  // No stack is used.
33210006Srdivacky  StackOffset = 0;
34223017Sdim
35251662Sdim  clearByValRegsInfo();
36210006Srdivacky  UsedRegs.resize((TRI.getNumRegs()+31)/32);
37210006Srdivacky}
38210006Srdivacky
39223017Sdim// HandleByVal - Allocate space on the stack large enough to pass an argument
40223017Sdim// by value. The size and alignment information of the argument is encoded in
41223017Sdim// its parameter attribute.
42218893Sdimvoid CCState::HandleByVal(unsigned ValNo, MVT ValVT,
43218893Sdim                          MVT LocVT, CCValAssign::LocInfo LocInfo,
44210006Srdivacky                          int MinSize, int MinAlign,
45210006Srdivacky                          ISD::ArgFlagsTy ArgFlags) {
46210006Srdivacky  unsigned Align = ArgFlags.getByValAlign();
47210006Srdivacky  unsigned Size  = ArgFlags.getByValSize();
48210006Srdivacky  if (MinSize > (int)Size)
49210006Srdivacky    Size = MinSize;
50210006Srdivacky  if (MinAlign > (int)Align)
51210006Srdivacky    Align = MinAlign;
52239462Sdim  MF.getFrameInfo()->ensureMaxAlignment(Align);
53243830Sdim  TM.getTargetLowering()->HandleByVal(this, Size, Align);
54210006Srdivacky  unsigned Offset = AllocateStack(Size, Align);
55210006Srdivacky  addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
56210006Srdivacky}
57210006Srdivacky
58210006Srdivacky/// MarkAllocated - Mark a register and all of its aliases as allocated.
59210006Srdivackyvoid CCState::MarkAllocated(unsigned Reg) {
60239462Sdim  for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
61239462Sdim    UsedRegs[*AI/32] |= 1 << (*AI&31);
62210006Srdivacky}
63210006Srdivacky
64210006Srdivacky/// AnalyzeFormalArguments - Analyze an array of argument values,
65210006Srdivacky/// incorporating info about the formals into this state.
66210006Srdivackyvoid
67210006SrdivackyCCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
68210006Srdivacky                                CCAssignFn Fn) {
69210006Srdivacky  unsigned NumArgs = Ins.size();
70210006Srdivacky
71210006Srdivacky  for (unsigned i = 0; i != NumArgs; ++i) {
72218893Sdim    MVT ArgVT = Ins[i].VT;
73210006Srdivacky    ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
74210006Srdivacky    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
75210006Srdivacky#ifndef NDEBUG
76210006Srdivacky      dbgs() << "Formal argument #" << i << " has unhandled type "
77249423Sdim             << EVT(ArgVT).getEVTString() << '\n';
78210006Srdivacky#endif
79210006Srdivacky      llvm_unreachable(0);
80210006Srdivacky    }
81210006Srdivacky  }
82210006Srdivacky}
83210006Srdivacky
84210006Srdivacky/// CheckReturn - Analyze the return values of a function, returning true if
85210006Srdivacky/// the return can be performed without sret-demotion, and false otherwise.
86210006Srdivackybool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
87210006Srdivacky                          CCAssignFn Fn) {
88210006Srdivacky  // Determine which register each value should be copied into.
89210006Srdivacky  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
90218893Sdim    MVT VT = Outs[i].VT;
91210006Srdivacky    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
92210006Srdivacky    if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this))
93210006Srdivacky      return false;
94210006Srdivacky  }
95210006Srdivacky  return true;
96210006Srdivacky}
97210006Srdivacky
98210006Srdivacky/// AnalyzeReturn - Analyze the returned values of a return,
99210006Srdivacky/// incorporating info about the result values into this state.
100210006Srdivackyvoid CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
101210006Srdivacky                            CCAssignFn Fn) {
102210006Srdivacky  // Determine which register each value should be copied into.
103210006Srdivacky  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
104218893Sdim    MVT VT = Outs[i].VT;
105210006Srdivacky    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
106210006Srdivacky    if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) {
107210006Srdivacky#ifndef NDEBUG
108210006Srdivacky      dbgs() << "Return operand #" << i << " has unhandled type "
109249423Sdim             << EVT(VT).getEVTString() << '\n';
110210006Srdivacky#endif
111210006Srdivacky      llvm_unreachable(0);
112210006Srdivacky    }
113210006Srdivacky  }
114210006Srdivacky}
115210006Srdivacky
116210006Srdivacky/// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
117210006Srdivacky/// incorporating info about the passed values into this state.
118210006Srdivackyvoid CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
119210006Srdivacky                                  CCAssignFn Fn) {
120210006Srdivacky  unsigned NumOps = Outs.size();
121210006Srdivacky  for (unsigned i = 0; i != NumOps; ++i) {
122218893Sdim    MVT ArgVT = Outs[i].VT;
123210006Srdivacky    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
124210006Srdivacky    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
125210006Srdivacky#ifndef NDEBUG
126210006Srdivacky      dbgs() << "Call operand #" << i << " has unhandled type "
127249423Sdim             << EVT(ArgVT).getEVTString() << '\n';
128210006Srdivacky#endif
129210006Srdivacky      llvm_unreachable(0);
130210006Srdivacky    }
131210006Srdivacky  }
132210006Srdivacky}
133210006Srdivacky
134210006Srdivacky/// AnalyzeCallOperands - Same as above except it takes vectors of types
135210006Srdivacky/// and argument flags.
136218893Sdimvoid CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs,
137210006Srdivacky                                  SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
138210006Srdivacky                                  CCAssignFn Fn) {
139210006Srdivacky  unsigned NumOps = ArgVTs.size();
140210006Srdivacky  for (unsigned i = 0; i != NumOps; ++i) {
141218893Sdim    MVT ArgVT = ArgVTs[i];
142210006Srdivacky    ISD::ArgFlagsTy ArgFlags = Flags[i];
143210006Srdivacky    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
144210006Srdivacky#ifndef NDEBUG
145210006Srdivacky      dbgs() << "Call operand #" << i << " has unhandled type "
146249423Sdim             << EVT(ArgVT).getEVTString() << '\n';
147210006Srdivacky#endif
148210006Srdivacky      llvm_unreachable(0);
149210006Srdivacky    }
150210006Srdivacky  }
151210006Srdivacky}
152210006Srdivacky
153210006Srdivacky/// AnalyzeCallResult - Analyze the return values of a call,
154210006Srdivacky/// incorporating info about the passed values into this state.
155210006Srdivackyvoid CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
156210006Srdivacky                                CCAssignFn Fn) {
157210006Srdivacky  for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
158218893Sdim    MVT VT = Ins[i].VT;
159210006Srdivacky    ISD::ArgFlagsTy Flags = Ins[i].Flags;
160210006Srdivacky    if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) {
161210006Srdivacky#ifndef NDEBUG
162210006Srdivacky      dbgs() << "Call result #" << i << " has unhandled type "
163249423Sdim             << EVT(VT).getEVTString() << '\n';
164210006Srdivacky#endif
165210006Srdivacky      llvm_unreachable(0);
166210006Srdivacky    }
167210006Srdivacky  }
168210006Srdivacky}
169210006Srdivacky
170210006Srdivacky/// AnalyzeCallResult - Same as above except it's specialized for calls which
171210006Srdivacky/// produce a single value.
172218893Sdimvoid CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) {
173210006Srdivacky  if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
174210006Srdivacky#ifndef NDEBUG
175210006Srdivacky    dbgs() << "Call result has unhandled type "
176249423Sdim           << EVT(VT).getEVTString() << '\n';
177210006Srdivacky#endif
178210006Srdivacky    llvm_unreachable(0);
179210006Srdivacky  }
180210006Srdivacky}
181