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
16namespace llvm {
17class SDNode;
18class MipsSubtarget;
19
20class MipsCCState : public CCState {
21public:
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
29private:
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
82public:
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