xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/MipsCCState.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric //===---- MipsCCState.h - CCState with Mips specific extensions -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef MIPSCCSTATE_H
100b57cec5SDimitry Andric #define MIPSCCSTATE_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "MipsISelLowering.h"
130b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric namespace llvm {
170b57cec5SDimitry Andric class SDNode;
180b57cec5SDimitry Andric class MipsSubtarget;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric class MipsCCState : public CCState {
210b57cec5SDimitry Andric public:
220b57cec5SDimitry Andric   enum SpecialCallingConvType { Mips16RetHelperConv, NoSpecialCallingConv };
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric   /// Determine the SpecialCallingConvType for the given callee
250b57cec5SDimitry Andric   static SpecialCallingConvType
260b57cec5SDimitry Andric   getSpecialCallingConvForCallee(const SDNode *Callee,
270b57cec5SDimitry Andric                                  const MipsSubtarget &Subtarget);
280b57cec5SDimitry Andric 
29*fe6060f1SDimitry Andric   /// This function returns true if CallSym is a long double emulation routine.
30*fe6060f1SDimitry Andric   ///
31*fe6060f1SDimitry Andric   /// FIXME: Changing the ABI based on the callee name is unsound. The lib func
32*fe6060f1SDimitry Andric   /// address could be captured.
33*fe6060f1SDimitry Andric   static bool isF128SoftLibCall(const char *CallSym);
34*fe6060f1SDimitry Andric 
35*fe6060f1SDimitry Andric   static bool originalTypeIsF128(const Type *Ty, const char *Func);
36*fe6060f1SDimitry Andric   static bool originalEVTTypeIsVectorFloat(EVT Ty);
37*fe6060f1SDimitry Andric   static bool originalTypeIsVectorFloat(const Type *Ty);
38*fe6060f1SDimitry Andric 
39*fe6060f1SDimitry Andric   void PreAnalyzeCallOperand(const Type *ArgTy, bool IsFixed, const char *Func);
40*fe6060f1SDimitry Andric 
41*fe6060f1SDimitry Andric   void PreAnalyzeFormalArgument(const Type *ArgTy, ISD::ArgFlagsTy Flags);
42*fe6060f1SDimitry Andric   void PreAnalyzeReturnValue(EVT ArgVT);
43*fe6060f1SDimitry Andric 
440b57cec5SDimitry Andric private:
450b57cec5SDimitry Andric   /// Identify lowered values that originated from f128 arguments and record
460b57cec5SDimitry Andric   /// this for use by RetCC_MipsN.
470b57cec5SDimitry Andric   void PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins,
480b57cec5SDimitry Andric                                    const Type *RetTy, const char * Func);
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   /// Identify lowered values that originated from f128 arguments and record
510b57cec5SDimitry Andric   /// this for use by RetCC_MipsN.
520b57cec5SDimitry Andric   void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs);
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   /// Identify lowered values that originated from f128 arguments and record
550b57cec5SDimitry Andric   /// this.
560b57cec5SDimitry Andric   void
570b57cec5SDimitry Andric   PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
580b57cec5SDimitry Andric                          std::vector<TargetLowering::ArgListEntry> &FuncArgs,
590b57cec5SDimitry Andric                          const char *Func);
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   /// Identify lowered values that originated from f128 arguments and record
620b57cec5SDimitry Andric   /// this for use by RetCC_MipsN.
630b57cec5SDimitry Andric   void
640b57cec5SDimitry Andric   PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl<ISD::InputArg> &Ins);
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   void
670b57cec5SDimitry Andric   PreAnalyzeCallResultForVectorFloat(const SmallVectorImpl<ISD::InputArg> &Ins,
680b57cec5SDimitry Andric                                      const Type *RetTy);
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   void PreAnalyzeFormalArgumentsForVectorFloat(
710b57cec5SDimitry Andric       const SmallVectorImpl<ISD::InputArg> &Ins);
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   void
740b57cec5SDimitry Andric   PreAnalyzeReturnForVectorFloat(const SmallVectorImpl<ISD::OutputArg> &Outs);
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// Records whether the value has been lowered from an f128.
770b57cec5SDimitry Andric   SmallVector<bool, 4> OriginalArgWasF128;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   /// Records whether the value has been lowered from float.
800b57cec5SDimitry Andric   SmallVector<bool, 4> OriginalArgWasFloat;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// Records whether the value has been lowered from a floating point vector.
830b57cec5SDimitry Andric   SmallVector<bool, 4> OriginalArgWasFloatVector;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// Records whether the return value has been lowered from a floating point
860b57cec5SDimitry Andric   /// vector.
870b57cec5SDimitry Andric   SmallVector<bool, 4> OriginalRetWasFloatVector;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   /// Records whether the value was a fixed argument.
900b57cec5SDimitry Andric   /// See ISD::OutputArg::IsFixed,
910b57cec5SDimitry Andric   SmallVector<bool, 4> CallOperandIsFixed;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   // Used to handle MIPS16-specific calling convention tweaks.
940b57cec5SDimitry Andric   // FIXME: This should probably be a fully fledged calling convention.
950b57cec5SDimitry Andric   SpecialCallingConvType SpecialCallingConv;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric public:
980b57cec5SDimitry Andric   MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
990b57cec5SDimitry Andric               SmallVectorImpl<CCValAssign> &locs, LLVMContext &C,
1000b57cec5SDimitry Andric               SpecialCallingConvType SpecialCC = NoSpecialCallingConv)
CCState(CC,isVarArg,MF,locs,C)1010b57cec5SDimitry Andric       : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {}
1020b57cec5SDimitry Andric 
PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn,std::vector<TargetLowering::ArgListEntry> & FuncArgs,const char * Func)103*fe6060f1SDimitry Andric   void PreAnalyzeCallOperands(
104*fe6060f1SDimitry Andric       const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn,
105*fe6060f1SDimitry Andric       std::vector<TargetLowering::ArgListEntry> &FuncArgs, const char *Func) {
106*fe6060f1SDimitry Andric     OriginalArgWasF128.clear();
107*fe6060f1SDimitry Andric     OriginalArgWasFloat.clear();
108*fe6060f1SDimitry Andric     OriginalArgWasFloatVector.clear();
109*fe6060f1SDimitry Andric     CallOperandIsFixed.clear();
110*fe6060f1SDimitry Andric     PreAnalyzeCallOperands(Outs, FuncArgs, Func);
111*fe6060f1SDimitry Andric   }
112*fe6060f1SDimitry Andric 
1130b57cec5SDimitry Andric   void
AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn,std::vector<TargetLowering::ArgListEntry> & FuncArgs,const char * Func)1140b57cec5SDimitry Andric   AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
1150b57cec5SDimitry Andric                       CCAssignFn Fn,
1160b57cec5SDimitry Andric                       std::vector<TargetLowering::ArgListEntry> &FuncArgs,
1170b57cec5SDimitry Andric                       const char *Func) {
118*fe6060f1SDimitry Andric     PreAnalyzeCallOperands(Outs, Fn, FuncArgs, Func);
1190b57cec5SDimitry Andric     CCState::AnalyzeCallOperands(Outs, Fn);
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   // The AnalyzeCallOperands in the base class is not usable since we must
1230b57cec5SDimitry Andric   // provide a means of accessing ArgListEntry::IsFixed. Delete them from this
1240b57cec5SDimitry Andric   // class. This doesn't stop them being used via the base class though.
1250b57cec5SDimitry Andric   void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
1260b57cec5SDimitry Andric                            CCAssignFn Fn) = delete;
1270b57cec5SDimitry Andric   void AnalyzeCallOperands(const SmallVectorImpl<MVT> &Outs,
1280b57cec5SDimitry Andric                            SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
1290b57cec5SDimitry Andric                            CCAssignFn Fn) = delete;
1300b57cec5SDimitry Andric 
PreAnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn)131*fe6060f1SDimitry Andric   void PreAnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
1320b57cec5SDimitry Andric                                  CCAssignFn Fn) {
1330b57cec5SDimitry Andric     OriginalArgWasFloat.clear();
1340b57cec5SDimitry Andric     OriginalArgWasF128.clear();
1350b57cec5SDimitry Andric     OriginalArgWasFloatVector.clear();
136*fe6060f1SDimitry Andric     PreAnalyzeFormalArgumentsForF128(Ins);
137*fe6060f1SDimitry Andric   }
138*fe6060f1SDimitry Andric 
AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn)139*fe6060f1SDimitry Andric   void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
140*fe6060f1SDimitry Andric                               CCAssignFn Fn) {
141*fe6060f1SDimitry Andric     PreAnalyzeFormalArguments(Ins, Fn);
142*fe6060f1SDimitry Andric     CCState::AnalyzeFormalArguments(Ins, Fn);
143*fe6060f1SDimitry Andric   }
144*fe6060f1SDimitry Andric 
PreAnalyzeCallResult(const Type * RetTy,const char * Func)145*fe6060f1SDimitry Andric   void PreAnalyzeCallResult(const Type *RetTy, const char *Func) {
146*fe6060f1SDimitry Andric     OriginalArgWasF128.push_back(originalTypeIsF128(RetTy, Func));
147*fe6060f1SDimitry Andric     OriginalArgWasFloat.push_back(RetTy->isFloatingPointTy());
148*fe6060f1SDimitry Andric     OriginalRetWasFloatVector.push_back(originalTypeIsVectorFloat(RetTy));
149*fe6060f1SDimitry Andric   }
150*fe6060f1SDimitry Andric 
PreAnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn,const Type * RetTy,const char * Func)151*fe6060f1SDimitry Andric   void PreAnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
152*fe6060f1SDimitry Andric                             CCAssignFn Fn, const Type *RetTy,
153*fe6060f1SDimitry Andric                             const char *Func) {
154*fe6060f1SDimitry Andric     OriginalArgWasFloat.clear();
155*fe6060f1SDimitry Andric     OriginalArgWasF128.clear();
156*fe6060f1SDimitry Andric     OriginalArgWasFloatVector.clear();
157*fe6060f1SDimitry Andric     PreAnalyzeCallResultForF128(Ins, RetTy, Func);
158*fe6060f1SDimitry Andric     PreAnalyzeCallResultForVectorFloat(Ins, RetTy);
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric 
AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn,const Type * RetTy,const char * Func)1610b57cec5SDimitry Andric   void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
1620b57cec5SDimitry Andric                          CCAssignFn Fn, const Type *RetTy,
1630b57cec5SDimitry Andric                          const char *Func) {
164*fe6060f1SDimitry Andric     PreAnalyzeCallResult(Ins, Fn, RetTy, Func);
1650b57cec5SDimitry Andric     CCState::AnalyzeCallResult(Ins, Fn);
166*fe6060f1SDimitry Andric   }
167*fe6060f1SDimitry Andric 
PreAnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn)168*fe6060f1SDimitry Andric   void PreAnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
169*fe6060f1SDimitry Andric                         CCAssignFn Fn) {
1700b57cec5SDimitry Andric     OriginalArgWasFloat.clear();
1710b57cec5SDimitry Andric     OriginalArgWasF128.clear();
1720b57cec5SDimitry Andric     OriginalArgWasFloatVector.clear();
173*fe6060f1SDimitry Andric     PreAnalyzeReturnForF128(Outs);
174*fe6060f1SDimitry Andric     PreAnalyzeReturnForVectorFloat(Outs);
1750b57cec5SDimitry Andric   }
1760b57cec5SDimitry Andric 
AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn)1770b57cec5SDimitry Andric   void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
1780b57cec5SDimitry Andric                      CCAssignFn Fn) {
179*fe6060f1SDimitry Andric     PreAnalyzeReturn(Outs, Fn);
1800b57cec5SDimitry Andric     CCState::AnalyzeReturn(Outs, Fn);
1810b57cec5SDimitry Andric   }
1820b57cec5SDimitry Andric 
CheckReturn(const SmallVectorImpl<ISD::OutputArg> & ArgsFlags,CCAssignFn Fn)1830b57cec5SDimitry Andric   bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
1840b57cec5SDimitry Andric                    CCAssignFn Fn) {
1850b57cec5SDimitry Andric     PreAnalyzeReturnForF128(ArgsFlags);
1860b57cec5SDimitry Andric     PreAnalyzeReturnForVectorFloat(ArgsFlags);
1870b57cec5SDimitry Andric     bool Return = CCState::CheckReturn(ArgsFlags, Fn);
1880b57cec5SDimitry Andric     OriginalArgWasFloat.clear();
1890b57cec5SDimitry Andric     OriginalArgWasF128.clear();
1900b57cec5SDimitry Andric     OriginalArgWasFloatVector.clear();
1910b57cec5SDimitry Andric     return Return;
1920b57cec5SDimitry Andric   }
1930b57cec5SDimitry Andric 
WasOriginalArgF128(unsigned ValNo)1940b57cec5SDimitry Andric   bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; }
WasOriginalArgFloat(unsigned ValNo)1950b57cec5SDimitry Andric   bool WasOriginalArgFloat(unsigned ValNo) {
1960b57cec5SDimitry Andric       return OriginalArgWasFloat[ValNo];
1970b57cec5SDimitry Andric   }
WasOriginalArgVectorFloat(unsigned ValNo)1980b57cec5SDimitry Andric   bool WasOriginalArgVectorFloat(unsigned ValNo) const {
1990b57cec5SDimitry Andric     return OriginalArgWasFloatVector[ValNo];
2000b57cec5SDimitry Andric   }
WasOriginalRetVectorFloat(unsigned ValNo)2010b57cec5SDimitry Andric   bool WasOriginalRetVectorFloat(unsigned ValNo) const {
2020b57cec5SDimitry Andric     return OriginalRetWasFloatVector[ValNo];
2030b57cec5SDimitry Andric   }
IsCallOperandFixed(unsigned ValNo)2040b57cec5SDimitry Andric   bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; }
getSpecialCallingConv()2050b57cec5SDimitry Andric   SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; }
2060b57cec5SDimitry Andric };
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric #endif
210