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