Go to the documentation of this file.
24 #define DEBUG_TYPE "mips16-hard-float"
34 StringRef getPassName()
const override {
return "MIPS16 Hard Float Pass"; }
41 bool runOnModule(
Module &
M)
override;
47 std::vector<Type *> AsmArgTypes;
48 std::vector<Value *> AsmArgs;
71 switch (
T->getTypeID()) {
78 if (
ST->getNumElements() != 2)
80 if ((
ST->getElementType(0)->isFloatTy()) &&
81 (
ST->getElementType(1)->isFloatTy()))
83 if ((
ST->getElementType(0)->isDoubleTy()) &&
84 (
ST->getElementType(1)->isDoubleTy()))
107 switch (
F.arg_size()) {
111 TypeID ArgTypeID =
F.getFunctionType()->getParamType(0)->getTypeID();
122 TypeID ArgTypeID0 =
F.getFunctionType()->getParamType(0)->getTypeID();
123 TypeID ArgTypeID1 =
F.getFunctionType()->getParamType(1)->getTypeID();
126 switch (ArgTypeID1) {
136 switch (ArgTypeID1) {
157 if (
F.arg_size() >=1) {
158 Type *ArgType =
F.getFunctionType()->getParamType(0);
171 Type* RetType =
F.getReturnType();
188 std::string
MI = ToFP ?
"mtc1 ":
"mfc1 ";
193 AsmText +=
MI +
"$$4, $$f12\n";
197 AsmText +=
MI +
"$$4, $$f12\n";
198 AsmText +=
MI +
"$$5, $$f14\n";
202 AsmText +=
MI +
"$$4, $$f12\n";
204 AsmText +=
MI +
"$$6, $$f14\n";
205 AsmText +=
MI +
"$$7, $$f15\n";
207 AsmText +=
MI +
"$$7, $$f14\n";
208 AsmText +=
MI +
"$$6, $$f15\n";
214 AsmText +=
MI +
"$$4, $$f12\n";
215 AsmText +=
MI +
"$$5, $$f13\n";
217 AsmText +=
MI +
"$$5, $$f12\n";
218 AsmText +=
MI +
"$$4, $$f13\n";
224 AsmText +=
MI +
"$$4, $$f12\n";
225 AsmText +=
MI +
"$$5, $$f13\n";
226 AsmText +=
MI +
"$$6, $$f14\n";
227 AsmText +=
MI +
"$$7, $$f15\n";
229 AsmText +=
MI +
"$$5, $$f12\n";
230 AsmText +=
MI +
"$$4, $$f13\n";
231 AsmText +=
MI +
"$$7, $$f14\n";
232 AsmText +=
MI +
"$$6, $$f15\n";
238 AsmText +=
MI +
"$$4, $$f12\n";
239 AsmText +=
MI +
"$$5, $$f13\n";
241 AsmText +=
MI +
"$$5, $$f12\n";
242 AsmText +=
MI +
"$$4, $$f13\n";
244 AsmText +=
MI +
"$$6, $$f14\n";
259 if (
TM.isPositionIndependent())
262 bool LE =
TM.isLittleEndian();
263 std::string
Name(
F.getName());
265 std::string StubName =
"__call_stub_fp_" +
Name;
269 Function *FStub =
M->getFunction(StubName);
284 AsmText +=
".set reorder\n";
287 AsmText +=
"move $$18, $$31\n";
288 AsmText +=
"jal " +
Name +
"\n";
290 AsmText +=
"lui $$25, %hi(" +
Name +
")\n";
291 AsmText +=
"addiu $$25, $$25, %lo(" +
Name +
")\n";
296 AsmText +=
"mfc1 $$2, $$f0\n";
301 AsmText +=
"mfc1 $$2, $$f0\n";
302 AsmText +=
"mfc1 $$3, $$f1\n";
304 AsmText +=
"mfc1 $$3, $$f0\n";
305 AsmText +=
"mfc1 $$2, $$f1\n";
311 AsmText +=
"mfc1 $$2, $$f0\n";
312 AsmText +=
"mfc1 $$3, $$f2\n";
314 AsmText +=
"mfc1 $$3, $$f0\n";
315 AsmText +=
"mfc1 $$3, $$f2\n";
321 AsmText +=
"mfc1 $$4, $$f2\n";
322 AsmText +=
"mfc1 $$5, $$f3\n";
323 AsmText +=
"mfc1 $$2, $$f0\n";
324 AsmText +=
"mfc1 $$3, $$f1\n";
327 AsmText +=
"mfc1 $$5, $$f2\n";
328 AsmText +=
"mfc1 $$4, $$f3\n";
329 AsmText +=
"mfc1 $$3, $$f0\n";
330 AsmText +=
"mfc1 $$2, $$f1\n";
339 AsmText +=
"jr $$18\n";
341 AsmText +=
"jr $$25\n";
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",
384 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(&
I)) {
385 Value *RVal = RI->getReturnValue();
397 static const char *
const Helper[
NoFPRet] = {
398 "__mips16_ret_sf",
"__mips16_ret_df",
"__mips16_ret_sc",
401 const char *
Name = Helper[RV];
403 Value *Params[] = {RVal};
411 A = A.addFnAttribute(
C,
"__Mips16RetHelper");
412 A = A.addFnAttribute(
C, Attribute::ReadNone);
413 A = A.addFnAttribute(
C, Attribute::NoInline);
416 }
else if (
const CallInst *CI = dyn_cast<CallInst>(&
I)) {
418 Function *F_ = CI->getCalledFunction();
422 F.addFnAttr(
"saveS2");
429 F.addFnAttr(
"saveS2");
431 if (!
TM.isPositionIndependent()) {
445 bool PicMode =
TM.isPositionIndependent();
446 bool LE =
TM.isLittleEndian();
448 std::string
Name(
F->getName());
450 std::string StubName =
"__fn_stub_" +
Name;
453 (
F->getFunctionType(),
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";
471 AsmText +=
"la $$25, " +
Name +
"\n";
473 AsmText +=
"jr $$25\n";
483 F.removeFnAttr(
"use-soft-float");
484 if (
F.hasFnAttribute(
"use-soft-float")) {
487 F.addFnAttr(
"use-soft-float",
"false");
506 bool Mips16HardFloat::runOnModule(
Module &M) {
512 if (
F->hasFnAttribute(
"nomips16") &&
513 F->hasFnAttribute(
"use-soft-float")) {
517 if (
F->isDeclaration() ||
F->hasFnAttribute(
"mips16_fp_stub") ||
518 F->hasFnAttribute(
"nomips16"))
continue;
static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM)
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM)
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
This is an optimization pass for GlobalISel generic memory operations.
const Type::TypeID FloatTyID
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Return a value (possibly void), from a function.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
FunctionListType::iterator iterator
The Function iterators.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
TypeID getTypeID() const
Return the type id for the type.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
The instances of the Type class are immutable: once they are created, they are never changed.
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ModulePass * createMips16HardFloatPass()
static bool isIntrinsicInline(Function *F)
LLVM Basic Block Representation.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void setSection(StringRef S)
Change the section for this global.
(vector float) vec_cmpeq(*A, *B) C
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Represent the analysis usage information of a pass.
static FPReturnVariant whichFPReturnVariant(Type *T)
@ InternalLinkage
Rename collisions when linking (static functions).
static 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const Type::TypeID DoubleTyID
Target-Independent Code Generator Pass Configuration Options.
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
Type * getReturnType() const
Returns the type of the ret val.
This is an important class for using LLVM in a threaded context.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Primary interface to the complete machine description for the target machine.
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
static bool needsFPHelperFromSig(Function &F)
A Module instance is used to store all the information related to an LLVM module.
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
Class to represent struct types.
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Type * getType() const
All values are typed, get the type of this value.
static void removeUseSoftFloat(Function &F)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static bool needsFPStubFromParams(Function &F)
static bool needsFPReturnHelper(Function &F)
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP)
static const char *const IntrinsicInline[]
static Type * getVoidTy(LLVMContext &C)
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
const char LLVMTargetMachineRef TM
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
This function has undefined behavior.
AnalysisUsage & addRequired()
TypeID
Definitions of all of the base types for the Type system.
static FPParamVariant whichFPParamVariantNeeded(Function &F)
Type * getReturnType() const
LLVM Value Representation.
Class to represent function types.