1*0a6a1f1dSLionel Sambuc //===---- MipsCCState.h - CCState with Mips specific extensions -----------===// 2*0a6a1f1dSLionel Sambuc // 3*0a6a1f1dSLionel Sambuc // The LLVM Compiler Infrastructure 4*0a6a1f1dSLionel Sambuc // 5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details. 7*0a6a1f1dSLionel Sambuc // 8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 9*0a6a1f1dSLionel Sambuc 10*0a6a1f1dSLionel Sambuc #ifndef MIPSCCSTATE_H 11*0a6a1f1dSLionel Sambuc #define MIPSCCSTATE_H 12*0a6a1f1dSLionel Sambuc 13*0a6a1f1dSLionel Sambuc #include "MipsISelLowering.h" 14*0a6a1f1dSLionel Sambuc #include "llvm/ADT/SmallVector.h" 15*0a6a1f1dSLionel Sambuc #include "llvm/CodeGen/CallingConvLower.h" 16*0a6a1f1dSLionel Sambuc 17*0a6a1f1dSLionel Sambuc namespace llvm { 18*0a6a1f1dSLionel Sambuc class SDNode; 19*0a6a1f1dSLionel Sambuc class MipsSubtarget; 20*0a6a1f1dSLionel Sambuc 21*0a6a1f1dSLionel Sambuc class MipsCCState : public CCState { 22*0a6a1f1dSLionel Sambuc public: 23*0a6a1f1dSLionel Sambuc enum SpecialCallingConvType { Mips16RetHelperConv, NoSpecialCallingConv }; 24*0a6a1f1dSLionel Sambuc 25*0a6a1f1dSLionel Sambuc /// Determine the SpecialCallingConvType for the given callee 26*0a6a1f1dSLionel Sambuc static SpecialCallingConvType 27*0a6a1f1dSLionel Sambuc getSpecialCallingConvForCallee(const SDNode *Callee, 28*0a6a1f1dSLionel Sambuc const MipsSubtarget &Subtarget); 29*0a6a1f1dSLionel Sambuc 30*0a6a1f1dSLionel Sambuc private: 31*0a6a1f1dSLionel Sambuc /// Identify lowered values that originated from f128 arguments and record 32*0a6a1f1dSLionel Sambuc /// this for use by RetCC_MipsN. 33*0a6a1f1dSLionel Sambuc void PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins, 34*0a6a1f1dSLionel Sambuc const TargetLowering::CallLoweringInfo &CLI); 35*0a6a1f1dSLionel Sambuc 36*0a6a1f1dSLionel Sambuc /// Identify lowered values that originated from f128 arguments and record 37*0a6a1f1dSLionel Sambuc /// this for use by RetCC_MipsN. 38*0a6a1f1dSLionel Sambuc void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs); 39*0a6a1f1dSLionel Sambuc 40*0a6a1f1dSLionel Sambuc /// Identify lowered values that originated from f128 arguments and record 41*0a6a1f1dSLionel Sambuc /// this. 42*0a6a1f1dSLionel Sambuc void 43*0a6a1f1dSLionel Sambuc PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 44*0a6a1f1dSLionel Sambuc std::vector<TargetLowering::ArgListEntry> &FuncArgs, 45*0a6a1f1dSLionel Sambuc const SDNode *CallNode); 46*0a6a1f1dSLionel Sambuc 47*0a6a1f1dSLionel Sambuc /// Identify lowered values that originated from f128 arguments and record 48*0a6a1f1dSLionel Sambuc /// this. 49*0a6a1f1dSLionel Sambuc void 50*0a6a1f1dSLionel Sambuc PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl<ISD::InputArg> &Ins); 51*0a6a1f1dSLionel Sambuc 52*0a6a1f1dSLionel Sambuc /// Records whether the value has been lowered from an f128. 53*0a6a1f1dSLionel Sambuc SmallVector<bool, 4> OriginalArgWasF128; 54*0a6a1f1dSLionel Sambuc 55*0a6a1f1dSLionel Sambuc /// Records whether the value has been lowered from float. 56*0a6a1f1dSLionel Sambuc SmallVector<bool, 4> OriginalArgWasFloat; 57*0a6a1f1dSLionel Sambuc 58*0a6a1f1dSLionel Sambuc /// Records whether the value was a fixed argument. 59*0a6a1f1dSLionel Sambuc /// See ISD::OutputArg::IsFixed, 60*0a6a1f1dSLionel Sambuc SmallVector<bool, 4> CallOperandIsFixed; 61*0a6a1f1dSLionel Sambuc 62*0a6a1f1dSLionel Sambuc // Used to handle MIPS16-specific calling convention tweaks. 63*0a6a1f1dSLionel Sambuc // FIXME: This should probably be a fully fledged calling convention. 64*0a6a1f1dSLionel Sambuc SpecialCallingConvType SpecialCallingConv; 65*0a6a1f1dSLionel Sambuc 66*0a6a1f1dSLionel Sambuc public: 67*0a6a1f1dSLionel Sambuc MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, 68*0a6a1f1dSLionel Sambuc SmallVectorImpl<CCValAssign> &locs, LLVMContext &C, 69*0a6a1f1dSLionel Sambuc SpecialCallingConvType SpecialCC = NoSpecialCallingConv) CCState(CC,isVarArg,MF,locs,C)70*0a6a1f1dSLionel Sambuc : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} 71*0a6a1f1dSLionel Sambuc 72*0a6a1f1dSLionel Sambuc void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn,std::vector<TargetLowering::ArgListEntry> & FuncArgs,const SDNode * CallNode)73*0a6a1f1dSLionel Sambuc AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 74*0a6a1f1dSLionel Sambuc CCAssignFn Fn, 75*0a6a1f1dSLionel Sambuc std::vector<TargetLowering::ArgListEntry> &FuncArgs, 76*0a6a1f1dSLionel Sambuc const SDNode *CallNode) { 77*0a6a1f1dSLionel Sambuc PreAnalyzeCallOperands(Outs, FuncArgs, CallNode); 78*0a6a1f1dSLionel Sambuc CCState::AnalyzeCallOperands(Outs, Fn); 79*0a6a1f1dSLionel Sambuc OriginalArgWasF128.clear(); 80*0a6a1f1dSLionel Sambuc OriginalArgWasFloat.clear(); 81*0a6a1f1dSLionel Sambuc CallOperandIsFixed.clear(); 82*0a6a1f1dSLionel Sambuc } 83*0a6a1f1dSLionel Sambuc 84*0a6a1f1dSLionel Sambuc // The AnalyzeCallOperands in the base class is not usable since we must 85*0a6a1f1dSLionel Sambuc // provide a means of accessing ArgListEntry::IsFixed. Delete them from this 86*0a6a1f1dSLionel Sambuc // class. This doesn't stop them being used via the base class though. 87*0a6a1f1dSLionel Sambuc void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 88*0a6a1f1dSLionel Sambuc CCAssignFn Fn) LLVM_DELETED_FUNCTION; 89*0a6a1f1dSLionel Sambuc void AnalyzeCallOperands(const SmallVectorImpl<MVT> &Outs, 90*0a6a1f1dSLionel Sambuc SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 91*0a6a1f1dSLionel Sambuc CCAssignFn Fn) LLVM_DELETED_FUNCTION; 92*0a6a1f1dSLionel Sambuc AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn)93*0a6a1f1dSLionel Sambuc void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 94*0a6a1f1dSLionel Sambuc CCAssignFn Fn) { 95*0a6a1f1dSLionel Sambuc PreAnalyzeFormalArgumentsForF128(Ins); 96*0a6a1f1dSLionel Sambuc CCState::AnalyzeFormalArguments(Ins, Fn); 97*0a6a1f1dSLionel Sambuc OriginalArgWasFloat.clear(); 98*0a6a1f1dSLionel Sambuc OriginalArgWasF128.clear(); 99*0a6a1f1dSLionel Sambuc } 100*0a6a1f1dSLionel Sambuc AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn,const TargetLowering::CallLoweringInfo & CLI)101*0a6a1f1dSLionel Sambuc void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 102*0a6a1f1dSLionel Sambuc CCAssignFn Fn, 103*0a6a1f1dSLionel Sambuc const TargetLowering::CallLoweringInfo &CLI) { 104*0a6a1f1dSLionel Sambuc PreAnalyzeCallResultForF128(Ins, CLI); 105*0a6a1f1dSLionel Sambuc CCState::AnalyzeCallResult(Ins, Fn); 106*0a6a1f1dSLionel Sambuc OriginalArgWasFloat.clear(); 107*0a6a1f1dSLionel Sambuc OriginalArgWasF128.clear(); 108*0a6a1f1dSLionel Sambuc } 109*0a6a1f1dSLionel Sambuc AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn)110*0a6a1f1dSLionel Sambuc void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 111*0a6a1f1dSLionel Sambuc CCAssignFn Fn) { 112*0a6a1f1dSLionel Sambuc PreAnalyzeReturnForF128(Outs); 113*0a6a1f1dSLionel Sambuc CCState::AnalyzeReturn(Outs, Fn); 114*0a6a1f1dSLionel Sambuc OriginalArgWasFloat.clear(); 115*0a6a1f1dSLionel Sambuc OriginalArgWasF128.clear(); 116*0a6a1f1dSLionel Sambuc } 117*0a6a1f1dSLionel Sambuc CheckReturn(const SmallVectorImpl<ISD::OutputArg> & ArgsFlags,CCAssignFn Fn)118*0a6a1f1dSLionel Sambuc bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 119*0a6a1f1dSLionel Sambuc CCAssignFn Fn) { 120*0a6a1f1dSLionel Sambuc PreAnalyzeReturnForF128(ArgsFlags); 121*0a6a1f1dSLionel Sambuc bool Return = CCState::CheckReturn(ArgsFlags, Fn); 122*0a6a1f1dSLionel Sambuc OriginalArgWasFloat.clear(); 123*0a6a1f1dSLionel Sambuc OriginalArgWasF128.clear(); 124*0a6a1f1dSLionel Sambuc return Return; 125*0a6a1f1dSLionel Sambuc } 126*0a6a1f1dSLionel Sambuc WasOriginalArgF128(unsigned ValNo)127*0a6a1f1dSLionel Sambuc bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } WasOriginalArgFloat(unsigned ValNo)128*0a6a1f1dSLionel Sambuc bool WasOriginalArgFloat(unsigned ValNo) { 129*0a6a1f1dSLionel Sambuc return OriginalArgWasFloat[ValNo]; 130*0a6a1f1dSLionel Sambuc } IsCallOperandFixed(unsigned ValNo)131*0a6a1f1dSLionel Sambuc bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; } getSpecialCallingConv()132*0a6a1f1dSLionel Sambuc SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; } 133*0a6a1f1dSLionel Sambuc }; 134*0a6a1f1dSLionel Sambuc } 135*0a6a1f1dSLionel Sambuc 136*0a6a1f1dSLionel Sambuc #endif 137