14 #define DEBUG_TYPE "mips16-hard-float"
24 std::vector<llvm::Type *> AsmArgTypes;
25 std::vector<llvm::Value*> AsmArgs;
33 CallInst::Create(IA, AsmArgs,
"", BB);
38 class InlineAsmHelper {
69 case Type::StructTyID:
120 switch (ArgTypeID1) {
130 switch (ArgTypeID1) {
181 bool LE,
bool ToFP) {
183 std::string
MI = ToFP?
"mtc1 ":
"mfc1 ";
186 IAH.Out(MI +
"$$4,$$f12");
189 IAH.Out(MI +
"$$4,$$f12");
190 IAH.Out(MI +
"$$5,$$f14");
193 IAH.Out(MI +
"$$4,$$f12");
195 IAH.Out(MI +
"$$6,$$f14");
196 IAH.Out(MI +
"$$7,$$f15");
198 IAH.Out(MI +
"$$7,$$f14");
199 IAH.Out(MI +
"$$6,$$f15");
204 IAH.Out(MI +
"$$4,$$f12");
205 IAH.Out(MI +
"$$5,$$f13");
207 IAH.Out(MI +
"$$5,$$f12");
208 IAH.Out(MI +
"$$4,$$f13");
213 IAH.Out(MI +
"$$4,$$f12");
214 IAH.Out(MI +
"$$5,$$f13");
215 IAH.Out(MI +
"$$6,$$f14");
216 IAH.Out(MI +
"$$7,$$f15");
218 IAH.Out(MI +
"$$5,$$f12");
219 IAH.Out(MI +
"$$4,$$f13");
220 IAH.Out(MI +
"$$7,$$f14");
221 IAH.Out(MI +
"$$6,$$f15");
226 IAH.Out(MI +
"$$4,$$f12");
227 IAH.Out(MI +
"$$5,$$f13");
229 IAH.Out(MI +
"$$5,$$f12");
230 IAH.Out(MI +
"$$4,$$f13");
232 IAH.Out(MI +
"$$6,$$f14");
250 std::string SectionName =
".mips16.call.fp." +
Name;
251 std::string StubName =
"__call_stub_fp_" +
Name;
258 Function::InternalLinkage, StubName, M);
265 BasicBlock *BB = BasicBlock::Create(Context,
"entry", FStub);
266 InlineAsmHelper IAH(Context, BB);
267 IAH.Out(
".set reorder");
272 IAH.Out(
"move $$18, $$31");
273 IAH.Out(
"jal " + Name);
275 IAH.Out(
"lui $$25,%hi(" + Name +
")");
276 IAH.Out(
"addiu $$25,$$25,%lo(" + Name +
")" );
280 IAH.Out(
"mfc1 $$2,$$f0");
284 IAH.Out(
"mfc1 $$2,$$f0");
285 IAH.Out(
"mfc1 $$3,$$f1");
287 IAH.Out(
"mfc1 $$3,$$f0");
288 IAH.Out(
"mfc1 $$2,$$f1");
293 IAH.Out(
"mfc1 $$2,$$f0");
294 IAH.Out(
"mfc1 $$3,$$f2");
296 IAH.Out(
"mfc1 $$3,$$f0");
297 IAH.Out(
"mfc1 $$3,$$f2");
302 IAH.Out(
"mfc1 $$4,$$f2");
303 IAH.Out(
"mfc1 $$5,$$f3");
304 IAH.Out(
"mfc1 $$2,$$f0");
305 IAH.Out(
"mfc1 $$3,$$f1");
308 IAH.Out(
"mfc1 $$5,$$f2");
309 IAH.Out(
"mfc1 $$4,$$f3");
310 IAH.Out(
"mfc1 $$3,$$f0");
311 IAH.Out(
"mfc1 $$2,$$f1");
330 "llvm.ceil.f32",
"llvm.ceil.f64",
331 "llvm.copysign.f32",
"llvm.copysign.f64",
332 "llvm.cos.f32",
"llvm.cos.f64",
333 "llvm.exp.f32",
"llvm.exp.f64",
334 "llvm.exp2.f32",
"llvm.exp2.f64",
335 "llvm.fabs.f32",
"llvm.fabs.f64",
336 "llvm.floor.f32",
"llvm.floor.f64",
337 "llvm.fma.f32",
"llvm.fma.f64",
338 "llvm.log.f32",
"llvm.log.f64",
339 "llvm.log10.f32",
"llvm.log10.f64",
340 "llvm.nearbyint.f32",
"llvm.nearbyint.f64",
341 "llvm.pow.f32",
"llvm.pow.f64",
342 "llvm.powi.f32",
"llvm.powi.f64",
343 "llvm.rint.f32",
"llvm.rint.f64",
344 "llvm.round.f32",
"llvm.round.f64",
345 "llvm.sin.f32",
"llvm.sin.f64",
346 "llvm.sqrt.f32",
"llvm.sqrt.f64",
347 "llvm.trunc.f32",
"llvm.trunc.f64",
351 return std::binary_search(
361 bool Modified =
false;
363 Type *MyVoid = Type::getVoidTy(C);
368 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(
I)) {
369 Value *RVal = RI->getReturnValue();
381 static const char* Helper[
NoFPRet] =
382 {
"__mips16_ret_sf",
"__mips16_ret_df",
"__mips16_ret_sc",
384 const char *
Name = Helper[RV];
386 Value *Params[] = {RVal};
395 "__Mips16RetHelper");
397 Attribute::ReadNone);
399 Attribute::NoInline);
401 CallInst::Create(F, Params,
"", &Inst );
402 }
else if (
const CallInst *CI = dyn_cast<CallInst>(
I)) {
406 Function *F_ = CI->getCalledFunction();
423 std::string SectionName =
".mips16.fn." +
Name;
424 std::string StubName =
"__fn_stub_" +
Name;
425 std::string LocalName =
"$$__fn_local_" +
Name;
428 Function::InternalLinkage, StubName, M);
435 BasicBlock *BB = BasicBlock::Create(Context,
"entry", FStub);
436 InlineAsmHelper IAH(Context, BB);
437 IAH.Out(
" .set macro");
439 IAH.Out(
".set noreorder");
440 IAH.Out(
".cpload $$25");
441 IAH.Out(
".set reorder");
442 IAH.Out(
".reloc 0,R_MIPS_NONE," + Name);
443 IAH.Out(
"la $$25," + LocalName);
446 IAH.Out(
".set reorder");
447 IAH.Out(
"la $$25," + Name);
451 IAH.Out(LocalName +
" = " + Name);
460 DEBUG(
errs() <<
"removing -use-soft-float\n");
462 "use-soft-float",
"false");
465 DEBUG(
errs() <<
"still has -use-soft-float\n");
490 DEBUG(
errs() <<
"Run on Module Mips16HardFloat\n");
491 bool Modified =
false;
T * array_endof(T(&x)[N])
static void swapFPIntParams(FPParamVariant PV, Module *M, InlineAsmHelper &IAH, bool LE, bool ToFP)
LLVMContext & getContext() const
unsigned getStructNumElements() const
static bool needsFPReturnHelper(Function &F)
The main container class for the LLVM Intermediate Representation.
static void removeUseSoftFloat(Function &F)
Reloc::Model getRelocationModel() const
bool isDoubleTy() const
isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
Type * getReturnType() const
void setSection(StringRef S)
StringRef getName() const
ModulePass * createMips16HardFloat(MipsTargetMachine &TM)
#define llvm_unreachable(msg)
static bool needsFPHelperFromSig(Function &F)
void addFnAttr(Attribute::AttrKind N)
Add function attributes to this function.
static bool needsFPStubFromParams(Function &F)
static FPReturnVariant whichFPReturnVariant(Type *T)
static const char * IntrinsicInline[]
const Type::TypeID FloatTyID
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
void removeAttributes(unsigned i, AttributeSet attr)
removes the attributes from the list of attributes.
static bool isIntrinsicInline(Function *F)
Function * getFunction(StringRef Name) const
Type * getParamType(unsigned i) const
Parameter type accessors.
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("MIPS: mips16 hard float enable."), cl::init(false))
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
LLVM Basic Block Representation.
Type * getContainedType(unsigned i) const
static void inlineAsmOut(LLVMContext &C, StringRef AsmString, BasicBlock *BB)
bool isFloatTy() const
isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsSubtarget &Subtarget)
Function doesn't unwind stack.
virtual bool runOnModule(Module &M)
static FPParamVariant whichFPParamVariantNeeded(Function &F)
AttributeSet addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Attr) const
Add an attribute to the attribute set at the given index. Since attribute sets are immutable...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
FunctionType * getFunctionType() const
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
const Type::TypeID DoubleTyID
LLVM Value Representation.
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsSubtarget &Subtarget)
void addAttributes(unsigned i, AttributeSet attrs)
adds the attributes to the list of attributes.
static void assureFPCallStub(Function &F, Module *M, const MipsSubtarget &Subtarget)
LLVMContext & getContext() const