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), 28498e5f89SDan Gohman TRI(*TM.getRegisterInfo()), Locs(locs), Context(C) { 29498e5f89SDan Gohman // No stack is used. 30498e5f89SDan Gohman StackOffset = 0; 31498e5f89SDan Gohman 32498e5f89SDan Gohman UsedRegs.resize((TRI.getNumRegs()+31)/32); 33498e5f89SDan Gohman } 34498e5f89SDan Gohman 35498e5f89SDan Gohman // HandleByVal - Allocate a stack slot large enough to pass an argument by 36498e5f89SDan Gohman // value. The size and alignment information of the argument is encoded in its 37498e5f89SDan Gohman // parameter attribute. 3871049f78SDuncan Sands void CCState::HandleByVal(unsigned ValNo, MVT ValVT, 39f5dda01fSDuncan Sands MVT LocVT, CCValAssign::LocInfo LocInfo, 40498e5f89SDan Gohman int MinSize, int MinAlign, 41498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags) { 42498e5f89SDan Gohman unsigned Align = ArgFlags.getByValAlign(); 43498e5f89SDan Gohman unsigned Size = ArgFlags.getByValSize(); 44498e5f89SDan Gohman if (MinSize > (int)Size) 45498e5f89SDan Gohman Size = MinSize; 46498e5f89SDan Gohman if (MinAlign > (int)Align) 47498e5f89SDan Gohman Align = MinAlign; 48498e5f89SDan Gohman unsigned Offset = AllocateStack(Size, Align); 49498e5f89SDan Gohman 50498e5f89SDan Gohman addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 5167c5c3e9SStuart Hastings TM.getTargetLowering()->HandleByVal(const_cast<CCState*>(this)); 52498e5f89SDan Gohman } 53498e5f89SDan Gohman 54498e5f89SDan Gohman /// MarkAllocated - Mark a register and all of its aliases as allocated. 55498e5f89SDan Gohman void CCState::MarkAllocated(unsigned Reg) { 5647b93401SJakob Stoklund Olesen for (const unsigned *Alias = TRI.getOverlaps(Reg); 5747b93401SJakob Stoklund Olesen unsigned Reg = *Alias; ++Alias) 58498e5f89SDan Gohman UsedRegs[Reg/32] |= 1 << (Reg&31); 59498e5f89SDan Gohman } 60498e5f89SDan Gohman 61498e5f89SDan Gohman /// AnalyzeFormalArguments - Analyze an array of argument values, 62498e5f89SDan Gohman /// incorporating info about the formals into this state. 63498e5f89SDan Gohman void 64498e5f89SDan Gohman CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 65498e5f89SDan Gohman CCAssignFn Fn) { 66498e5f89SDan Gohman unsigned NumArgs = Ins.size(); 67498e5f89SDan Gohman 68498e5f89SDan Gohman for (unsigned i = 0; i != NumArgs; ++i) { 69f5dda01fSDuncan Sands MVT ArgVT = Ins[i].VT; 70498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Ins[i].Flags; 71498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 72498e5f89SDan Gohman #ifndef NDEBUG 73498e5f89SDan Gohman dbgs() << "Formal argument #" << i << " has unhandled type " 74f5dda01fSDuncan Sands << EVT(ArgVT).getEVTString(); 75498e5f89SDan Gohman #endif 76498e5f89SDan Gohman llvm_unreachable(0); 77498e5f89SDan Gohman } 78498e5f89SDan Gohman } 79498e5f89SDan Gohman } 80498e5f89SDan Gohman 81498e5f89SDan Gohman /// CheckReturn - Analyze the return values of a function, returning true if 82498e5f89SDan Gohman /// the return can be performed without sret-demotion, and false otherwise. 83d7b5ce33SDan Gohman bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 84498e5f89SDan Gohman CCAssignFn Fn) { 85498e5f89SDan Gohman // Determine which register each value should be copied into. 86d7b5ce33SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 87f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 88d7b5ce33SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 89498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) 90498e5f89SDan Gohman return false; 91498e5f89SDan Gohman } 92498e5f89SDan Gohman return true; 93498e5f89SDan Gohman } 94498e5f89SDan Gohman 95498e5f89SDan Gohman /// AnalyzeReturn - Analyze the returned values of a return, 96498e5f89SDan Gohman /// incorporating info about the result values into this state. 97498e5f89SDan Gohman void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 98498e5f89SDan Gohman CCAssignFn Fn) { 99498e5f89SDan Gohman // Determine which register each value should be copied into. 100498e5f89SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 101f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 102498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 103498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) { 104498e5f89SDan Gohman #ifndef NDEBUG 105498e5f89SDan Gohman dbgs() << "Return operand #" << i << " has unhandled type " 106f5dda01fSDuncan Sands << EVT(VT).getEVTString(); 107498e5f89SDan Gohman #endif 108498e5f89SDan Gohman llvm_unreachable(0); 109498e5f89SDan Gohman } 110498e5f89SDan Gohman } 111498e5f89SDan Gohman } 112498e5f89SDan Gohman 113498e5f89SDan Gohman /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, 114498e5f89SDan Gohman /// incorporating info about the passed values into this state. 115498e5f89SDan Gohman void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 116498e5f89SDan Gohman CCAssignFn Fn) { 117498e5f89SDan Gohman unsigned NumOps = Outs.size(); 118498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 119f5dda01fSDuncan Sands MVT ArgVT = Outs[i].VT; 120498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 121498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 122498e5f89SDan Gohman #ifndef NDEBUG 123498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 124f5dda01fSDuncan Sands << EVT(ArgVT).getEVTString(); 125498e5f89SDan Gohman #endif 126498e5f89SDan Gohman llvm_unreachable(0); 127498e5f89SDan Gohman } 128498e5f89SDan Gohman } 129498e5f89SDan Gohman } 130498e5f89SDan Gohman 131498e5f89SDan Gohman /// AnalyzeCallOperands - Same as above except it takes vectors of types 132498e5f89SDan Gohman /// and argument flags. 133f5dda01fSDuncan Sands void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, 134498e5f89SDan Gohman SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 135498e5f89SDan Gohman CCAssignFn Fn) { 136498e5f89SDan Gohman unsigned NumOps = ArgVTs.size(); 137498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 138f5dda01fSDuncan Sands MVT ArgVT = ArgVTs[i]; 139498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Flags[i]; 140498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 141498e5f89SDan Gohman #ifndef NDEBUG 142498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 143f5dda01fSDuncan Sands << EVT(ArgVT).getEVTString(); 144498e5f89SDan Gohman #endif 145498e5f89SDan Gohman llvm_unreachable(0); 146498e5f89SDan Gohman } 147498e5f89SDan Gohman } 148498e5f89SDan Gohman } 149498e5f89SDan Gohman 150498e5f89SDan Gohman /// AnalyzeCallResult - Analyze the return values of a call, 151498e5f89SDan Gohman /// incorporating info about the passed values into this state. 152498e5f89SDan Gohman void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 153498e5f89SDan Gohman CCAssignFn Fn) { 154498e5f89SDan Gohman for (unsigned i = 0, e = Ins.size(); i != e; ++i) { 155f5dda01fSDuncan Sands MVT VT = Ins[i].VT; 156498e5f89SDan Gohman ISD::ArgFlagsTy Flags = Ins[i].Flags; 157498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) { 158498e5f89SDan Gohman #ifndef NDEBUG 159498e5f89SDan Gohman dbgs() << "Call result #" << i << " has unhandled type " 160*40326989SEric Christopher << EVT(VT).getEVTString() << "\n"; 161498e5f89SDan Gohman #endif 162498e5f89SDan Gohman llvm_unreachable(0); 163498e5f89SDan Gohman } 164498e5f89SDan Gohman } 165498e5f89SDan Gohman } 166498e5f89SDan Gohman 167498e5f89SDan Gohman /// AnalyzeCallResult - Same as above except it's specialized for calls which 168498e5f89SDan Gohman /// produce a single value. 169f5dda01fSDuncan Sands void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) { 170498e5f89SDan Gohman if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) { 171498e5f89SDan Gohman #ifndef NDEBUG 172498e5f89SDan Gohman dbgs() << "Call result has unhandled type " 173f5dda01fSDuncan Sands << EVT(VT).getEVTString(); 174498e5f89SDan Gohman #endif 175498e5f89SDan Gohman llvm_unreachable(0); 176498e5f89SDan Gohman } 177498e5f89SDan Gohman } 178