//
//===----------------------------------------------------------------------===//
-#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;
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);
}
// 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;
//
static const char *IntrinsicInline[] =
{"fabs",
+ "fabsf",
"llvm.ceil.f32", "llvm.ceil.f64",
"llvm.copysign.f32", "llvm.copysign.f64",
"llvm.cos.f32", "llvm.cos.f64",
};
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
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;
+ }
}
}
}
// 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