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" 160713a9d8SEric Christopher #include "llvm/CodeGen/MachineFrameInfo.h" 17*9fb823bbSChandler Carruth #include "llvm/IR/DataLayout.h" 18498e5f89SDan Gohman #include "llvm/Support/Debug.h" 19498e5f89SDan Gohman #include "llvm/Support/ErrorHandling.h" 20498e5f89SDan Gohman #include "llvm/Support/raw_ostream.h" 2167c5c3e9SStuart Hastings #include "llvm/Target/TargetLowering.h" 22ed0881b2SChandler Carruth #include "llvm/Target/TargetMachine.h" 23ed0881b2SChandler Carruth #include "llvm/Target/TargetRegisterInfo.h" 24498e5f89SDan Gohman using namespace llvm; 25498e5f89SDan Gohman 260713a9d8SEric Christopher CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf, 2762211394SCameron Zwarich const TargetMachine &tm, SmallVector<CCValAssign, 16> &locs, 2862211394SCameron Zwarich LLVMContext &C) 290713a9d8SEric Christopher : CallingConv(CC), IsVarArg(isVarArg), MF(mf), TM(tm), 3045fe3c38SStuart Hastings TRI(*TM.getRegisterInfo()), Locs(locs), Context(C), 318b58a838SCameron Zwarich CallOrPrologue(Unknown) { 32498e5f89SDan Gohman // No stack is used. 33498e5f89SDan Gohman StackOffset = 0; 34498e5f89SDan Gohman 3545fe3c38SStuart Hastings clearFirstByValReg(); 36498e5f89SDan Gohman UsedRegs.resize((TRI.getNumRegs()+31)/32); 37498e5f89SDan Gohman } 38498e5f89SDan Gohman 390713a9d8SEric Christopher // HandleByVal - Allocate space on the stack large enough to pass an argument 400713a9d8SEric Christopher // by value. The size and alignment information of the argument is encoded in 410713a9d8SEric Christopher // its parameter attribute. 4271049f78SDuncan Sands void CCState::HandleByVal(unsigned ValNo, MVT ValVT, 43f5dda01fSDuncan Sands MVT LocVT, CCValAssign::LocInfo LocInfo, 44498e5f89SDan Gohman int MinSize, int MinAlign, 45498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags) { 46498e5f89SDan Gohman unsigned Align = ArgFlags.getByValAlign(); 47498e5f89SDan Gohman unsigned Size = ArgFlags.getByValSize(); 48498e5f89SDan Gohman if (MinSize > (int)Size) 49498e5f89SDan Gohman Size = MinSize; 50498e5f89SDan Gohman if (MinAlign > (int)Align) 51498e5f89SDan Gohman Align = MinAlign; 5273696927SChad Rosier MF.getFrameInfo()->ensureMaxAlignment(Align); 53e59a920bSStepan Dyatkovskiy TM.getTargetLowering()->HandleByVal(this, Size, Align); 54498e5f89SDan Gohman unsigned Offset = AllocateStack(Size, Align); 55498e5f89SDan Gohman addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 56498e5f89SDan Gohman } 57498e5f89SDan Gohman 58498e5f89SDan Gohman /// MarkAllocated - Mark a register and all of its aliases as allocated. 59498e5f89SDan Gohman void CCState::MarkAllocated(unsigned Reg) { 6054038d79SJakob Stoklund Olesen for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) 6154038d79SJakob Stoklund Olesen UsedRegs[*AI/32] |= 1 << (*AI&31); 62498e5f89SDan Gohman } 63498e5f89SDan Gohman 64498e5f89SDan Gohman /// AnalyzeFormalArguments - Analyze an array of argument values, 65498e5f89SDan Gohman /// incorporating info about the formals into this state. 66498e5f89SDan Gohman void 67498e5f89SDan Gohman CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 68498e5f89SDan Gohman CCAssignFn Fn) { 69498e5f89SDan Gohman unsigned NumArgs = Ins.size(); 70498e5f89SDan Gohman 71498e5f89SDan Gohman for (unsigned i = 0; i != NumArgs; ++i) { 72f5dda01fSDuncan Sands MVT ArgVT = Ins[i].VT; 73498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Ins[i].Flags; 74498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 75498e5f89SDan Gohman #ifndef NDEBUG 76498e5f89SDan Gohman dbgs() << "Formal argument #" << i << " has unhandled type " 7704a5cc39SCraig Topper << EVT(ArgVT).getEVTString() << '\n'; 78498e5f89SDan Gohman #endif 79498e5f89SDan Gohman llvm_unreachable(0); 80498e5f89SDan Gohman } 81498e5f89SDan Gohman } 82498e5f89SDan Gohman } 83498e5f89SDan Gohman 84498e5f89SDan Gohman /// CheckReturn - Analyze the return values of a function, returning true if 85498e5f89SDan Gohman /// the return can be performed without sret-demotion, and false otherwise. 86d7b5ce33SDan Gohman bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 87498e5f89SDan Gohman CCAssignFn Fn) { 88498e5f89SDan Gohman // Determine which register each value should be copied into. 89d7b5ce33SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 90f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 91d7b5ce33SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 92498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) 93498e5f89SDan Gohman return false; 94498e5f89SDan Gohman } 95498e5f89SDan Gohman return true; 96498e5f89SDan Gohman } 97498e5f89SDan Gohman 98498e5f89SDan Gohman /// AnalyzeReturn - Analyze the returned values of a return, 99498e5f89SDan Gohman /// incorporating info about the result values into this state. 100498e5f89SDan Gohman void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 101498e5f89SDan Gohman CCAssignFn Fn) { 102498e5f89SDan Gohman // Determine which register each value should be copied into. 103498e5f89SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 104f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 105498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 106498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) { 107498e5f89SDan Gohman #ifndef NDEBUG 108498e5f89SDan Gohman dbgs() << "Return operand #" << i << " has unhandled type " 10904a5cc39SCraig Topper << EVT(VT).getEVTString() << '\n'; 110498e5f89SDan Gohman #endif 111498e5f89SDan Gohman llvm_unreachable(0); 112498e5f89SDan Gohman } 113498e5f89SDan Gohman } 114498e5f89SDan Gohman } 115498e5f89SDan Gohman 116498e5f89SDan Gohman /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, 117498e5f89SDan Gohman /// incorporating info about the passed values into this state. 118498e5f89SDan Gohman void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 119498e5f89SDan Gohman CCAssignFn Fn) { 120498e5f89SDan Gohman unsigned NumOps = Outs.size(); 121498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 122f5dda01fSDuncan Sands MVT ArgVT = Outs[i].VT; 123498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 124498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 125498e5f89SDan Gohman #ifndef NDEBUG 126498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 12704a5cc39SCraig Topper << EVT(ArgVT).getEVTString() << '\n'; 128498e5f89SDan Gohman #endif 129498e5f89SDan Gohman llvm_unreachable(0); 130498e5f89SDan Gohman } 131498e5f89SDan Gohman } 132498e5f89SDan Gohman } 133498e5f89SDan Gohman 134498e5f89SDan Gohman /// AnalyzeCallOperands - Same as above except it takes vectors of types 135498e5f89SDan Gohman /// and argument flags. 136f5dda01fSDuncan Sands void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, 137498e5f89SDan Gohman SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 138498e5f89SDan Gohman CCAssignFn Fn) { 139498e5f89SDan Gohman unsigned NumOps = ArgVTs.size(); 140498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 141f5dda01fSDuncan Sands MVT ArgVT = ArgVTs[i]; 142498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Flags[i]; 143498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 144498e5f89SDan Gohman #ifndef NDEBUG 145498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 14604a5cc39SCraig Topper << EVT(ArgVT).getEVTString() << '\n'; 147498e5f89SDan Gohman #endif 148498e5f89SDan Gohman llvm_unreachable(0); 149498e5f89SDan Gohman } 150498e5f89SDan Gohman } 151498e5f89SDan Gohman } 152498e5f89SDan Gohman 153498e5f89SDan Gohman /// AnalyzeCallResult - Analyze the return values of a call, 154498e5f89SDan Gohman /// incorporating info about the passed values into this state. 155498e5f89SDan Gohman void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 156498e5f89SDan Gohman CCAssignFn Fn) { 157498e5f89SDan Gohman for (unsigned i = 0, e = Ins.size(); i != e; ++i) { 158f5dda01fSDuncan Sands MVT VT = Ins[i].VT; 159498e5f89SDan Gohman ISD::ArgFlagsTy Flags = Ins[i].Flags; 160498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) { 161498e5f89SDan Gohman #ifndef NDEBUG 162498e5f89SDan Gohman dbgs() << "Call result #" << i << " has unhandled type " 16304a5cc39SCraig Topper << EVT(VT).getEVTString() << '\n'; 164498e5f89SDan Gohman #endif 165498e5f89SDan Gohman llvm_unreachable(0); 166498e5f89SDan Gohman } 167498e5f89SDan Gohman } 168498e5f89SDan Gohman } 169498e5f89SDan Gohman 170498e5f89SDan Gohman /// AnalyzeCallResult - Same as above except it's specialized for calls which 171498e5f89SDan Gohman /// produce a single value. 172f5dda01fSDuncan Sands void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) { 173498e5f89SDan Gohman if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) { 174498e5f89SDan Gohman #ifndef NDEBUG 175498e5f89SDan Gohman dbgs() << "Call result has unhandled type " 17604a5cc39SCraig Topper << EVT(VT).getEVTString() << '\n'; 177498e5f89SDan Gohman #endif 178498e5f89SDan Gohman llvm_unreachable(0); 179498e5f89SDan Gohman } 180498e5f89SDan Gohman } 181