LLVM  8.0.1
MipsCCState.cpp
Go to the documentation of this file.
1 //===---- MipsCCState.cpp - 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 #include "MipsCCState.h"
11 #include "MipsSubtarget.h"
12 #include "llvm/IR/Module.h"
13 
14 using namespace llvm;
15 
16 /// This function returns true if CallSym is a long double emulation routine.
17 static bool isF128SoftLibCall(const char *CallSym) {
18  const char *const LibCalls[] = {
19  "__addtf3", "__divtf3", "__eqtf2", "__extenddftf2",
20  "__extendsftf2", "__fixtfdi", "__fixtfsi", "__fixtfti",
21  "__fixunstfdi", "__fixunstfsi", "__fixunstfti", "__floatditf",
22  "__floatsitf", "__floattitf", "__floatunditf", "__floatunsitf",
23  "__floatuntitf", "__getf2", "__gttf2", "__letf2",
24  "__lttf2", "__multf3", "__netf2", "__powitf2",
25  "__subtf3", "__trunctfdf2", "__trunctfsf2", "__unordtf2",
26  "ceill", "copysignl", "cosl", "exp2l",
27  "expl", "floorl", "fmal", "fmaxl",
28  "fmodl", "log10l", "log2l", "logl",
29  "nearbyintl", "powl", "rintl", "roundl",
30  "sinl", "sqrtl", "truncl"};
31 
32  // Check that LibCalls is sorted alphabetically.
33  auto Comp = [](const char *S1, const char *S2) { return strcmp(S1, S2) < 0; };
34  assert(std::is_sorted(std::begin(LibCalls), std::end(LibCalls), Comp));
35  return std::binary_search(std::begin(LibCalls), std::end(LibCalls),
36  CallSym, Comp);
37 }
38 
39 /// This function returns true if Ty is fp128, {f128} or i128 which was
40 /// originally a fp128.
41 static bool originalTypeIsF128(const Type *Ty, const char *Func) {
42  if (Ty->isFP128Ty())
43  return true;
44 
45  if (Ty->isStructTy() && Ty->getStructNumElements() == 1 &&
47  return true;
48 
49  // If the Ty is i128 and the function being called is a long double emulation
50  // routine, then the original type is f128.
51  return (Func && Ty->isIntegerTy(128) && isF128SoftLibCall(Func));
52 }
53 
54 /// Return true if the original type was vXfXX.
57  return true;
58 
59  return false;
60 }
61 
62 /// Return true if the original type was vXfXX / vXfXX.
63 static bool originalTypeIsVectorFloat(const Type * Ty) {
64  if (Ty->isVectorTy() && Ty->isFPOrFPVectorTy())
65  return true;
66 
67  return false;
68 }
69 
72  const MipsSubtarget &Subtarget) {
74  if (Subtarget.inMips16HardFloat()) {
75  if (const GlobalAddressSDNode *G =
76  dyn_cast<const GlobalAddressSDNode>(Callee)) {
77  llvm::StringRef Sym = G->getGlobal()->getName();
78  Function *F = G->getGlobal()->getParent()->getFunction(Sym);
79  if (F && F->hasFnAttribute("__Mips16RetHelper")) {
80  SpecialCallingConv = Mips16RetHelperConv;
81  }
82  }
83  }
84  return SpecialCallingConv;
85 }
86 
87 void MipsCCState::PreAnalyzeCallResultForF128(
89  const Type *RetTy, const char *Call) {
90  for (unsigned i = 0; i < Ins.size(); ++i) {
91  OriginalArgWasF128.push_back(
92  originalTypeIsF128(RetTy, Call));
93  OriginalArgWasFloat.push_back(RetTy->isFloatingPointTy());
94  }
95 }
96 
97 /// Identify lowered values that originated from f128 or float arguments and
98 /// record this for use by RetCC_MipsN.
99 void MipsCCState::PreAnalyzeReturnForF128(
100  const SmallVectorImpl<ISD::OutputArg> &Outs) {
101  const MachineFunction &MF = getMachineFunction();
102  for (unsigned i = 0; i < Outs.size(); ++i) {
103  OriginalArgWasF128.push_back(
104  originalTypeIsF128(MF.getFunction().getReturnType(), nullptr));
105  OriginalArgWasFloat.push_back(
107  }
108 }
109 
110 /// Identify lower values that originated from vXfXX and record
111 /// this.
112 void MipsCCState::PreAnalyzeCallResultForVectorFloat(
113  const SmallVectorImpl<ISD::InputArg> &Ins, const Type *RetTy) {
114  for (unsigned i = 0; i < Ins.size(); ++i) {
115  OriginalRetWasFloatVector.push_back(originalTypeIsVectorFloat(RetTy));
116  }
117 }
118 
119 /// Identify lowered values that originated from vXfXX arguments and record
120 /// this.
121 void MipsCCState::PreAnalyzeReturnForVectorFloat(
122  const SmallVectorImpl<ISD::OutputArg> &Outs) {
123  for (unsigned i = 0; i < Outs.size(); ++i) {
124  ISD::OutputArg Out = Outs[i];
125  OriginalRetWasFloatVector.push_back(
127  }
128 }
129 
130 /// Identify lowered values that originated from f128, float and sret to vXfXX
131 /// arguments and record this.
132 void MipsCCState::PreAnalyzeCallOperands(
134  std::vector<TargetLowering::ArgListEntry> &FuncArgs,
135  const char *Func) {
136  for (unsigned i = 0; i < Outs.size(); ++i) {
137  TargetLowering::ArgListEntry FuncArg = FuncArgs[Outs[i].OrigArgIndex];
138 
139  OriginalArgWasF128.push_back(originalTypeIsF128(FuncArg.Ty, Func));
140  OriginalArgWasFloat.push_back(FuncArg.Ty->isFloatingPointTy());
141  OriginalArgWasFloatVector.push_back(FuncArg.Ty->isVectorTy());
142  CallOperandIsFixed.push_back(Outs[i].IsFixed);
143  }
144 }
145 
146 /// Identify lowered values that originated from f128, float and vXfXX arguments
147 /// and record this.
148 void MipsCCState::PreAnalyzeFormalArgumentsForF128(
149  const SmallVectorImpl<ISD::InputArg> &Ins) {
150  const MachineFunction &MF = getMachineFunction();
151  for (unsigned i = 0; i < Ins.size(); ++i) {
153 
154  // SRet arguments cannot originate from f128 or {f128} returns so we just
155  // push false. We have to handle this specially since SRet arguments
156  // aren't mapped to an original argument.
157  if (Ins[i].Flags.isSRet()) {
158  OriginalArgWasF128.push_back(false);
159  OriginalArgWasFloat.push_back(false);
160  OriginalArgWasFloatVector.push_back(false);
161  continue;
162  }
163 
164  assert(Ins[i].getOrigArgIndex() < MF.getFunction().arg_size());
165  std::advance(FuncArg, Ins[i].getOrigArgIndex());
166 
167  OriginalArgWasF128.push_back(
168  originalTypeIsF128(FuncArg->getType(), nullptr));
169  OriginalArgWasFloat.push_back(FuncArg->getType()->isFloatingPointTy());
170 
171  // The MIPS vector ABI exhibits a corner case of sorts or quirk; if the
172  // first argument is actually an SRet pointer to a vector, then the next
173  // argument slot is $a2.
174  OriginalArgWasFloatVector.push_back(FuncArg->getType()->isVectorTy());
175  }
176 }
bool inMips16HardFloat() const
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:259
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void push_back(const T &Elt)
Definition: SmallVector.h:218
bool isFP128Ty() const
Return true if this is &#39;fp128&#39;.
Definition: Type.h:156
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:321
F(f)
Type * getStructElementType(unsigned N) const
Definition: DerivedTypes.h:333
MachineFunction & getMachineFunction() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:230
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: ValueTypes.h:136
bool isFloatingPointTy() const
Return true if this is one of the six floating-point types.
Definition: Type.h:162
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:197
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
static bool originalEVTTypeIsVectorFloat(EVT Ty)
Return true if the original type was vXfXX.
Definition: MipsCCState.cpp:55
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget)
Determine the SpecialCallingConvType for the given callee.
Definition: MipsCCState.cpp:71
static bool isF128SoftLibCall(const char *CallSym)
This function returns true if CallSym is a long double emulation routine.
Definition: MipsCCState.cpp:17
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:169
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
size_t arg_size() const
Definition: Function.h:698
unsigned getStructNumElements() const
Definition: DerivedTypes.h:329
arg_iterator arg_begin()
Definition: Function.h:671
Extended Value Type.
Definition: ValueTypes.h:34
size_t size() const
Definition: SmallVector.h:53
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:265
Module.h This file contains the declarations for the Module class.
const DataFlowGraph & G
Definition: RDFGraph.cpp:211
Represents one node in the SelectionDAG.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:151
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition: Type.h:185
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool originalTypeIsVectorFloat(const Type *Ty)
Return true if the original type was vXfXX / vXfXX.
Definition: MipsCCState.cpp:63
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static bool originalTypeIsF128(const Type *Ty, const char *Func)
This function returns true if Ty is fp128, {f128} or i128 which was originally a fp128.
Definition: MipsCCState.cpp:41
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:218