From 1a2265bc01b4d9bd53a79a5304993af2718e5663 Mon Sep 17 00:00:00 2001 From: Reed Kotler Date: Thu, 16 May 2013 02:17:42 +0000 Subject: 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 --- lib/Target/Mips/Mips16HardFloat.cpp | 46 ++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'lib/Target/Mips/Mips16HardFloat.cpp') diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp index cc7324f26e..45dd5d7957 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; } -- cgit v1.2.3