1 //===---- MipsCCState.h - CCState with Mips specific extensions -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef MIPSCCSTATE_H
11 #define MIPSCCSTATE_H
12 
13 #include "MipsISelLowering.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/CodeGen/CallingConvLower.h"
16 
17 namespace llvm {
18 class SDNode;
19 class MipsSubtarget;
20 
21 class MipsCCState : public CCState {
22 public:
23   enum SpecialCallingConvType { Mips16RetHelperConv, NoSpecialCallingConv };
24 
25   /// Determine the SpecialCallingConvType for the given callee
26   static SpecialCallingConvType
27   getSpecialCallingConvForCallee(const SDNode *Callee,
28                                  const MipsSubtarget &Subtarget);
29 
30 private:
31   /// Identify lowered values that originated from f128 arguments and record
32   /// this for use by RetCC_MipsN.
33   void PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins,
34                                    const Type *RetTy, const char * Func);
35 
36   /// Identify lowered values that originated from f128 arguments and record
37   /// this for use by RetCC_MipsN.
38   void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs);
39 
40   /// Identify lowered values that originated from f128 arguments and record
41   /// this.
42   void
43   PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
44                          std::vector<TargetLowering::ArgListEntry> &FuncArgs,
45                          const char *Func);
46 
47   /// Identify lowered values that originated from f128 arguments and record
48   /// this for use by RetCC_MipsN.
49   void
50   PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl<ISD::InputArg> &Ins);
51 
52   void
53   PreAnalyzeCallResultForVectorFloat(const SmallVectorImpl<ISD::InputArg> &Ins,
54                                      const Type *RetTy);
55 
56   void PreAnalyzeFormalArgumentsForVectorFloat(
57       const SmallVectorImpl<ISD::InputArg> &Ins);
58 
59   void
60   PreAnalyzeReturnForVectorFloat(const SmallVectorImpl<ISD::OutputArg> &Outs);
61 
62   /// Records whether the value has been lowered from an f128.
63   SmallVector<bool, 4> OriginalArgWasF128;
64 
65   /// Records whether the value has been lowered from float.
66   SmallVector<bool, 4> OriginalArgWasFloat;
67 
68   /// Records whether the value has been lowered from a floating point vector.
69   SmallVector<bool, 4> OriginalArgWasFloatVector;
70 
71   /// Records whether the return value has been lowered from a floating point
72   /// vector.
73   SmallVector<bool, 4> OriginalRetWasFloatVector;
74 
75   /// Records whether the value was a fixed argument.
76   /// See ISD::OutputArg::IsFixed,
77   SmallVector<bool, 4> CallOperandIsFixed;
78 
79   // Used to handle MIPS16-specific calling convention tweaks.
80   // FIXME: This should probably be a fully fledged calling convention.
81   SpecialCallingConvType SpecialCallingConv;
82 
83 public:
84   MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
85               SmallVectorImpl<CCValAssign> &locs, LLVMContext &C,
86               SpecialCallingConvType SpecialCC = NoSpecialCallingConv)
CCState(CC,isVarArg,MF,locs,C)87       : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {}
88 
89   void
AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn,std::vector<TargetLowering::ArgListEntry> & FuncArgs,const char * Func)90   AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
91                       CCAssignFn Fn,
92                       std::vector<TargetLowering::ArgListEntry> &FuncArgs,
93                       const char *Func) {
94     PreAnalyzeCallOperands(Outs, FuncArgs, Func);
95     CCState::AnalyzeCallOperands(Outs, Fn);
96     OriginalArgWasF128.clear();
97     OriginalArgWasFloat.clear();
98     OriginalArgWasFloatVector.clear();
99     CallOperandIsFixed.clear();
100   }
101 
102   // The AnalyzeCallOperands in the base class is not usable since we must
103   // provide a means of accessing ArgListEntry::IsFixed. Delete them from this
104   // class. This doesn't stop them being used via the base class though.
105   void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
106                            CCAssignFn Fn) = delete;
107   void AnalyzeCallOperands(const SmallVectorImpl<MVT> &Outs,
108                            SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
109                            CCAssignFn Fn) = delete;
110 
AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn)111   void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
112                               CCAssignFn Fn) {
113     PreAnalyzeFormalArgumentsForF128(Ins);
114     CCState::AnalyzeFormalArguments(Ins, Fn);
115     OriginalArgWasFloat.clear();
116     OriginalArgWasF128.clear();
117     OriginalArgWasFloatVector.clear();
118   }
119 
AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> & Ins,CCAssignFn Fn,const Type * RetTy,const char * Func)120   void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
121                          CCAssignFn Fn, const Type *RetTy,
122                          const char *Func) {
123     PreAnalyzeCallResultForF128(Ins, RetTy, Func);
124     PreAnalyzeCallResultForVectorFloat(Ins, RetTy);
125     CCState::AnalyzeCallResult(Ins, Fn);
126     OriginalArgWasFloat.clear();
127     OriginalArgWasF128.clear();
128     OriginalArgWasFloatVector.clear();
129   }
130 
AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> & Outs,CCAssignFn Fn)131   void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
132                      CCAssignFn Fn) {
133     PreAnalyzeReturnForF128(Outs);
134     PreAnalyzeReturnForVectorFloat(Outs);
135     CCState::AnalyzeReturn(Outs, Fn);
136     OriginalArgWasFloat.clear();
137     OriginalArgWasF128.clear();
138     OriginalArgWasFloatVector.clear();
139   }
140 
CheckReturn(const SmallVectorImpl<ISD::OutputArg> & ArgsFlags,CCAssignFn Fn)141   bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
142                    CCAssignFn Fn) {
143     PreAnalyzeReturnForF128(ArgsFlags);
144     PreAnalyzeReturnForVectorFloat(ArgsFlags);
145     bool Return = CCState::CheckReturn(ArgsFlags, Fn);
146     OriginalArgWasFloat.clear();
147     OriginalArgWasF128.clear();
148     OriginalArgWasFloatVector.clear();
149     return Return;
150   }
151 
WasOriginalArgF128(unsigned ValNo)152   bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; }
WasOriginalArgFloat(unsigned ValNo)153   bool WasOriginalArgFloat(unsigned ValNo) {
154       return OriginalArgWasFloat[ValNo];
155   }
WasOriginalArgVectorFloat(unsigned ValNo)156   bool WasOriginalArgVectorFloat(unsigned ValNo) const {
157     return OriginalArgWasFloatVector[ValNo];
158   }
WasOriginalRetVectorFloat(unsigned ValNo)159   bool WasOriginalRetVectorFloat(unsigned ValNo) const {
160     return OriginalRetWasFloatVector[ValNo];
161   }
IsCallOperandFixed(unsigned ValNo)162   bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; }
getSpecialCallingConv()163   SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; }
164 };
165 }
166 
167 #endif
168