diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/Mips16HardFloat.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/Mips16HardFloat.cpp | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/contrib/llvm/lib/Target/Mips/Mips16HardFloat.cpp b/contrib/llvm/lib/Target/Mips/Mips16HardFloat.cpp index 81bf18cd09d9..14055d608e11 100644 --- a/contrib/llvm/lib/Target/Mips/Mips16HardFloat.cpp +++ b/contrib/llvm/lib/Target/Mips/Mips16HardFloat.cpp @@ -11,14 +11,16 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "mips16-hard-float" #include "Mips16HardFloat.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Value.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <string> +#define DEBUG_TYPE "mips16-hard-float" + static void inlineAsmOut (LLVMContext &C, StringRef AsmString, BasicBlock *BB ) { std::vector<llvm::Type *> AsmArgTypes; @@ -167,6 +169,11 @@ static bool needsFPReturnHelper(Function &F) { return whichFPReturnVariant(RetType) != NoFPRet; } +static bool needsFPReturnHelper(const FunctionType &FT) { + Type* RetType = FT.getReturnType(); + return whichFPReturnVariant(RetType) != NoFPRet; +} + static bool needsFPHelperFromSig(Function &F) { return needsFPStubFromParams(F) || needsFPReturnHelper(F); } @@ -239,8 +246,8 @@ static void swapFPIntParams // Make sure that we know we already need a stub for this function. // Having called needsFPHelperFromSig // -static void assureFPCallStub(Function &F, Module *M, - const MipsSubtarget &Subtarget){ +static void assureFPCallStub(Function &F, Module *M, + const MipsSubtarget &Subtarget) { // for now we only need them for static relocation if (Subtarget.getRelocationModel() == Reloc::PIC_) return; @@ -348,9 +355,8 @@ static const char *IntrinsicInline[] = }; static bool isIntrinsicInline(Function *F) { - return std::binary_search( - IntrinsicInline, array_endof(IntrinsicInline), - F->getName()); + return std::binary_search(std::begin(IntrinsicInline), + std::end(IntrinsicInline), F->getName()); } // // Returns of float, double and complex need to be handled with a helper @@ -400,13 +406,31 @@ static bool fixupFPReturnAndCall Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, NULL)); CallInst::Create(F, Params, "", &Inst ); } else if (const CallInst *CI = dyn_cast<CallInst>(I)) { + const Value* V = CI->getCalledValue(); + const Type* T = nullptr; + if (V) T = V->getType(); + const PointerType *PFT=nullptr; + if (T) PFT = dyn_cast<PointerType>(T); + const FunctionType *FT=nullptr; + if (PFT) FT = dyn_cast<FunctionType>(PFT->getElementType()); + Function *F_ = CI->getCalledFunction(); + if (FT && needsFPReturnHelper(*FT) && + !(F_ && isIntrinsicInline(F_))) { + Modified=true; + F.addFnAttr("saveS2"); + } + if (F_ && !isIntrinsicInline(F_)) { // pic mode calls are handled by already defined // helper functions - if (Subtarget.getRelocationModel() != Reloc::PIC_ ) { - Function *F_ = CI->getCalledFunction(); - if (F_ && !isIntrinsicInline(F_) && needsFPHelperFromSig(*F_)) { - assureFPCallStub(*F_, M, Subtarget); + if (needsFPReturnHelper(*F_)) { Modified=true; + F.addFnAttr("saveS2"); + } + if (Subtarget.getRelocationModel() != Reloc::PIC_ ) { + if (needsFPHelperFromSig(*F_)) { + assureFPCallStub(*F_, M, Subtarget); + Modified=true; + } } } } @@ -476,8 +500,9 @@ namespace llvm { // declared via attributes as nomips16, we must: // 1) fixup all returns of float, double, single and double complex // 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 +// 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. // 3) in the case of static relocation, generate helper functions so that // mips16 functions can call extern functions of unknown type (mips16 or |