xref: /llvm-project/llvm/lib/Target/Mips/MipsCCState.h (revision 754ed95b6672b9a678a994cc652862a91cdc4406)
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 PreAnalyzeCallReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs, const Type *RetTy);
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)
101       : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {}
102 
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
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 
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 
139   void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
140                               CCAssignFn Fn) {
141     PreAnalyzeFormalArguments(Ins, Fn);
142     CCState::AnalyzeFormalArguments(Ins, Fn);
143   }
144 
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 
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 
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 
168   void PreAnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
169                         CCAssignFn Fn) {
170     const MachineFunction &MF = getMachineFunction();
171     OriginalArgWasFloat.clear();
172     OriginalArgWasF128.clear();
173     OriginalArgWasFloatVector.clear();
174     PreAnalyzeCallReturnForF128(Outs, MF.getFunction().getReturnType());
175     PreAnalyzeReturnForVectorFloat(Outs);
176   }
177 
178   void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
179                      CCAssignFn Fn) {
180     PreAnalyzeReturn(Outs, Fn);
181     CCState::AnalyzeReturn(Outs, Fn);
182   }
183 
184   bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
185                    CCAssignFn Fn) {
186     const MachineFunction &MF = getMachineFunction();
187     PreAnalyzeCallReturnForF128(ArgsFlags, MF.getFunction().getReturnType());
188     PreAnalyzeReturnForVectorFloat(ArgsFlags);
189     bool Return = CCState::CheckReturn(ArgsFlags, Fn);
190     OriginalArgWasFloat.clear();
191     OriginalArgWasF128.clear();
192     OriginalArgWasFloatVector.clear();
193     return Return;
194   }
195 
196   bool CheckCallReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
197                    CCAssignFn Fn, const Type *RetTy) {
198     PreAnalyzeCallReturnForF128(ArgsFlags, RetTy);
199     PreAnalyzeReturnForVectorFloat(ArgsFlags);
200     bool Return = CCState::CheckReturn(ArgsFlags, Fn);
201     OriginalArgWasFloat.clear();
202     OriginalArgWasF128.clear();
203     OriginalArgWasFloatVector.clear();
204     return Return;
205   }
206   bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; }
207   bool WasOriginalArgFloat(unsigned ValNo) {
208       return OriginalArgWasFloat[ValNo];
209   }
210   bool WasOriginalArgVectorFloat(unsigned ValNo) const {
211     return OriginalArgWasFloatVector[ValNo];
212   }
213   bool WasOriginalRetVectorFloat(unsigned ValNo) const {
214     return OriginalRetWasFloatVector[ValNo];
215   }
216   bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; }
217   SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; }
218 };
219 }
220 
221 #endif
222