aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorReed Kotler <rkotler@mips.com>2013-05-16 02:17:42 +0000
committerReed Kotler <rkotler@mips.com>2013-05-16 02:17:42 +0000
commit1a2265bc01b4d9bd53a79a5304993af2718e5663 (patch)
tree7eed7f59bc3a00d10eb3b0b5343f047b361acfd4 /lib/Target
parent40df0d7a462c0febccc93f90dee105a0797f8ac6 (diff)
downloadexternal_llvm-1a2265bc01b4d9bd53a79a5304993af2718e5663.zip
external_llvm-1a2265bc01b4d9bd53a79a5304993af2718e5663.tar.gz
external_llvm-1a2265bc01b4d9bd53a79a5304993af2718e5663.tar.bz2
Patch number 2 for mips16/32 floating point interoperability stubs.
This creates stubs that help Mips32 functions call Mips16 functions which have floating point parameters that are normally passed in floating point registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181972 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/Mips/Mips16HardFloat.cpp46
1 files changed, 43 insertions, 3 deletions
diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp
index cc7324f..45dd5d7 100644
--- a/lib/Target/Mips/Mips16HardFloat.cpp
+++ b/lib/Target/Mips/Mips16HardFloat.cpp
@@ -320,7 +320,7 @@ static void assureFPCallStub(Function &F, Module *M,
//
// Returns of float, double and complex need to be handled with a helper
-// function. The "AndCal" part is coming in a later patch.
+// function.
//
static bool fixupFPReturnAndCall
(Function &F, Module *M, const MipsSubtarget &Subtarget) {
@@ -378,6 +378,41 @@ static bool fixupFPReturnAndCall
return Modified;
}
+static void createFPFnStub(Function *F, Module *M, FPParamVariant PV,
+ const MipsSubtarget &Subtarget ) {
+ bool PicMode = Subtarget.getRelocationModel() == Reloc::PIC_;
+ bool LE = Subtarget.isLittle();
+ LLVMContext &Context = M->getContext();
+ std::string Name = F->getName();
+ std::string SectionName = ".mips16.fn." + Name;
+ std::string StubName = "__fn_stub_" + Name;
+ std::string LocalName = "__fn_local_" + Name;
+ Function *FStub = Function::Create
+ (F->getFunctionType(),
+ Function::ExternalLinkage, StubName, M);
+ FStub->addFnAttr("mips16_fp_stub");
+ FStub->addFnAttr(llvm::Attribute::Naked);
+ FStub->addFnAttr(llvm::Attribute::NoUnwind);
+ FStub->addFnAttr("nomips16");
+ FStub->setSection(SectionName);
+ BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
+ InlineAsmHelper IAH(Context, BB);
+ IAH.Out(" .set macro");
+ if (PicMode) {
+ IAH.Out(".set noreorder");
+ IAH.Out(".cpload $$2");
+ IAH.Out(".set reorder");
+ IAH.Out(".reloc 0,R_MIPS_NONE," + Name);
+ IAH.Out("la $$25," + LocalName);
+ }
+ else
+ IAH.Out("la $$25, " + Name);
+ swapFPIntParams(PV, M, IAH, LE, false);
+ IAH.Out("jr $$25");
+ IAH.Out(LocalName + " = " + Name);
+ new UnreachableInst(FStub->getContext(), BB);
+}
+
namespace llvm {
//
@@ -389,10 +424,10 @@ namespace llvm {
// by calling a helper function before the actual return.
// 2) generate helper functions (stubs) that can be called by mips32 functions
// that will move parameters passed normally passed in floating point
-// registers the soft float equivalents. (Coming in a later patch).
+// registers the soft float equivalents.
// 3) in the case of static relocation, generate helper functions so that
// mips16 functions can call extern functions of unknown type (mips16 or
-// mips32). (Coming in a later patch).
+// mips32).
// 4) TBD. For pic, calls to extern functions of unknown type are handled by
// predefined helper functions in libc but this work is currently done
// during call lowering but it should be moved here in the future.
@@ -404,6 +439,11 @@ bool Mips16HardFloat::runOnModule(Module &M) {
if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") ||
F->hasFnAttribute("nomips16")) continue;
Modified |= fixupFPReturnAndCall(*F, &M, Subtarget);
+ FPParamVariant V = whichFPParamVariantNeeded(*F);
+ if (V != NoSig) {
+ Modified = true;
+ createFPFnStub(F, &M, V, Subtarget);
+ }
}
return Modified;
}