|  | //===---- 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 |