27#define DEBUG_TYPE "mips-mips16-hard-float"
31class Mips16HardFloatLegacy :
public ModulePass {
37 StringRef getPassName()
const override {
return "MIPS16 Hard Float Pass"; }
45 bool runOnModule(
Module &M)
override;
51 std::vector<Type *> AsmArgTypes;
52 std::vector<Value *> AsmArgs;
61char Mips16HardFloatLegacy::ID = 0;
75 switch (
T->getTypeID()) {
82 if (ST->getNumElements() != 2)
84 if ((ST->getElementType(0)->isFloatTy()) &&
85 (ST->getElementType(1)->isFloatTy()))
87 if ((ST->getElementType(0)->isDoubleTy()) &&
88 (ST->getElementType(1)->isDoubleTy()))
111 switch (
F.arg_size()) {
115 TypeID ArgTypeID =
F.getFunctionType()->getParamType(0)->getTypeID();
126 TypeID ArgTypeID0 =
F.getFunctionType()->getParamType(0)->getTypeID();
127 TypeID ArgTypeID1 =
F.getFunctionType()->getParamType(1)->getTypeID();
130 switch (ArgTypeID1) {
140 switch (ArgTypeID1) {
161 if (
F.arg_size() >=1) {
162 Type *ArgType =
F.getFunctionType()->getParamType(0);
175 Type* RetType =
F.getReturnType();
180 Type* RetType = FT.getReturnType();
192 std::string
MI = ToFP ?
"mtc1 ":
"mfc1 ";
197 AsmText +=
MI +
"$$4, $$f12\n";
201 AsmText +=
MI +
"$$4, $$f12\n";
202 AsmText +=
MI +
"$$5, $$f14\n";
206 AsmText +=
MI +
"$$4, $$f12\n";
208 AsmText +=
MI +
"$$6, $$f14\n";
209 AsmText +=
MI +
"$$7, $$f15\n";
211 AsmText +=
MI +
"$$7, $$f14\n";
212 AsmText +=
MI +
"$$6, $$f15\n";
218 AsmText +=
MI +
"$$4, $$f12\n";
219 AsmText +=
MI +
"$$5, $$f13\n";
221 AsmText +=
MI +
"$$5, $$f12\n";
222 AsmText +=
MI +
"$$4, $$f13\n";
228 AsmText +=
MI +
"$$4, $$f12\n";
229 AsmText +=
MI +
"$$5, $$f13\n";
230 AsmText +=
MI +
"$$6, $$f14\n";
231 AsmText +=
MI +
"$$7, $$f15\n";
233 AsmText +=
MI +
"$$5, $$f12\n";
234 AsmText +=
MI +
"$$4, $$f13\n";
235 AsmText +=
MI +
"$$7, $$f14\n";
236 AsmText +=
MI +
"$$6, $$f15\n";
242 AsmText +=
MI +
"$$4, $$f12\n";
243 AsmText +=
MI +
"$$5, $$f13\n";
245 AsmText +=
MI +
"$$5, $$f12\n";
246 AsmText +=
MI +
"$$4, $$f13\n";
248 AsmText +=
MI +
"$$6, $$f14\n";
267 std::string Name(
F.getName());
268 std::string
SectionName =
".mips16.call.fp." + Name;
269 std::string StubName =
"__call_stub_fp_" + Name;
288 AsmText +=
".set reorder\n";
291 AsmText +=
"move $$18, $$31\n";
292 AsmText +=
"jal " + Name +
"\n";
294 AsmText +=
"lui $$25, %hi(" + Name +
")\n";
295 AsmText +=
"addiu $$25, $$25, %lo(" + Name +
")\n";
300 AsmText +=
"mfc1 $$2, $$f0\n";
305 AsmText +=
"mfc1 $$2, $$f0\n";
306 AsmText +=
"mfc1 $$3, $$f1\n";
308 AsmText +=
"mfc1 $$3, $$f0\n";
309 AsmText +=
"mfc1 $$2, $$f1\n";
315 AsmText +=
"mfc1 $$2, $$f0\n";
316 AsmText +=
"mfc1 $$3, $$f2\n";
318 AsmText +=
"mfc1 $$3, $$f0\n";
319 AsmText +=
"mfc1 $$3, $$f2\n";
325 AsmText +=
"mfc1 $$4, $$f2\n";
326 AsmText +=
"mfc1 $$5, $$f3\n";
327 AsmText +=
"mfc1 $$2, $$f0\n";
328 AsmText +=
"mfc1 $$3, $$f1\n";
331 AsmText +=
"mfc1 $$5, $$f2\n";
332 AsmText +=
"mfc1 $$4, $$f3\n";
333 AsmText +=
"mfc1 $$3, $$f0\n";
334 AsmText +=
"mfc1 $$2, $$f1\n";
343 AsmText +=
"jr $$18\n";
345 AsmText +=
"jr $$25\n";
354 "llvm.ceil.f32",
"llvm.ceil.f64",
355 "llvm.copysign.f32",
"llvm.copysign.f64",
356 "llvm.cos.f32",
"llvm.cos.f64",
357 "llvm.exp.f32",
"llvm.exp.f64",
358 "llvm.exp2.f32",
"llvm.exp2.f64",
359 "llvm.fabs.f32",
"llvm.fabs.f64",
360 "llvm.floor.f32",
"llvm.floor.f64",
361 "llvm.fma.f32",
"llvm.fma.f64",
362 "llvm.log.f32",
"llvm.log.f64",
363 "llvm.log10.f32",
"llvm.log10.f64",
364 "llvm.nearbyint.f32",
"llvm.nearbyint.f64",
365 "llvm.pow.f32",
"llvm.pow.f64",
366 "llvm.powi.f32.i32",
"llvm.powi.f64.i32",
367 "llvm.rint.f32",
"llvm.rint.f64",
368 "llvm.round.f32",
"llvm.round.f64",
369 "llvm.sin.f32",
"llvm.sin.f64",
370 "llvm.sqrt.f32",
"llvm.sqrt.f64",
371 "llvm.trunc.f32",
"llvm.trunc.f64",
388 Value *RVal = RI->getReturnValue();
400 static const char *
const Helper[
NoFPRet] = {
401 "__mips16_ret_sf",
"__mips16_ret_df",
"__mips16_ret_sc",
404 const char *Name = Helper[RV];
406 Value *Params[] = {RVal};
414 A =
A.addFnAttribute(
C,
"__Mips16RetHelper");
415 A =
A.addFnAttribute(
417 A =
A.addFnAttribute(
C, Attribute::NoInline);
422 Function *F_ = CI->getCalledFunction();
426 F.addFnAttr(
"saveS2");
433 F.addFnAttr(
"saveS2");
452 std::string Name(
F->getName());
454 std::string StubName =
"__fn_stub_" + Name;
455 std::string
LocalName =
"$$__fn_local_" + Name;
457 (
F->getFunctionType(),
469 AsmText +=
".set noreorder\n";
470 AsmText +=
".cpload $$25\n";
471 AsmText +=
".set reorder\n";
472 AsmText +=
".reloc 0, R_MIPS_NONE, " + Name +
"\n";
473 AsmText +=
"la $$25, " +
LocalName +
"\n";
475 AsmText +=
"la $$25, " + Name +
"\n";
477 AsmText +=
"jr $$25\n";
478 AsmText +=
LocalName +
" = " + Name +
"\n";
504 if (
F->isDeclaration() ||
F->hasFnAttribute(
"mips16_fp_stub") ||
518 return new Mips16HardFloatLegacy();
521bool Mips16HardFloatLegacy::runOnModule(
Module &M) {
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
This header defines various interfaces for pass management in LLVM.
@ DoubleTyID
64-bit floating point type
@ FloatTyID
32-bit floating point type
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM)
static bool needsFPStubFromParams(Function &F)
static bool needsFPReturnHelper(Function &F)
static bool needsFPHelperFromSig(Function &F)
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
static const char *const IntrinsicInline[]
static bool isIntrinsicInline(Function *F)
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
static FPReturnVariant whichFPReturnVariant(Type *T)
static bool runHardFloatOnModule(Module &M, const MipsTargetMachine &TM)
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP)
static FPParamVariant whichFPParamVariantNeeded(Function &F)
static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM)
ModuleAnalysisManager MAM
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
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.
Represents analyses that only rely on functions' control flow.
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()
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
bool inMips16HardFloat() const
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.
FunctionListType::iterator iterator
The Function iterators.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Return a value (possibly void), from a function.
Represent a constant reference to a string, i.e.
Class to represent struct types.
Primary interface to the complete machine description for the target machine.
bool isPositionIndependent() const
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
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.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - 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.
ModulePass * createMips16HardFloatLegacyPass()
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.