24 #define DEBUG_TYPE "mips16-hard-float"
33 const char *getPassName()
const override {
34 return "MIPS16 Hard Float Pass";
37 bool runOnModule(
Module &M)
override;
43 class InlineAsmHelper {
52 std::vector<llvm::Type *> AsmArgTypes;
53 std::vector<llvm::Value*> AsmArgs;
135 switch (ArgTypeID1) {
145 switch (ArgTypeID1) {
199 bool LE,
bool ToFP) {
201 std::string
MI = ToFP?
"mtc1 ":
"mfc1 ";
204 IAH.Out(MI +
"$$4,$$f12");
207 IAH.Out(MI +
"$$4,$$f12");
208 IAH.Out(MI +
"$$5,$$f14");
211 IAH.Out(MI +
"$$4,$$f12");
213 IAH.Out(MI +
"$$6,$$f14");
214 IAH.Out(MI +
"$$7,$$f15");
216 IAH.Out(MI +
"$$7,$$f14");
217 IAH.Out(MI +
"$$6,$$f15");
222 IAH.Out(MI +
"$$4,$$f12");
223 IAH.Out(MI +
"$$5,$$f13");
225 IAH.Out(MI +
"$$5,$$f12");
226 IAH.Out(MI +
"$$4,$$f13");
231 IAH.Out(MI +
"$$4,$$f12");
232 IAH.Out(MI +
"$$5,$$f13");
233 IAH.Out(MI +
"$$6,$$f14");
234 IAH.Out(MI +
"$$7,$$f15");
236 IAH.Out(MI +
"$$5,$$f12");
237 IAH.Out(MI +
"$$4,$$f13");
238 IAH.Out(MI +
"$$7,$$f14");
239 IAH.Out(MI +
"$$6,$$f15");
244 IAH.Out(MI +
"$$4,$$f12");
245 IAH.Out(MI +
"$$5,$$f13");
247 IAH.Out(MI +
"$$5,$$f12");
248 IAH.Out(MI +
"$$4,$$f13");
250 IAH.Out(MI +
"$$6,$$f14");
269 std::string SectionName =
".mips16.call.fp." +
Name;
270 std::string StubName =
"__call_stub_fp_" +
Name;
285 InlineAsmHelper IAH(Context, BB);
286 IAH.Out(
".set reorder");
291 IAH.Out(
"move $$18, $$31");
292 IAH.Out(
"jal " + Name);
294 IAH.Out(
"lui $$25,%hi(" + Name +
")");
295 IAH.Out(
"addiu $$25,$$25,%lo(" + Name +
")" );
299 IAH.Out(
"mfc1 $$2,$$f0");
303 IAH.Out(
"mfc1 $$2,$$f0");
304 IAH.Out(
"mfc1 $$3,$$f1");
306 IAH.Out(
"mfc1 $$3,$$f0");
307 IAH.Out(
"mfc1 $$2,$$f1");
312 IAH.Out(
"mfc1 $$2,$$f0");
313 IAH.Out(
"mfc1 $$3,$$f2");
315 IAH.Out(
"mfc1 $$3,$$f0");
316 IAH.Out(
"mfc1 $$3,$$f2");
321 IAH.Out(
"mfc1 $$4,$$f2");
322 IAH.Out(
"mfc1 $$5,$$f3");
323 IAH.Out(
"mfc1 $$2,$$f0");
324 IAH.Out(
"mfc1 $$3,$$f1");
327 IAH.Out(
"mfc1 $$5,$$f2");
328 IAH.Out(
"mfc1 $$4,$$f3");
329 IAH.Out(
"mfc1 $$3,$$f0");
330 IAH.Out(
"mfc1 $$2,$$f1");
348 "llvm.ceil.f32",
"llvm.ceil.f64",
349 "llvm.copysign.f32",
"llvm.copysign.f64",
350 "llvm.cos.f32",
"llvm.cos.f64",
351 "llvm.exp.f32",
"llvm.exp.f64",
352 "llvm.exp2.f32",
"llvm.exp2.f64",
353 "llvm.fabs.f32",
"llvm.fabs.f64",
354 "llvm.floor.f32",
"llvm.floor.f64",
355 "llvm.fma.f32",
"llvm.fma.f64",
356 "llvm.log.f32",
"llvm.log.f64",
357 "llvm.log10.f32",
"llvm.log10.f64",
358 "llvm.nearbyint.f32",
"llvm.nearbyint.f64",
359 "llvm.pow.f32",
"llvm.pow.f64",
360 "llvm.powi.f32",
"llvm.powi.f64",
361 "llvm.rint.f32",
"llvm.rint.f64",
362 "llvm.round.f32",
"llvm.round.f64",
363 "llvm.sin.f32",
"llvm.sin.f64",
364 "llvm.sqrt.f32",
"llvm.sqrt.f64",
365 "llvm.trunc.f32",
"llvm.trunc.f64",
378 bool Modified =
false;
385 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(
I)) {
386 Value *RVal = RI->getReturnValue();
398 static const char* 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)) {
421 const Value* V = CI->getCalledValue();
422 const Type*
T =
nullptr;
428 Function *F_ = CI->getCalledFunction();
459 std::string SectionName =
".mips16.fn." +
Name;
460 std::string StubName =
"__fn_stub_" +
Name;
461 std::string LocalName =
"$$__fn_local_" +
Name;
472 InlineAsmHelper IAH(Context, BB);
474 IAH.Out(
".set noreorder");
475 IAH.Out(
".cpload $$25");
476 IAH.Out(
".set reorder");
477 IAH.Out(
".reloc 0,R_MIPS_NONE," + Name);
478 IAH.Out(
"la $$25," + LocalName);
481 IAH.Out(
"la $$25," + Name);
485 IAH.Out(LocalName +
" = " + Name);
494 DEBUG(
errs() <<
"removing -use-soft-float\n");
496 "use-soft-float",
"false");
499 DEBUG(
errs() <<
"still has -use-soft-float\n");
523 bool Mips16HardFloat::runOnModule(
Module &M) {
524 DEBUG(
errs() <<
"Run on Module Mips16HardFloat\n");
525 bool Modified =
false;
527 if (
F->hasFnAttribute(
"nomips16") &&
528 F->hasFnAttribute(
"use-soft-float")) {
532 if (
F->isDeclaration() ||
F->hasFnAttribute(
"mips16_fp_stub") ||
533 F->hasFnAttribute(
"nomips16"))
continue;
ReturnInst - Return a value (possibly void), from a function.
const_iterator end(StringRef path)
Get end iterator over path.
static void swapFPIntParams(FPParamVariant PV, Module *M, InlineAsmHelper &IAH, bool LE, bool ToFP)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
unsigned getStructNumElements() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
static bool needsFPReturnHelper(Function &F)
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)
CallInst - This class represents a function call, abstracting a target machine's calling convention...
bool isDoubleTy() const
isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
const_iterator begin(StringRef path)
Get begin iterator over path.
Type * getReturnType() const
StringRef getName() const
Return a constant reference to the value's name.
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool needsFPHelperFromSig(Function &F)
TypeID
Definitions of all of the base types for the Type system.
Function does not access memory.
void addFnAttr(Attribute::AttrKind N)
Add function attributes to this function.
static bool needsFPStubFromParams(Function &F)
static FPReturnVariant whichFPReturnVariant(Type *T)
FunctionType - Class to represent function types.
static const char * IntrinsicInline[]
const Type::TypeID FloatTyID
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
FunctionType::get - This static method is the primary way of constructing a FunctionType.
TypeID getTypeID() const
getTypeID - Return the type id for the type.
void removeAttributes(unsigned i, AttributeSet attr)
removes the attributes from the list of attributes.
Type * getElementType() const
static bool isIntrinsicInline(Function *F)
PointerType - Class to represent pointers.
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM)
Type * getParamType(unsigned i) const
Parameter type accessors.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
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.
Type * getContainedType(unsigned i) const
getContainedType - This method is used to implement the type iterator (defined at the end of the file...
UnreachableInst - This function has undefined behavior.
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
bool isFloatTy() const
isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
static Type * getVoidTy(LLVMContext &C)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Function doesn't unwind stack.
ModulePass * createMips16HardFloatPass(MipsTargetMachine &TM)
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
bool isLittleEndian() const
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static FPParamVariant whichFPParamVariantNeeded(Function &F)
AttributeSet addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Attr) const
Add an attribute to the attribute set at the given index.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
FunctionType * getFunctionType() const
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.
3: 64-bit floating point type
Type * getReturnType() const
const Type::TypeID DoubleTyID
LLVM Value Representation.
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.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
void addAttributes(unsigned i, AttributeSet attrs)
adds the attributes to the list of attributes.
void setSection(StringRef S)
LLVMContext & getContext() const
Get the global data context.