1498e5f89SDan Gohman //===-- CallingConvLower.cpp - Calling Conventions ------------------------===// 2498e5f89SDan Gohman // 3498e5f89SDan Gohman // The LLVM Compiler Infrastructure 4498e5f89SDan Gohman // 5498e5f89SDan Gohman // This file is distributed under the University of Illinois Open Source 6498e5f89SDan Gohman // License. See LICENSE.TXT for details. 7498e5f89SDan Gohman // 8498e5f89SDan Gohman //===----------------------------------------------------------------------===// 9498e5f89SDan Gohman // 10498e5f89SDan Gohman // This file implements the CCState class, used for lowering and implementing 11498e5f89SDan Gohman // calling conventions. 12498e5f89SDan Gohman // 13498e5f89SDan Gohman //===----------------------------------------------------------------------===// 14498e5f89SDan Gohman 15498e5f89SDan Gohman #include "llvm/CodeGen/CallingConvLower.h" 16498e5f89SDan Gohman #include "llvm/Support/Debug.h" 17498e5f89SDan Gohman #include "llvm/Support/ErrorHandling.h" 18498e5f89SDan Gohman #include "llvm/Support/raw_ostream.h" 19498e5f89SDan Gohman #include "llvm/Target/TargetRegisterInfo.h" 20498e5f89SDan Gohman #include "llvm/Target/TargetData.h" 21498e5f89SDan Gohman #include "llvm/Target/TargetMachine.h" 2267c5c3e9SStuart Hastings #include "llvm/Target/TargetLowering.h" 23498e5f89SDan Gohman using namespace llvm; 24498e5f89SDan Gohman 25498e5f89SDan Gohman CCState::CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &tm, 26498e5f89SDan Gohman SmallVector<CCValAssign, 16> &locs, LLVMContext &C) 27498e5f89SDan Gohman : CallingConv(CC), IsVarArg(isVarArg), TM(tm), 28*45fe3c38SStuart Hastings TRI(*TM.getRegisterInfo()), Locs(locs), Context(C), 29*45fe3c38SStuart Hastings CallOrPrologue(Invalid) { 30498e5f89SDan Gohman // No stack is used. 31498e5f89SDan Gohman StackOffset = 0; 32498e5f89SDan Gohman 33*45fe3c38SStuart Hastings clearFirstByValReg(); 34498e5f89SDan Gohman UsedRegs.resize((TRI.getNumRegs()+31)/32); 35498e5f89SDan Gohman } 36498e5f89SDan Gohman 37498e5f89SDan Gohman // HandleByVal - Allocate a stack slot large enough to pass an argument by 38498e5f89SDan Gohman // value. The size and alignment information of the argument is encoded in its 39498e5f89SDan Gohman // parameter attribute. 4071049f78SDuncan Sands void CCState::HandleByVal(unsigned ValNo, MVT ValVT, 41f5dda01fSDuncan Sands MVT LocVT, CCValAssign::LocInfo LocInfo, 42498e5f89SDan Gohman int MinSize, int MinAlign, 43498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags) { 44498e5f89SDan Gohman unsigned Align = ArgFlags.getByValAlign(); 45498e5f89SDan Gohman unsigned Size = ArgFlags.getByValSize(); 46498e5f89SDan Gohman if (MinSize > (int)Size) 47498e5f89SDan Gohman Size = MinSize; 48498e5f89SDan Gohman if (MinAlign > (int)Align) 49498e5f89SDan Gohman Align = MinAlign; 50*45fe3c38SStuart Hastings TM.getTargetLowering()->HandleByVal(const_cast<CCState*>(this), Size); 51498e5f89SDan Gohman unsigned Offset = AllocateStack(Size, Align); 52498e5f89SDan Gohman addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 53498e5f89SDan Gohman } 54498e5f89SDan Gohman 55498e5f89SDan Gohman /// MarkAllocated - Mark a register and all of its aliases as allocated. 56498e5f89SDan Gohman void CCState::MarkAllocated(unsigned Reg) { 5747b93401SJakob Stoklund Olesen for (const unsigned *Alias = TRI.getOverlaps(Reg); 5847b93401SJakob Stoklund Olesen unsigned Reg = *Alias; ++Alias) 59498e5f89SDan Gohman UsedRegs[Reg/32] |= 1 << (Reg&31); 60498e5f89SDan Gohman } 61498e5f89SDan Gohman 62498e5f89SDan Gohman /// AnalyzeFormalArguments - Analyze an array of argument values, 63498e5f89SDan Gohman /// incorporating info about the formals into this state. 64498e5f89SDan Gohman void 65498e5f89SDan Gohman CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 66498e5f89SDan Gohman CCAssignFn Fn) { 67498e5f89SDan Gohman unsigned NumArgs = Ins.size(); 68498e5f89SDan Gohman 69498e5f89SDan Gohman for (unsigned i = 0; i != NumArgs; ++i) { 70f5dda01fSDuncan Sands MVT ArgVT = Ins[i].VT; 71498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Ins[i].Flags; 72498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 73498e5f89SDan Gohman #ifndef NDEBUG 74498e5f89SDan Gohman dbgs() << "Formal argument #" << i << " has unhandled type " 75f5dda01fSDuncan Sands << EVT(ArgVT).getEVTString(); 76498e5f89SDan Gohman #endif 77498e5f89SDan Gohman llvm_unreachable(0); 78498e5f89SDan Gohman } 79498e5f89SDan Gohman } 80498e5f89SDan Gohman } 81498e5f89SDan Gohman 82498e5f89SDan Gohman /// CheckReturn - Analyze the return values of a function, returning true if 83498e5f89SDan Gohman /// the return can be performed without sret-demotion, and false otherwise. 84d7b5ce33SDan Gohman bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 85498e5f89SDan Gohman CCAssignFn Fn) { 86498e5f89SDan Gohman // Determine which register each value should be copied into. 87d7b5ce33SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 88f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 89d7b5ce33SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 90498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) 91498e5f89SDan Gohman return false; 92498e5f89SDan Gohman } 93498e5f89SDan Gohman return true; 94498e5f89SDan Gohman } 95498e5f89SDan Gohman 96498e5f89SDan Gohman /// AnalyzeReturn - Analyze the returned values of a return, 97498e5f89SDan Gohman /// incorporating info about the result values into this state. 98498e5f89SDan Gohman void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 99498e5f89SDan Gohman CCAssignFn Fn) { 100498e5f89SDan Gohman // Determine which register each value should be copied into. 101498e5f89SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 102f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 103498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 104498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) { 105498e5f89SDan Gohman #ifndef NDEBUG 106498e5f89SDan Gohman dbgs() << "Return operand #" << i << " has unhandled type " 107f5dda01fSDuncan Sands << EVT(VT).getEVTString(); 108498e5f89SDan Gohman #endif 109498e5f89SDan Gohman llvm_unreachable(0); 110498e5f89SDan Gohman } 111498e5f89SDan Gohman } 112498e5f89SDan Gohman } 113498e5f89SDan Gohman 114498e5f89SDan Gohman /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, 115498e5f89SDan Gohman /// incorporating info about the passed values into this state. 116498e5f89SDan Gohman void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 117498e5f89SDan Gohman CCAssignFn Fn) { 118498e5f89SDan Gohman unsigned NumOps = Outs.size(); 119498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 120f5dda01fSDuncan Sands MVT ArgVT = Outs[i].VT; 121498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 122498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 123498e5f89SDan Gohman #ifndef NDEBUG 124498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 125f5dda01fSDuncan Sands << EVT(ArgVT).getEVTString(); 126498e5f89SDan Gohman #endif 127498e5f89SDan Gohman llvm_unreachable(0); 128498e5f89SDan Gohman } 129498e5f89SDan Gohman } 130498e5f89SDan Gohman } 131498e5f89SDan Gohman 132498e5f89SDan Gohman /// AnalyzeCallOperands - Same as above except it takes vectors of types 133498e5f89SDan Gohman /// and argument flags. 134f5dda01fSDuncan Sands void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, 135498e5f89SDan Gohman SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 136498e5f89SDan Gohman CCAssignFn Fn) { 137498e5f89SDan Gohman unsigned NumOps = ArgVTs.size(); 138498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 139f5dda01fSDuncan Sands MVT ArgVT = ArgVTs[i]; 140498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Flags[i]; 141498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 142498e5f89SDan Gohman #ifndef NDEBUG 143498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 144f5dda01fSDuncan Sands << EVT(ArgVT).getEVTString(); 145498e5f89SDan Gohman #endif 146498e5f89SDan Gohman llvm_unreachable(0); 147498e5f89SDan Gohman } 148498e5f89SDan Gohman } 149498e5f89SDan Gohman } 150498e5f89SDan Gohman 151498e5f89SDan Gohman /// AnalyzeCallResult - Analyze the return values of a call, 152498e5f89SDan Gohman /// incorporating info about the passed values into this state. 153498e5f89SDan Gohman void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 154498e5f89SDan Gohman CCAssignFn Fn) { 155498e5f89SDan Gohman for (unsigned i = 0, e = Ins.size(); i != e; ++i) { 156f5dda01fSDuncan Sands MVT VT = Ins[i].VT; 157498e5f89SDan Gohman ISD::ArgFlagsTy Flags = Ins[i].Flags; 158498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) { 159498e5f89SDan Gohman #ifndef NDEBUG 160498e5f89SDan Gohman dbgs() << "Call result #" << i << " has unhandled type " 16140326989SEric Christopher << EVT(VT).getEVTString() << "\n"; 162498e5f89SDan Gohman #endif 163498e5f89SDan Gohman llvm_unreachable(0); 164498e5f89SDan Gohman } 165498e5f89SDan Gohman } 166498e5f89SDan Gohman } 167498e5f89SDan Gohman 168498e5f89SDan Gohman /// AnalyzeCallResult - Same as above except it's specialized for calls which 169498e5f89SDan Gohman /// produce a single value. 170f5dda01fSDuncan Sands void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) { 171498e5f89SDan Gohman if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) { 172498e5f89SDan Gohman #ifndef NDEBUG 173498e5f89SDan Gohman dbgs() << "Call result has unhandled type " 174f5dda01fSDuncan Sands << EVT(VT).getEVTString(); 175498e5f89SDan Gohman #endif 176498e5f89SDan Gohman llvm_unreachable(0); 177498e5f89SDan Gohman } 178498e5f89SDan Gohman } 179