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