LLVM  4.0.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", "roundl", "sinl",
30  "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(Type *Ty, const SDNode *CallNode) {
42  if (Ty->isFP128Ty())
43  return true;
44 
45  if (Ty->isStructTy() && Ty->getStructNumElements() == 1 &&
47  return true;
48 
49  const ExternalSymbolSDNode *ES =
50  dyn_cast_or_null<const ExternalSymbolSDNode>(CallNode);
51 
52  // If the Ty is i128 and the function being called is a long double emulation
53  // routine, then the original type is f128.
54  return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol()));
55 }
56 
59  const MipsSubtarget &Subtarget) {
61  if (Subtarget.inMips16HardFloat()) {
62  if (const GlobalAddressSDNode *G =
63  dyn_cast<const GlobalAddressSDNode>(Callee)) {
64  llvm::StringRef Sym = G->getGlobal()->getName();
65  Function *F = G->getGlobal()->getParent()->getFunction(Sym);
66  if (F && F->hasFnAttribute("__Mips16RetHelper")) {
67  SpecialCallingConv = Mips16RetHelperConv;
68  }
69  }
70  }
71  return SpecialCallingConv;
72 }
73 
74 void MipsCCState::PreAnalyzeCallResultForF128(
77  for (unsigned i = 0; i < Ins.size(); ++i) {
78  OriginalArgWasF128.push_back(
80  OriginalArgWasFloat.push_back(CLI.RetTy->isFloatingPointTy());
81  }
82 }
83 
84 /// Identify lowered values that originated from f128 arguments and record
85 /// this for use by RetCC_MipsN.
86 void MipsCCState::PreAnalyzeReturnForF128(
87  const SmallVectorImpl<ISD::OutputArg> &Outs) {
88  const MachineFunction &MF = getMachineFunction();
89  for (unsigned i = 0; i < Outs.size(); ++i) {
90  OriginalArgWasF128.push_back(
91  originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr));
92  OriginalArgWasFloat.push_back(
94  }
95 }
96 
97 /// Identify lowered values that originated from f128 arguments and record
98 /// this.
99 void MipsCCState::PreAnalyzeCallOperands(
101  std::vector<TargetLowering::ArgListEntry> &FuncArgs,
102  const SDNode *CallNode) {
103  for (unsigned i = 0; i < Outs.size(); ++i) {
104  OriginalArgWasF128.push_back(
105  originalTypeIsF128(FuncArgs[Outs[i].OrigArgIndex].Ty, CallNode));
106  OriginalArgWasFloat.push_back(
107  FuncArgs[Outs[i].OrigArgIndex].Ty->isFloatingPointTy());
108  CallOperandIsFixed.push_back(Outs[i].IsFixed);
109  }
110 }
111 
112 /// Identify lowered values that originated from f128 arguments and record
113 /// this.
114 void MipsCCState::PreAnalyzeFormalArgumentsForF128(
115  const SmallVectorImpl<ISD::InputArg> &Ins) {
116  const MachineFunction &MF = getMachineFunction();
117  for (unsigned i = 0; i < Ins.size(); ++i) {
119 
120  // SRet arguments cannot originate from f128 or {f128} returns so we just
121  // push false. We have to handle this specially since SRet arguments
122  // aren't mapped to an original argument.
123  if (Ins[i].Flags.isSRet()) {
124  OriginalArgWasF128.push_back(false);
125  OriginalArgWasFloat.push_back(false);
126  continue;
127  }
128 
129  assert(Ins[i].getOrigArgIndex() < MF.getFunction()->arg_size());
130  std::advance(FuncArg, Ins[i].getOrigArgIndex());
131 
132  OriginalArgWasF128.push_back(
133  originalTypeIsF128(FuncArg->getType(), nullptr));
134  OriginalArgWasFloat.push_back(FuncArg->getType()->isFloatingPointTy());
135  }
136 }
void push_back(const T &Elt)
Definition: SmallVector.h:211
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
const char * getSymbol() const
size_t i
unsigned getStructNumElements() const
Definition: DerivedTypes.h:305
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.cpp:238
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
size_t arg_size() const
Definition: Function.cpp:327
struct fuzzer::@269 Flags
static void advance(T &it, size_t Val)
bool inMips16HardFloat() const
MachineFunction & getMachineFunction() const
#define F(x, y, z)
Definition: MD5.cpp:51
Type * getStructElementType(unsigned N) const
Definition: DerivedTypes.h:309
static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget)
Determine the SpecialCallingConvType for the given callee.
Definition: MipsCCState.cpp:58
bool isFloatingPointTy() const
Return true if this is one of the six floating-point types.
Definition: Type.h:160
static bool originalTypeIsF128(Type *Ty, const SDNode *CallNode)
This function returns true if Ty is fp128, {f128} or i128 which was originally a fp128.
Definition: MipsCCState.cpp:41
static bool isF128SoftLibCall(const char *CallSym)
This function returns true if CallSym is a long double emulation routine.
Definition: MipsCCState.cpp:17
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:550
bool isFP128Ty() const
Return true if this is 'fp128'.
Definition: Type.h:154
This structure contains all information that is necessary for lowering calls.
Iterator for intrusive lists based on ilist_node.
Module.h This file contains the declarations for the Module class.
const DataFlowGraph & G
Definition: RDFGraph.cpp:206
Represents one node in the SelectionDAG.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:195
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:207
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:226
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47