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 /// This function returns true if CallSym is a long double emulation routine. 30 /// 31 /// FIXME: Changing the ABI based on the callee name is unsound. The lib func 32 /// address could be captured. 33 static bool isF128SoftLibCall(const char *CallSym); 34 35 static bool originalTypeIsF128(const Type *Ty, const char *Func); 36 static bool originalEVTTypeIsVectorFloat(EVT Ty); 37 static bool originalTypeIsVectorFloat(const Type *Ty); 38 39 void PreAnalyzeCallOperand(const Type *ArgTy, bool IsFixed, const char *Func); 40 41 void PreAnalyzeFormalArgument(const Type *ArgTy, ISD::ArgFlagsTy Flags); 42 void PreAnalyzeReturnValue(EVT ArgVT); 43 44 private: 45 /// Identify lowered values that originated from f128 arguments and record 46 /// this for use by RetCC_MipsN. 47 void PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins, 48 const Type *RetTy, const char * Func); 49 50 /// Identify lowered values that originated from f128 arguments and record 51 /// this for use by RetCC_MipsN. 52 void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs); 53 54 /// Identify lowered values that originated from f128 arguments and record 55 /// this. 56 void 57 PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 58 std::vector<TargetLowering::ArgListEntry> &FuncArgs, 59 const char *Func); 60 61 /// Identify lowered values that originated from f128 arguments and record 62 /// this for use by RetCC_MipsN. 63 void 64 PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl<ISD::InputArg> &Ins); 65 66 void 67 PreAnalyzeCallResultForVectorFloat(const SmallVectorImpl<ISD::InputArg> &Ins, 68 const Type *RetTy); 69 70 void PreAnalyzeFormalArgumentsForVectorFloat( 71 const SmallVectorImpl<ISD::InputArg> &Ins); 72 73 void 74 PreAnalyzeReturnForVectorFloat(const SmallVectorImpl<ISD::OutputArg> &Outs); 75 76 /// Records whether the value has been lowered from an f128. 77 SmallVector<bool, 4> OriginalArgWasF128; 78 79 /// Records whether the value has been lowered from float. 80 SmallVector<bool, 4> OriginalArgWasFloat; 81 82 /// Records whether the value has been lowered from a floating point vector. 83 SmallVector<bool, 4> OriginalArgWasFloatVector; 84 85 /// Records whether the return value has been lowered from a floating point 86 /// vector. 87 SmallVector<bool, 4> OriginalRetWasFloatVector; 88 89 /// Records whether the value was a fixed argument. 90 /// See ISD::OutputArg::IsFixed, 91 SmallVector<bool, 4> CallOperandIsFixed; 92 93 // Used to handle MIPS16-specific calling convention tweaks. 94 // FIXME: This should probably be a fully fledged calling convention. 95 SpecialCallingConvType SpecialCallingConv; 96 97 public: 98 MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, 99 SmallVectorImpl<CCValAssign> &locs, LLVMContext &C, 100 SpecialCallingConvType SpecialCC = NoSpecialCallingConv) CCState(CC,isVarArg,MF,locs,C)101 : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} 102 PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn,std::vector<TargetLowering::ArgListEntry> & FuncArgs,const char * Func)103 void PreAnalyzeCallOperands( 104 const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn, 105 std::vector<TargetLowering::ArgListEntry> &FuncArgs, const char *Func) { 106 OriginalArgWasF128.clear(); 107 OriginalArgWasFloat.clear(); 108 OriginalArgWasFloatVector.clear(); 109 CallOperandIsFixed.clear(); 110 PreAnalyzeCallOperands(Outs, FuncArgs, Func); 111 } 112 113 void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn,std::vector<TargetLowering::ArgListEntry> & FuncArgs,const char * Func)114 AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 115 CCAssignFn Fn, 116 std::vector<TargetLowering::ArgListEntry> &FuncArgs, 117 const char *Func) { 118 PreAnalyzeCallOperands(Outs, Fn, FuncArgs, Func); 119 CCState::AnalyzeCallOperands(Outs, Fn); 120 } 121 122 // The AnalyzeCallOperands in the base class is not usable since we must 123 // provide a means of accessing ArgListEntry::IsFixed. Delete them from this 124 // class. This doesn't stop them being used via the base class though. 125 void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 126 CCAssignFn Fn) = delete; 127 void AnalyzeCallOperands(const SmallVectorImpl<MVT> &Outs, 128 SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 129 CCAssignFn Fn) = delete; 130 PreAnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn)131 void PreAnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 132 CCAssignFn Fn) { 133 OriginalArgWasFloat.clear(); 134 OriginalArgWasF128.clear(); 135 OriginalArgWasFloatVector.clear(); 136 PreAnalyzeFormalArgumentsForF128(Ins); 137 } 138 AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn)139 void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 140 CCAssignFn Fn) { 141 PreAnalyzeFormalArguments(Ins, Fn); 142 CCState::AnalyzeFormalArguments(Ins, Fn); 143 } 144 PreAnalyzeCallResult(const Type * RetTy,const char * Func)145 void PreAnalyzeCallResult(const Type *RetTy, const char *Func) { 146 OriginalArgWasF128.push_back(originalTypeIsF128(RetTy, Func)); 147 OriginalArgWasFloat.push_back(RetTy->isFloatingPointTy()); 148 OriginalRetWasFloatVector.push_back(originalTypeIsVectorFloat(RetTy)); 149 } 150 PreAnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn,const Type * RetTy,const char * Func)151 void PreAnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 152 CCAssignFn Fn, const Type *RetTy, 153 const char *Func) { 154 OriginalArgWasFloat.clear(); 155 OriginalArgWasF128.clear(); 156 OriginalArgWasFloatVector.clear(); 157 PreAnalyzeCallResultForF128(Ins, RetTy, Func); 158 PreAnalyzeCallResultForVectorFloat(Ins, RetTy); 159 } 160 AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn,const Type * RetTy,const char * Func)161 void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 162 CCAssignFn Fn, const Type *RetTy, 163 const char *Func) { 164 PreAnalyzeCallResult(Ins, Fn, RetTy, Func); 165 CCState::AnalyzeCallResult(Ins, Fn); 166 } 167 PreAnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn)168 void PreAnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 169 CCAssignFn Fn) { 170 OriginalArgWasFloat.clear(); 171 OriginalArgWasF128.clear(); 172 OriginalArgWasFloatVector.clear(); 173 PreAnalyzeReturnForF128(Outs); 174 PreAnalyzeReturnForVectorFloat(Outs); 175 } 176 AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn)177 void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 178 CCAssignFn Fn) { 179 PreAnalyzeReturn(Outs, Fn); 180 CCState::AnalyzeReturn(Outs, Fn); 181 } 182 CheckReturn(const SmallVectorImpl<ISD::OutputArg> & ArgsFlags,CCAssignFn Fn)183 bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 184 CCAssignFn Fn) { 185 PreAnalyzeReturnForF128(ArgsFlags); 186 PreAnalyzeReturnForVectorFloat(ArgsFlags); 187 bool Return = CCState::CheckReturn(ArgsFlags, Fn); 188 OriginalArgWasFloat.clear(); 189 OriginalArgWasF128.clear(); 190 OriginalArgWasFloatVector.clear(); 191 return Return; 192 } 193 WasOriginalArgF128(unsigned ValNo)194 bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } WasOriginalArgFloat(unsigned ValNo)195 bool WasOriginalArgFloat(unsigned ValNo) { 196 return OriginalArgWasFloat[ValNo]; 197 } WasOriginalArgVectorFloat(unsigned ValNo)198 bool WasOriginalArgVectorFloat(unsigned ValNo) const { 199 return OriginalArgWasFloatVector[ValNo]; 200 } WasOriginalRetVectorFloat(unsigned ValNo)201 bool WasOriginalRetVectorFloat(unsigned ValNo) const { 202 return OriginalRetWasFloatVector[ValNo]; 203 } IsCallOperandFixed(unsigned ValNo)204 bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; } getSpecialCallingConv()205 SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; } 206 }; 207 } 208 209 #endif 210