1 //===---- MipsCCState.h - CCState with Mips specific extensions -----------===//
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
7 //===----------------------------------------------------------------------===//
12 #include "MipsISelLowering.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/CodeGen/CallingConvLower.h"
20 class MipsCCState
: public CCState
{
22 enum SpecialCallingConvType
{ Mips16RetHelperConv
, NoSpecialCallingConv
};
24 /// Determine the SpecialCallingConvType for the given callee
25 static SpecialCallingConvType
26 getSpecialCallingConvForCallee(const SDNode
*Callee
,
27 const MipsSubtarget
&Subtarget
);
29 /// This function returns true if CallSym is a long double emulation routine.
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
);
35 static bool originalTypeIsF128(const Type
*Ty
, const char *Func
);
36 static bool originalEVTTypeIsVectorFloat(EVT Ty
);
37 static bool originalTypeIsVectorFloat(const Type
*Ty
);
39 void PreAnalyzeCallOperand(const Type
*ArgTy
, bool IsFixed
, const char *Func
);
41 void PreAnalyzeFormalArgument(const Type
*ArgTy
, ISD::ArgFlagsTy Flags
);
42 void PreAnalyzeReturnValue(EVT ArgVT
);
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
);
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
);
54 /// Identify lowered values that originated from f128 arguments and record
57 PreAnalyzeCallOperands(const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
58 std::vector
<TargetLowering::ArgListEntry
> &FuncArgs
,
61 /// Identify lowered values that originated from f128 arguments and record
62 /// this for use by RetCC_MipsN.
64 PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl
<ISD::InputArg
> &Ins
);
67 PreAnalyzeCallResultForVectorFloat(const SmallVectorImpl
<ISD::InputArg
> &Ins
,
70 void PreAnalyzeFormalArgumentsForVectorFloat(
71 const SmallVectorImpl
<ISD::InputArg
> &Ins
);
74 PreAnalyzeReturnForVectorFloat(const SmallVectorImpl
<ISD::OutputArg
> &Outs
);
76 /// Records whether the value has been lowered from an f128.
77 SmallVector
<bool, 4> OriginalArgWasF128
;
79 /// Records whether the value has been lowered from float.
80 SmallVector
<bool, 4> OriginalArgWasFloat
;
82 /// Records whether the value has been lowered from a floating point vector.
83 SmallVector
<bool, 4> OriginalArgWasFloatVector
;
85 /// Records whether the return value has been lowered from a floating point
87 SmallVector
<bool, 4> OriginalRetWasFloatVector
;
89 /// Records whether the value was a fixed argument.
90 /// See ISD::OutputArg::IsFixed,
91 SmallVector
<bool, 4> CallOperandIsFixed
;
93 // Used to handle MIPS16-specific calling convention tweaks.
94 // FIXME: This should probably be a fully fledged calling convention.
95 SpecialCallingConvType SpecialCallingConv
;
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
) {}
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
);
114 AnalyzeCallOperands(const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
116 std::vector
<TargetLowering::ArgListEntry
> &FuncArgs
,
118 PreAnalyzeCallOperands(Outs
, Fn
, FuncArgs
, Func
);
119 CCState::AnalyzeCallOperands(Outs
, Fn
);
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;
131 void PreAnalyzeFormalArguments(const SmallVectorImpl
<ISD::InputArg
> &Ins
,
133 OriginalArgWasFloat
.clear();
134 OriginalArgWasF128
.clear();
135 OriginalArgWasFloatVector
.clear();
136 PreAnalyzeFormalArgumentsForF128(Ins
);
139 void AnalyzeFormalArguments(const SmallVectorImpl
<ISD::InputArg
> &Ins
,
141 PreAnalyzeFormalArguments(Ins
, Fn
);
142 CCState::AnalyzeFormalArguments(Ins
, Fn
);
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
));
151 void PreAnalyzeCallResult(const SmallVectorImpl
<ISD::InputArg
> &Ins
,
152 CCAssignFn Fn
, const Type
*RetTy
,
154 OriginalArgWasFloat
.clear();
155 OriginalArgWasF128
.clear();
156 OriginalArgWasFloatVector
.clear();
157 PreAnalyzeCallResultForF128(Ins
, RetTy
, Func
);
158 PreAnalyzeCallResultForVectorFloat(Ins
, RetTy
);
161 void AnalyzeCallResult(const SmallVectorImpl
<ISD::InputArg
> &Ins
,
162 CCAssignFn Fn
, const Type
*RetTy
,
164 PreAnalyzeCallResult(Ins
, Fn
, RetTy
, Func
);
165 CCState::AnalyzeCallResult(Ins
, Fn
);
168 void PreAnalyzeReturn(const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
170 OriginalArgWasFloat
.clear();
171 OriginalArgWasF128
.clear();
172 OriginalArgWasFloatVector
.clear();
173 PreAnalyzeReturnForF128(Outs
);
174 PreAnalyzeReturnForVectorFloat(Outs
);
177 void AnalyzeReturn(const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
179 PreAnalyzeReturn(Outs
, Fn
);
180 CCState::AnalyzeReturn(Outs
, Fn
);
183 bool CheckReturn(const SmallVectorImpl
<ISD::OutputArg
> &ArgsFlags
,
185 PreAnalyzeReturnForF128(ArgsFlags
);
186 PreAnalyzeReturnForVectorFloat(ArgsFlags
);
187 bool Return
= CCState::CheckReturn(ArgsFlags
, Fn
);
188 OriginalArgWasFloat
.clear();
189 OriginalArgWasF128
.clear();
190 OriginalArgWasFloatVector
.clear();
194 bool WasOriginalArgF128(unsigned ValNo
) { return OriginalArgWasF128
[ValNo
]; }
195 bool WasOriginalArgFloat(unsigned ValNo
) {
196 return OriginalArgWasFloat
[ValNo
];
198 bool WasOriginalArgVectorFloat(unsigned ValNo
) const {
199 return OriginalArgWasFloatVector
[ValNo
];
201 bool WasOriginalRetVectorFloat(unsigned ValNo
) const {
202 return OriginalRetWasFloatVector
[ValNo
];
204 bool IsCallOperandFixed(unsigned ValNo
) { return CallOperandIsFixed
[ValNo
]; }
205 SpecialCallingConvType
getSpecialCallingConv() { return SpecialCallingConv
; }