LLVM  3.7.0
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", "fmodl",
28  "log10l", "log2l", "logl", "nearbyintl",
29  "powl", "rintl", "sinl", "sqrtl",
30  "truncl"};
31 
32  const char *const *End = LibCalls + array_lengthof(LibCalls);
33 
34  // Check that LibCalls is sorted alphabetically.
36 
37 #ifndef NDEBUG
38  for (const char *const *I = LibCalls; I < End - 1; ++I)
39  assert(Comp(*I, *(I + 1)));
40 #endif
41 
42  return std::binary_search(LibCalls, End, CallSym, Comp);
43 }
44 
45 /// This function returns true if Ty is fp128, {f128} or i128 which was
46 /// originally a fp128.
47 static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode) {
48  if (Ty->isFP128Ty())
49  return true;
50 
51  if (Ty->isStructTy() && Ty->getStructNumElements() == 1 &&
53  return true;
54 
55  const ExternalSymbolSDNode *ES =
56  dyn_cast_or_null<const ExternalSymbolSDNode>(CallNode);
57 
58  // If the Ty is i128 and the function being called is a long double emulation
59  // routine, then the original type is f128.
60  return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol()));
61 }
62 
65  const MipsSubtarget &Subtarget) {
67  if (Subtarget.inMips16HardFloat()) {
68  if (const GlobalAddressSDNode *G =
69  dyn_cast<const GlobalAddressSDNode>(Callee)) {
70  llvm::StringRef Sym = G->getGlobal()->getName();
71  Function *F = G->getGlobal()->getParent()->getFunction(Sym);
72  if (F && F->hasFnAttribute("__Mips16RetHelper")) {
73  SpecialCallingConv = Mips16RetHelperConv;
74  }
75  }
76  }
77  return SpecialCallingConv;
78 }
79 
80 void MipsCCState::PreAnalyzeCallResultForF128(
83  for (unsigned i = 0; i < Ins.size(); ++i) {
84  OriginalArgWasF128.push_back(
86  OriginalArgWasFloat.push_back(CLI.RetTy->isFloatingPointTy());
87  }
88 }
89 
90 /// Identify lowered values that originated from f128 arguments and record
91 /// this for use by RetCC_MipsN.
92 void MipsCCState::PreAnalyzeReturnForF128(
93  const SmallVectorImpl<ISD::OutputArg> &Outs) {
94  const MachineFunction &MF = getMachineFunction();
95  for (unsigned i = 0; i < Outs.size(); ++i) {
96  OriginalArgWasF128.push_back(
97  originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr));
98  OriginalArgWasFloat.push_back(
100  }
101 }
102 
103 /// Identify lowered values that originated from f128 arguments and record
104 /// this.
105 void MipsCCState::PreAnalyzeCallOperands(
107  std::vector<TargetLowering::ArgListEntry> &FuncArgs,
108  const SDNode *CallNode) {
109  for (unsigned i = 0; i < Outs.size(); ++i) {
110  OriginalArgWasF128.push_back(
111  originalTypeIsF128(FuncArgs[Outs[i].OrigArgIndex].Ty, CallNode));
112  OriginalArgWasFloat.push_back(
113  FuncArgs[Outs[i].OrigArgIndex].Ty->isFloatingPointTy());
114  CallOperandIsFixed.push_back(Outs[i].IsFixed);
115  }
116 }
117 
118 /// Identify lowered values that originated from f128 arguments and record
119 /// this.
120 void MipsCCState::PreAnalyzeFormalArgumentsForF128(
121  const SmallVectorImpl<ISD::InputArg> &Ins) {
122  const MachineFunction &MF = getMachineFunction();
123  for (unsigned i = 0; i < Ins.size(); ++i) {
125 
126  // SRet arguments cannot originate from f128 or {f128} returns so we just
127  // push false. We have to handle this specially since SRet arguments
128  // aren't mapped to an original argument.
129  if (Ins[i].Flags.isSRet()) {
130  OriginalArgWasF128.push_back(false);
131  OriginalArgWasFloat.push_back(false);
132  continue;
133  }
134 
135  assert(Ins[i].getOrigArgIndex() < MF.getFunction()->arg_size());
136  std::advance(FuncArg, Ins[i].getOrigArgIndex());
137 
138  OriginalArgWasF128.push_back(
139  originalTypeIsF128(FuncArg->getType(), nullptr));
140  OriginalArgWasFloat.push_back(FuncArg->getType()->isFloatingPointTy());
141  }
142 }
void push_back(const T &Elt)
Definition: SmallVector.h:222
const char * getSymbol() const
unsigned getStructNumElements() const
Definition: Type.cpp:196
Type * getReturnType() const
Definition: Function.cpp:233
F(f)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode)
This function returns true if Ty is fp128, {f128} or i128 which was originally a fp128.
Definition: MipsCCState.cpp:47
size_t arg_size() const
Definition: Function.cpp:301
static void advance(T &it, size_t Val)
bool inMips16HardFloat() const
#define G(x, y, z)
Definition: MD5.cpp:52
MachineFunction & getMachineFunction() const
static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget)
Determine the SpecialCallingConvType for the given callee.
Definition: MipsCCState.cpp:64
bool isFloatingPointTy() const
isFloatingPointTy - Return true if this is one of the six floating point types
Definition: Type.h:159
static bool isF128SoftLibCall(const char *CallSym)
This function returns true if CallSym is a long double emulation routine.
Definition: MipsCCState.cpp:17
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:247
SDNode * getNode() const
get the SDNode which holds the desired result
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
arg_iterator arg_begin()
Definition: Function.h:472
bool isFP128Ty() const
isFP128Ty - Return true if this is 'fp128'.
Definition: Type.h:152
This structure contains all information that is necessary for lowering calls.
Module.h This file contains the declarations for the Module class.
Represents one node in the SelectionDAG.
bool isIntegerTy() const
isIntegerTy - True if this is an instance of IntegerType.
Definition: Type.h:193
bool isStructTy() const
isStructTy - True if this is an instance of StructType.
Definition: Type.h:209
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:217
#define I(x, y, z)
Definition: MD5.cpp:54
Type * getStructElementType(unsigned N) const
Definition: Type.cpp:200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40