LLVM: lib/Target/Mips/Mips16HardFloat.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
20#include
21
22using namespace llvm;
23
24#define DEBUG_TYPE "mips16-hard-float"
25
26namespace {
27
28 class Mips16HardFloat : public ModulePass {
29 public:
30 static char ID;
31
33
34 StringRef getPassName() const override { return "MIPS16 Hard Float Pass"; }
35
36 void getAnalysisUsage(AnalysisUsage &AU) const override {
39 }
40
41 bool runOnModule(Module &M) override;
42 };
43
44}
45
47 std::vector<Type *> AsmArgTypes;
48 std::vector<Value *> AsmArgs;
49
55}
56
57char Mips16HardFloat::ID = 0;
58
59
60
61
62
66
67
68
69
71 switch (T->getTypeID()) {
78 if (ST->getNumElements() != 2)
79 break;
80 if ((ST->getElementType(0)->isFloatTy()) &&
81 (ST->getElementType(1)->isFloatTy()))
83 if ((ST->getElementType(0)->isDoubleTy()) &&
84 (ST->getElementType(1)->isDoubleTy()))
86 break;
87 }
88 default:
89 break;
90 }
92}
93
94
95
100
101
105
107 switch (F.arg_size()) {
108 case 0:
110 case 1:{
111 TypeID ArgTypeID = F.getFunctionType()->getParamType(0)->getTypeID();
112 switch (ArgTypeID) {
117 default:
119 }
120 }
121 default: {
122 TypeID ArgTypeID0 = F.getFunctionType()->getParamType(0)->getTypeID();
123 TypeID ArgTypeID1 = F.getFunctionType()->getParamType(1)->getTypeID();
124 switch(ArgTypeID0) {
126 switch (ArgTypeID1) {
131 default:
133 }
134 }
136 switch (ArgTypeID1) {
141 default:
143 }
144 }
145 default:
147 }
148 }
149 }
151}
152
153
154
155
157 if (F.arg_size() >=1) {
158 Type *ArgType = F.getFunctionType()->getParamType(0);
162 return true;
163 default:
164 break;
165 }
166 }
167 return false;
168}
169
171 Type* RetType = F.getReturnType();
173}
174
176 Type* RetType = FT.getReturnType();
178}
179
183
184
185
187 bool ToFP) {
188 std::string MI = ToFP ? "mtc1 ": "mfc1 ";
189 std::string AsmText;
190
191 switch (PV) {
193 AsmText += MI + "$$4, f12\n";
194 break;
195
197 AsmText += MI + "$$4, f12\n";
198 AsmText += MI + "$$5, f14\n";
199 break;
200
202 AsmText += MI + "$$4, f12\n";
203 if (LE) {
204 AsmText += MI + "$$6, f14\n";
205 AsmText += MI + "$$7, f15\n";
206 } else {
207 AsmText += MI + "$$7, f14\n";
208 AsmText += MI + "$$6, f15\n";
209 }
210 break;
211
213 if (LE) {
214 AsmText += MI + "$$4, f12\n";
215 AsmText += MI + "$$5, f13\n";
216 } else {
217 AsmText += MI + "$$5, f12\n";
218 AsmText += MI + "$$4, f13\n";
219 }
220 break;
221
223 if (LE) {
224 AsmText += MI + "$$4, f12\n";
225 AsmText += MI + "$$5, f13\n";
226 AsmText += MI + "$$6, f14\n";
227 AsmText += MI + "$$7, f15\n";
228 } else {
229 AsmText += MI + "$$5, f12\n";
230 AsmText += MI + "$$4, f13\n";
231 AsmText += MI + "$$7, f14\n";
232 AsmText += MI + "$$6, f15\n";
233 }
234 break;
235
237 if (LE) {
238 AsmText += MI + "$$4, f12\n";
239 AsmText += MI + "$$5, f13\n";
240 } else {
241 AsmText += MI + "$$5, f12\n";
242 AsmText += MI + "$$4, f13\n";
243 }
244 AsmText += MI + "$$6, f14\n";
245 break;
246
248 break;
249 }
250
251 return AsmText;
252}
253
254
255
258
260 return;
263 std::string Name(F.getName());
264 std::string SectionName = ".mips16.call.fp." + Name;
265 std::string StubName = "__call_stub_fp_" + Name;
266
267
268
273 FStub->addFnAttr("mips16_fp_stub");
274 FStub->addFnAttr(Attribute::Naked);
275 FStub->addFnAttr(Attribute::NoInline);
276 FStub->addFnAttr(Attribute::NoUnwind);
282
283 std::string AsmText;
284 AsmText += ".set reorder\n";
287 AsmText += "move 18, 31\n";
288 AsmText += "jal " + Name + "\n";
289 } else {
290 AsmText += "lui 25, %hi(" + Name + ")\n";
291 AsmText += "addiu 25, 25, %lo(" + Name + ")\n";
292 }
293
294 switch (RV) {
296 AsmText += "mfc1 2, f0\n";
297 break;
298
300 if (LE) {
301 AsmText += "mfc1 2, f0\n";
302 AsmText += "mfc1 3, f1\n";
303 } else {
304 AsmText += "mfc1 3, f0\n";
305 AsmText += "mfc1 2, f1\n";
306 }
307 break;
308
310 if (LE) {
311 AsmText += "mfc1 2, f0\n";
312 AsmText += "mfc1 3, f2\n";
313 } else {
314 AsmText += "mfc1 3, f0\n";
315 AsmText += "mfc1 3, f2\n";
316 }
317 break;
318
320 if (LE) {
321 AsmText += "mfc1 4, f2\n";
322 AsmText += "mfc1 5, f3\n";
323 AsmText += "mfc1 2, f0\n";
324 AsmText += "mfc1 3, f1\n";
325
326 } else {
327 AsmText += "mfc1 5, f2\n";
328 AsmText += "mfc1 4, f3\n";
329 AsmText += "mfc1 3, f0\n";
330 AsmText += "mfc1 2, f1\n";
331 }
332 break;
333
335 break;
336 }
337
339 AsmText += "jr 18\n";
340 else
341 AsmText += "jr 25\n";
343
345}
346
347
349 "fabs", "fabsf",
350 "llvm.ceil.f32", "llvm.ceil.f64",
351 "llvm.copysign.f32", "llvm.copysign.f64",
352 "llvm.cos.f32", "llvm.cos.f64",
353 "llvm.exp.f32", "llvm.exp.f64",
354 "llvm.exp2.f32", "llvm.exp2.f64",
355 "llvm.fabs.f32", "llvm.fabs.f64",
356 "llvm.floor.f32", "llvm.floor.f64",
357 "llvm.fma.f32", "llvm.fma.f64",
358 "llvm.log.f32", "llvm.log.f64",
359 "llvm.log10.f32", "llvm.log10.f64",
360 "llvm.nearbyint.f32", "llvm.nearbyint.f64",
361 "llvm.pow.f32", "llvm.pow.f64",
362 "llvm.powi.f32.i32", "llvm.powi.f64.i32",
363 "llvm.rint.f32", "llvm.rint.f64",
364 "llvm.round.f32", "llvm.round.f64",
365 "llvm.sin.f32", "llvm.sin.f64",
366 "llvm.sqrt.f32", "llvm.sqrt.f64",
367 "llvm.trunc.f32", "llvm.trunc.f64",
368};
369
373
374
375
381 for (auto &BB: F)
382 for (auto &I: BB) {
384 Value *RVal = RI->getReturnValue();
385 if (!RVal) continue;
386
387
388
389
390
391
392
395 if (RV == NoFPRet) continue;
396 static const char *const Helper[NoFPRet] = {
397 "__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc",
398 "__mips16_ret_dc"
399 };
400 const char *Name = Helper[RV];
401 AttributeList A;
402 Value *Params[] = {RVal};
404
405
406
407
408
409
410 A = A.addFnAttribute(C, "__Mips16RetHelper");
413 A = A.addFnAttribute(C, Attribute::NoInline);
418 Function *F_ = CI->getCalledFunction();
422 F.addFnAttr("saveS2");
423 }
425
426
429 F.addFnAttr("saveS2");
430 }
435 }
436 }
437 }
438 }
439 }
441}
442
448 std::string Name(F->getName());
449 std::string SectionName = ".mips16.fn." + Name;
450 std::string StubName = "__fn_stub_" + Name;
451 std::string LocalName = "$$__fn_local_" + Name;
453 (F->getFunctionType(),
455 FStub->addFnAttr("mips16_fp_stub");
456 FStub->addFnAttr(Attribute::Naked);
457 FStub->addFnAttr(Attribute::NoUnwind);
458 FStub->addFnAttr(Attribute::NoInline);
462
463 std::string AsmText;
464 if (PicMode) {
465 AsmText += ".set noreorder\n";
466 AsmText += ".cpload 25\n";
467 AsmText += ".set reorder\n";
468 AsmText += ".reloc 0, R_MIPS_NONE, " + Name + "\n";
469 AsmText += "la 25, " + LocalName + "\n";
470 } else
471 AsmText += "la 25, " + Name + "\n";
473 AsmText += "jr 25\n";
474 AsmText += LocalName + " = " + Name + "\n";
476
478}
479
480
483 F.removeFnAttr("use-soft-float");
484 if (F.hasFnAttribute("use-soft-float")) {
486 }
487 F.addFnAttr("use-soft-float", "false");
488}
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506bool Mips16HardFloat::runOnModule(Module &M) {
507 auto &TM = static_cast<const MipsTargetMachine &>(
508 getAnalysis().getTM());
509 LLVM_DEBUG(errs() << "Run on Module Mips16HardFloat\n");
511 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
512 if (F->hasFnAttribute("nomips16") &&
513 F->hasFnAttribute("use-soft-float")) {
515 continue;
516 }
517 if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") ||
518 F->hasFnAttribute("nomips16")) continue;
521 if (V != NoSig) {
524 }
525 }
527}
528
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Module.h This file contains the declarations for the Module class.
FPReturnVariant
Definition Mips16HardFloat.cpp:63
@ CDRet
Definition Mips16HardFloat.cpp:64
@ NoFPRet
Definition Mips16HardFloat.cpp:64
@ DRet
Definition Mips16HardFloat.cpp:64
@ CFRet
Definition Mips16HardFloat.cpp:64
@ FRet
Definition Mips16HardFloat.cpp:64
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM)
Definition Mips16HardFloat.cpp:376
static bool needsFPStubFromParams(Function &F)
Definition Mips16HardFloat.cpp:156
static bool needsFPReturnHelper(Function &F)
Definition Mips16HardFloat.cpp:170
static bool needsFPHelperFromSig(Function &F)
Definition Mips16HardFloat.cpp:180
const Type::TypeID FloatTyID
Definition Mips16HardFloat.cpp:103
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
Definition Mips16HardFloat.cpp:443
FPParamVariant
Definition Mips16HardFloat.cpp:96
@ DDSig
Definition Mips16HardFloat.cpp:98
@ DFSig
Definition Mips16HardFloat.cpp:98
@ FDSig
Definition Mips16HardFloat.cpp:97
@ NoSig
Definition Mips16HardFloat.cpp:98
@ FFSig
Definition Mips16HardFloat.cpp:97
@ DSig
Definition Mips16HardFloat.cpp:98
@ FSig
Definition Mips16HardFloat.cpp:97
Type::TypeID TypeID
Definition Mips16HardFloat.cpp:102
static void removeUseSoftFloat(Function &F)
Definition Mips16HardFloat.cpp:481
static const char *const IntrinsicInline[]
Definition Mips16HardFloat.cpp:348
static bool isIntrinsicInline(Function *F)
Definition Mips16HardFloat.cpp:370
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
Definition Mips16HardFloat.cpp:46
static FPReturnVariant whichFPReturnVariant(Type *T)
Definition Mips16HardFloat.cpp:70
const Type::TypeID DoubleTyID
Definition Mips16HardFloat.cpp:104
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP)
Definition Mips16HardFloat.cpp:186
static FPParamVariant whichFPParamVariantNeeded(Function &F)
Definition Mips16HardFloat.cpp:106
static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM)
Definition Mips16HardFloat.cpp:256
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const Function & getFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
@ InternalLinkage
Rename collisions when linking (static functions).
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
This is an important class for using LLVM in a threaded context.
static MemoryEffectsBase none()
bool isLittleEndian() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Return a value (possibly void), from a function.
StringRef - Represent a constant reference to a string, i.e.
Class to represent struct types.
bool isPositionIndependent() const
Target-Independent Code Generator Pass Configuration Options.
The instances of the Type class are immutable: once they are created, they are never changed.
TypeID
Definitions of all of the base types for the Type system.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
TypeID getTypeID() const
Return the type id for the type.
This function has undefined behavior.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto binary_search(R &&Range, T &&Value)
Provide wrappers to std::binary_search which take ranges instead of having to pass begin/end explicit...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
ModulePass * createMips16HardFloatPass()
Definition Mips16HardFloat.cpp:529