25 #define DEBUG_TYPE "mips16-hard-float" 35 StringRef getPassName()
const override {
return "MIPS16 Hard Float Pass"; }
42 bool runOnModule(
Module &M)
override;
48 std::vector<Type *> AsmArgTypes;
49 std::vector<Value *> AsmArgs;
127 switch (ArgTypeID1) {
137 switch (ArgTypeID1) {
189 std::string
MI = ToFP ?
"mtc1 ":
"mfc1 ";
194 AsmText += MI +
"$$4, $$f12\n";
198 AsmText += MI +
"$$4, $$f12\n";
199 AsmText += MI +
"$$5, $$f14\n";
203 AsmText += MI +
"$$4, $$f12\n";
205 AsmText += MI +
"$$6, $$f14\n";
206 AsmText += MI +
"$$7, $$f15\n";
208 AsmText += MI +
"$$7, $$f14\n";
209 AsmText += MI +
"$$6, $$f15\n";
215 AsmText += MI +
"$$4, $$f12\n";
216 AsmText += MI +
"$$5, $$f13\n";
218 AsmText += MI +
"$$5, $$f12\n";
219 AsmText += MI +
"$$4, $$f13\n";
225 AsmText += MI +
"$$4, $$f12\n";
226 AsmText += MI +
"$$5, $$f13\n";
227 AsmText += MI +
"$$6, $$f14\n";
228 AsmText += MI +
"$$7, $$f15\n";
230 AsmText += MI +
"$$5, $$f12\n";
231 AsmText += MI +
"$$4, $$f13\n";
232 AsmText += MI +
"$$7, $$f14\n";
233 AsmText += MI +
"$$6, $$f15\n";
239 AsmText += MI +
"$$4, $$f12\n";
240 AsmText += MI +
"$$5, $$f13\n";
242 AsmText += MI +
"$$5, $$f12\n";
243 AsmText += MI +
"$$4, $$f13\n";
245 AsmText += MI +
"$$6, $$f14\n";
266 std::string StubName =
"__call_stub_fp_" +
Name;
285 AsmText +=
".set reorder\n";
288 AsmText +=
"move $$18, $$31\n";
289 AsmText +=
"jal " + Name +
"\n";
291 AsmText +=
"lui $$25, %hi(" + Name +
")\n";
292 AsmText +=
"addiu $$25, $$25, %lo(" + Name +
")\n";
297 AsmText +=
"mfc1 $$2, $$f0\n";
302 AsmText +=
"mfc1 $$2, $$f0\n";
303 AsmText +=
"mfc1 $$3, $$f1\n";
305 AsmText +=
"mfc1 $$3, $$f0\n";
306 AsmText +=
"mfc1 $$2, $$f1\n";
312 AsmText +=
"mfc1 $$2, $$f0\n";
313 AsmText +=
"mfc1 $$3, $$f2\n";
315 AsmText +=
"mfc1 $$3, $$f0\n";
316 AsmText +=
"mfc1 $$3, $$f2\n";
322 AsmText +=
"mfc1 $$4, $$f2\n";
323 AsmText +=
"mfc1 $$5, $$f3\n";
324 AsmText +=
"mfc1 $$2, $$f0\n";
325 AsmText +=
"mfc1 $$3, $$f1\n";
328 AsmText +=
"mfc1 $$5, $$f2\n";
329 AsmText +=
"mfc1 $$4, $$f3\n";
330 AsmText +=
"mfc1 $$3, $$f0\n";
331 AsmText +=
"mfc1 $$2, $$f1\n";
340 AsmText +=
"jr $$18\n";
342 AsmText +=
"jr $$25\n";
351 "llvm.ceil.f32",
"llvm.ceil.f64",
352 "llvm.copysign.f32",
"llvm.copysign.f64",
353 "llvm.cos.f32",
"llvm.cos.f64",
354 "llvm.exp.f32",
"llvm.exp.f64",
355 "llvm.exp2.f32",
"llvm.exp2.f64",
356 "llvm.fabs.f32",
"llvm.fabs.f64",
357 "llvm.floor.f32",
"llvm.floor.f64",
358 "llvm.fma.f32",
"llvm.fma.f64",
359 "llvm.log.f32",
"llvm.log.f64",
360 "llvm.log10.f32",
"llvm.log10.f64",
361 "llvm.nearbyint.f32",
"llvm.nearbyint.f64",
362 "llvm.pow.f32",
"llvm.pow.f64",
363 "llvm.powi.f32",
"llvm.powi.f64",
364 "llvm.rint.f32",
"llvm.rint.f64",
365 "llvm.round.f32",
"llvm.round.f64",
366 "llvm.sin.f32",
"llvm.sin.f64",
367 "llvm.sqrt.f32",
"llvm.sqrt.f64",
368 "llvm.trunc.f32",
"llvm.trunc.f64",
372 return std::binary_search(
std::begin(IntrinsicInline),
385 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(&
I)) {
386 Value *RVal = RI->getReturnValue();
398 static const char *
const Helper[
NoFPRet] = {
399 "__mips16_ret_sf",
"__mips16_ret_df",
"__mips16_ret_sc",
402 const char *
Name = Helper[RV];
404 Value *Params[] = {RVal};
413 "__Mips16RetHelper");
420 }
else if (
const CallInst *CI = dyn_cast<CallInst>(&
I)) {
422 Function *F_ = CI->getCalledFunction();
426 F.addFnAttr(
"saveS2");
433 F.addFnAttr(
"saveS2");
454 std::string StubName =
"__fn_stub_" +
Name;
455 std::string LocalName =
"$$__fn_local_" +
Name;
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";
512 bool Mips16HardFloat::runOnModule(
Module &M) {
514 getAnalysis<TargetPassConfig>().getTM<TargetMachine>());
518 if (
F->hasFnAttribute(
"nomips16") &&
519 F->hasFnAttribute(
"use-soft-float")) {
523 if (
F->isDeclaration() ||
F->hasFnAttribute(
"mips16_fp_stub") ||
524 F->hasFnAttribute(
"nomips16"))
continue;
Return a value (possibly void), from a function.
const_iterator end(StringRef path)
Get end iterator over path.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
This class represents lattice values for constants.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getElementType(unsigned N) const
static bool needsFPReturnHelper(Function &F)
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
A Module instance is used to store all the information related to an LLVM module. ...
2: 32-bit floating point type
static void removeUseSoftFloat(Function &F)
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
unsigned getNumElements() const
Random access to the elements.
This class represents a function call, abstracting a target machine's calling convention.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
AnalysisUsage & addRequired()
amdgpu Simplify well known AMD library false Value Value const Twine & Name
TypeID getTypeID() const
Return the type id for the type.
Class to represent struct types.
LLVMContext & getContext() const
Get the global data context.
static bool needsFPHelperFromSig(Function &F)
TypeID
Definitions of all of the base types for the Type system.
Target-Independent Code Generator Pass Configuration Options.
static bool needsFPStubFromParams(Function &F)
static FPReturnVariant whichFPReturnVariant(Type *T)
Class to represent function types.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Type * getType() const
All values are typed, get the type of this value.
const Type::TypeID FloatTyID
static bool isIntrinsicInline(Function *F)
static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Type * getReturnType() const
Returns the type of the ret val.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM Basic Block Representation.
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM)
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This function has undefined behavior.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
static void EmitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
ModulePass * createMips16HardFloatPass()
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
bool isLittleEndian() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Iterator for intrusive lists based on ilist_node.
Module.h This file contains the declarations for the Module class.
Type * getReturnType() const
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
void removeAttributes(unsigned i, const AttrBuilder &Attrs)
removes the attributes from the list of attributes.
LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Add an attribute to the attribute set at the given index.
static FPParamVariant whichFPParamVariantNeeded(Function &F)
static const char *const IntrinsicInline[]
bool isPositionIndependent() const
StringRef getName() const
Return a constant reference to the value's name.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Rename collisions when linking (static functions).
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
3: 64-bit floating point type
void addAttributes(unsigned i, const AttrBuilder &Attrs)
adds the attributes to the list of attributes.
const Type::TypeID DoubleTyID
LLVM Value Representation.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
StringRef - Represent a constant reference to a string, i.e.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
void setSection(StringRef S)
Change the section for this global.
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP)