//===---- MipsCCState.h - CCState with Mips specific extensions -----------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MIPSCCSTATE_H #define MIPSCCSTATE_H #include "MipsISelLowering.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/CallingConvLower.h" namespace llvm { class SDNode; class MipsSubtarget; class MipsCCState : public CCState { public: enum SpecialCallingConvType { Mips16RetHelperConv, NoSpecialCallingConv }; /// Determine the SpecialCallingConvType for the given callee static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget); private: /// Identify lowered values that originated from f128 arguments and record /// this for use by RetCC_MipsN. void PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins, const TargetLowering::CallLoweringInfo &CLI); /// Identify lowered values that originated from f128 arguments and record /// this for use by RetCC_MipsN. void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs); /// Identify lowered values that originated from f128 arguments and record /// this. void PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, std::vector<TargetLowering::ArgListEntry> &FuncArgs, const SDNode *CallNode); /// Identify lowered values that originated from f128 arguments and record /// this. void PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl<ISD::InputArg> &Ins); /// Records whether the value has been lowered from an f128. SmallVector<bool, 4> OriginalArgWasF128; /// Records whether the value has been lowered from float. SmallVector<bool, 4> OriginalArgWasFloat; /// Records whether the value was a fixed argument. /// See ISD::OutputArg::IsFixed, SmallVector<bool, 4> CallOperandIsFixed; // Used to handle MIPS16-specific calling convention tweaks. // FIXME: This should probably be a fully fledged calling convention. SpecialCallingConvType SpecialCallingConv; public: MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, SmallVectorImpl<CCValAssign> &locs, LLVMContext &C, SpecialCallingConvType SpecialCC = NoSpecialCallingConv) : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn, std::vector<TargetLowering::ArgListEntry> &FuncArgs, const SDNode *CallNode) { PreAnalyzeCallOperands(Outs, FuncArgs, CallNode); CCState::AnalyzeCallOperands(Outs, Fn); OriginalArgWasF128.clear(); OriginalArgWasFloat.clear(); CallOperandIsFixed.clear(); } // The AnalyzeCallOperands in the base class is not usable since we must // provide a means of accessing ArgListEntry::IsFixed. Delete them from this // class. This doesn't stop them being used via the base class though. void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn) = delete; void AnalyzeCallOperands(const SmallVectorImpl<MVT> &Outs, SmallVectorImpl<ISD::ArgFlagsTy> &Flags, CCAssignFn Fn) = delete; void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, CCAssignFn Fn) { PreAnalyzeFormalArgumentsForF128(Ins); CCState::AnalyzeFormalArguments(Ins, Fn); OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); } void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, CCAssignFn Fn, const TargetLowering::CallLoweringInfo &CLI) { PreAnalyzeCallResultForF128(Ins, CLI); CCState::AnalyzeCallResult(Ins, Fn); OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); } void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn) { PreAnalyzeReturnForF128(Outs); CCState::AnalyzeReturn(Outs, Fn); OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); } bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, CCAssignFn Fn) { PreAnalyzeReturnForF128(ArgsFlags); bool Return = CCState::CheckReturn(ArgsFlags, Fn); OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); return Return; } bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } bool WasOriginalArgFloat(unsigned ValNo) { return OriginalArgWasFloat[ValNo]; } bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; } SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; } }; } #endif