1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- CallingConvLower.cpp - Calling Conventions ------------------------===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file implements the CCState class, used for lowering and implementing
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// calling conventions.
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/CallingConvLower.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFrameInfo.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetRegisterInfo.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetData.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetLowering.h"
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf,
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 const TargetMachine &tm, SmallVector<CCValAssign, 16> &locs,
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 LLVMContext &C)
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : CallingConv(CC), IsVarArg(isVarArg), MF(mf), TM(tm),
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TRI(*TM.getRegisterInfo()), Locs(locs), Context(C),
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CallOrPrologue(Unknown) {
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // No stack is used.
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StackOffset = 0;
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  clearFirstByValReg();
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  UsedRegs.resize((TRI.getNumRegs()+31)/32);
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// HandleByVal - Allocate space on the stack large enough to pass an argument
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// by value. The size and alignment information of the argument is encoded in
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// its parameter attribute.
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CCState::HandleByVal(unsigned ValNo, MVT ValVT,
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          MVT LocVT, CCValAssign::LocInfo LocInfo,
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                          int MinSize, int MinAlign,
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                          ISD::ArgFlagsTy ArgFlags) {
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Align = ArgFlags.getByValAlign();
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Size  = ArgFlags.getByValSize();
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (MinSize > (int)Size)
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Size = MinSize;
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (MinAlign > (int)Align)
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Align = MinAlign;
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MF.getFrameInfo()->getMaxAlignment() < Align)
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MF.getFrameInfo()->setMaxAlignment(Align);
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TM.getTargetLowering()->HandleByVal(this, Size);
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Offset = AllocateStack(Size, Align);
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// MarkAllocated - Mark a register and all of its aliases as allocated.
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid CCState::MarkAllocated(unsigned Reg) {
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (const unsigned *Alias = TRI.getOverlaps(Reg);
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       unsigned Reg = *Alias; ++Alias)
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    UsedRegs[Reg/32] |= 1 << (Reg&31);
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AnalyzeFormalArguments - Analyze an array of argument values,
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// incorporating info about the formals into this state.
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanCCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                CCAssignFn Fn) {
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned NumArgs = Ins.size();
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0; i != NumArgs; ++i) {
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MVT ArgVT = Ins[i].VT;
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      dbgs() << "Formal argument #" << i << " has unhandled type "
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             << EVT(ArgVT).getEVTString();
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      llvm_unreachable(0);
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// CheckReturn - Analyze the return values of a function, returning true if
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the return can be performed without sret-demotion, and false otherwise.
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                          CCAssignFn Fn) {
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Determine which register each value should be copied into.
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MVT VT = Outs[i].VT;
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this))
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return true;
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AnalyzeReturn - Analyze the returned values of a return,
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// incorporating info about the result values into this state.
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                            CCAssignFn Fn) {
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Determine which register each value should be copied into.
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MVT VT = Outs[i].VT;
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) {
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      dbgs() << "Return operand #" << i << " has unhandled type "
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             << EVT(VT).getEVTString();
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      llvm_unreachable(0);
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// incorporating info about the passed values into this state.
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  CCAssignFn Fn) {
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned NumOps = Outs.size();
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0; i != NumOps; ++i) {
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MVT ArgVT = Outs[i].VT;
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      dbgs() << "Call operand #" << i << " has unhandled type "
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             << EVT(ArgVT).getEVTString();
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      llvm_unreachable(0);
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AnalyzeCallOperands - Same as above except it takes vectors of types
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and argument flags.
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs,
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  CCAssignFn Fn) {
141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned NumOps = ArgVTs.size();
142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0; i != NumOps; ++i) {
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MVT ArgVT = ArgVTs[i];
144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ISD::ArgFlagsTy ArgFlags = Flags[i];
145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG
147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      dbgs() << "Call operand #" << i << " has unhandled type "
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             << EVT(ArgVT).getEVTString();
149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      llvm_unreachable(0);
151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AnalyzeCallResult - Analyze the return values of a call,
156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// incorporating info about the passed values into this state.
157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                CCAssignFn Fn) {
159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MVT VT = Ins[i].VT;
161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ISD::ArgFlagsTy Flags = Ins[i].Flags;
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) {
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG
164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      dbgs() << "Call result #" << i << " has unhandled type "
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             << EVT(VT).getEVTString() << "\n";
166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      llvm_unreachable(0);
168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AnalyzeCallResult - Same as above except it's specialized for calls which
173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// produce a single value.
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) {
175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG
177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    dbgs() << "Call result has unhandled type "
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           << EVT(VT).getEVTString();
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    llvm_unreachable(0);
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
183