7a1eeb23d20629a2ca452f542eec23d4ea72009c
[oota-llvm.git] / lib / CodeGen / SelectionDAG / CallingConvLower.cpp
1 //===-- CallingConvLower.cpp - Calling Conventions ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the CCState class, used for lowering and implementing
11 // calling conventions.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/CodeGen/CallingConvLower.h"
16 #include "llvm/Support/ErrorHandling.h"
17 #include "llvm/Support/raw_ostream.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19 #include "llvm/Target/TargetData.h"
20 #include "llvm/Target/TargetMachine.h"
21 using namespace llvm;
22
23 CCState::CCState(unsigned CC, bool isVarArg, const TargetMachine &tm,
24                  SmallVector<CCValAssign, 16> &locs, LLVMContext &C)
25   : CallingConv(CC), IsVarArg(isVarArg), TM(tm),
26     TRI(*TM.getRegisterInfo()), Locs(locs), Context(C) {
27   // No stack is used.
28   StackOffset = 0;
29   
30   UsedRegs.resize((TRI.getNumRegs()+31)/32);
31 }
32
33 // HandleByVal - Allocate a stack slot large enough to pass an argument by
34 // value. The size and alignment information of the argument is encoded in its
35 // parameter attribute.
36 void CCState::HandleByVal(unsigned ValNo, EVT ValVT,
37                           EVT LocVT, CCValAssign::LocInfo LocInfo,
38                           int MinSize, int MinAlign,
39                           ISD::ArgFlagsTy ArgFlags) {
40   unsigned Align = ArgFlags.getByValAlign();
41   unsigned Size  = ArgFlags.getByValSize();
42   if (MinSize > (int)Size)
43     Size = MinSize;
44   if (MinAlign > (int)Align)
45     Align = MinAlign;
46   unsigned Offset = AllocateStack(Size, Align);
47
48   addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
49 }
50
51 /// MarkAllocated - Mark a register and all of its aliases as allocated.
52 void CCState::MarkAllocated(unsigned Reg) {
53   UsedRegs[Reg/32] |= 1 << (Reg&31);
54   
55   if (const unsigned *RegAliases = TRI.getAliasSet(Reg))
56     for (; (Reg = *RegAliases); ++RegAliases)
57       UsedRegs[Reg/32] |= 1 << (Reg&31);
58 }
59
60 /// AnalyzeFormalArguments - Analyze an array of argument values,
61 /// incorporating info about the formals into this state.
62 void
63 CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
64                                 CCAssignFn Fn) {
65   unsigned NumArgs = Ins.size();
66
67   for (unsigned i = 0; i != NumArgs; ++i) {
68     EVT ArgVT = Ins[i].VT;
69     ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
70     if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
71 #ifndef NDEBUG
72       cerr << "Formal argument #" << i << " has unhandled type "
73            << ArgVT.getEVTString();
74 #endif
75       llvm_unreachable(0);
76     }
77   }
78 }
79
80 /// AnalyzeReturn - Analyze the returned values of a return,
81 /// incorporating info about the result values into this state.
82 void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
83                             CCAssignFn Fn) {
84   // Determine which register each value should be copied into.
85   for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
86     EVT VT = Outs[i].Val.getValueType();
87     ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
88     if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) {
89 #ifndef NDEBUG
90       cerr << "Return operand #" << i << " has unhandled type "
91            << VT.getEVTString();
92 #endif
93       llvm_unreachable(0);
94     }
95   }
96 }
97
98
99 /// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
100 /// incorporating info about the passed values into this state.
101 void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
102                                   CCAssignFn Fn) {
103   unsigned NumOps = Outs.size();
104   for (unsigned i = 0; i != NumOps; ++i) {
105     EVT ArgVT = Outs[i].Val.getValueType();
106     ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
107     if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
108 #ifndef NDEBUG
109       cerr << "Call operand #" << i << " has unhandled type "
110            << ArgVT.getEVTString();
111 #endif
112       llvm_unreachable(0);
113     }
114   }
115 }
116
117 /// AnalyzeCallOperands - Same as above except it takes vectors of types
118 /// and argument flags.
119 void CCState::AnalyzeCallOperands(SmallVectorImpl<EVT> &ArgVTs,
120                                   SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
121                                   CCAssignFn Fn) {
122   unsigned NumOps = ArgVTs.size();
123   for (unsigned i = 0; i != NumOps; ++i) {
124     EVT ArgVT = ArgVTs[i];
125     ISD::ArgFlagsTy ArgFlags = Flags[i];
126     if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
127 #ifndef NDEBUG
128       cerr << "Call operand #" << i << " has unhandled type "
129            << ArgVT.getEVTString();
130 #endif
131       llvm_unreachable(0);
132     }
133   }
134 }
135
136 /// AnalyzeCallResult - Analyze the return values of a call,
137 /// incorporating info about the passed values into this state.
138 void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
139                                 CCAssignFn Fn) {
140   for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
141     EVT VT = Ins[i].VT;
142     ISD::ArgFlagsTy Flags = Ins[i].Flags;
143     if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) {
144 #ifndef NDEBUG
145       cerr << "Call result #" << i << " has unhandled type "
146            << VT.getEVTString();
147 #endif
148       llvm_unreachable(0);
149     }
150   }
151 }
152
153 /// AnalyzeCallResult - Same as above except it's specialized for calls which
154 /// produce a single value.
155 void CCState::AnalyzeCallResult(EVT VT, CCAssignFn Fn) {
156   if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
157 #ifndef NDEBUG
158     cerr << "Call result has unhandled type "
159          << VT.getEVTString();
160 #endif
161     llvm_unreachable(0);
162   }
163 }