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;
 
 
   57char Mips16HardFloat::ID = 0;
 
   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();
 
 
  176  Type* RetType = FT.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());
 
  264  std::string 
SectionName = 
".mips16.call.fp." + Name;
 
  265  std::string StubName = 
"__call_stub_fp_" + Name;
 
  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        Value *RVal = RI->getReturnValue();
 
  396        static const char *
const Helper[
NoFPRet] = {
 
  397          "__mips16_ret_sf", 
"__mips16_ret_df", 
"__mips16_ret_sc",
 
  400        const char *Name = Helper[RV];
 
  402        Value *Params[] = {RVal};
 
  410        A = 
A.addFnAttribute(
C, 
"__Mips16RetHelper");
 
  411        A = 
A.addFnAttribute(
 
  413        A = 
A.addFnAttribute(
C, Attribute::NoInline);
 
  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;
 
  451  std::string 
LocalName = 
"$$__fn_local_" + 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";
 
  474  AsmText += 
LocalName + 
" = " + Name + 
"\n";
 
 
  483  F.removeFnAttr(
"use-soft-float");
 
  484  if (
F.hasFnAttribute(
"use-soft-float")) {
 
  487  F.addFnAttr(
"use-soft-float", 
"false");
 
 
  506bool Mips16HardFloat::runOnModule(
Module &M) {
 
  507  auto &
TM = 
static_cast<const MipsTargetMachine &
>(
 
  508      getAnalysis<TargetPassConfig>().getTM<TargetMachine>());
 
  511  for (Module::iterator 
F = 
M.begin(), 
E = 
M.end(); 
F != 
E; ++
F) {
 
  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 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.
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)
const Type::TypeID FloatTyID
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
static void removeUseSoftFloat(Function &F)
static const char *const IntrinsicInline[]
static bool isIntrinsicInline(Function *F)
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
static FPReturnVariant whichFPReturnVariant(Type *T)
const Type::TypeID DoubleTyID
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)
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()
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.
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<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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
ModulePass * createMips16HardFloatPass()