diff options
| author | Reed Kotler <rkotler@mips.com> | 2014-10-10 17:00:46 +0000 |
|---|---|---|
| committer | Reed Kotler <rkotler@mips.com> | 2014-10-10 17:00:46 +0000 |
| commit | 12f9488e3375e5254226befb423b888b65410ee0 (patch) | |
| tree | a2352097c75361683847d854f270c37a33d45472 /llvm/lib | |
| parent | 7d6f29d1eed3bcbd716ac7502a71ee4792c2538d (diff) | |
| download | bcm5719-llvm-12f9488e3375e5254226befb423b888b65410ee0.tar.gz bcm5719-llvm-12f9488e3375e5254226befb423b888b65410ee0.zip | |
Implement floating point to integer conversion in mips fast-isel
Summary: Add the ability to convert 64 or 32 bit floating point values to integer in mips fast-isel
Test Plan:
fpintconv.ll
ran 4 flavors of test-suite with no errors, misp32 r1/r2 O0/O2
Reviewers: dsanders
Reviewed By: dsanders
Subscribers: llvm-commits, rfuhler, mcrosier
Differential Revision: http://reviews.llvm.org/D5562
llvm-svn: 219511
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsFastISel.cpp | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index 14cf86f0b77..63299f9b988 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -48,6 +48,7 @@ class MipsFastISel final : public FastISel { LLVMContext *Context; bool TargetSupported; + bool UnsupportedFPMode; public: explicit MipsFastISel(FunctionLoweringInfo &funcInfo, @@ -63,6 +64,7 @@ public: TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) && (Subtarget->isABI_O32()))); + UnsupportedFPMode = Subtarget->isFP64bit(); } bool fastSelectInstruction(const Instruction *I) override; @@ -82,6 +84,7 @@ private: bool SelectTrunc(const Instruction *I); bool SelectFPExt(const Instruction *I); bool SelectFPTrunc(const Instruction *I); + bool SelectFPToI(const Instruction *I, bool IsSigned); bool isTypeLegal(Type *Ty, MVT &VT); bool isLoadTypeLegal(Type *Ty, MVT &VT); @@ -191,11 +194,15 @@ bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, break; } case MVT::f32: { + if (UnsupportedFPMode) + return false; ResultReg = createResultReg(&Mips::FGR32RegClass); Opc = Mips::LWC1; break; } case MVT::f64: { + if (UnsupportedFPMode) + return false; ResultReg = createResultReg(&Mips::AFGR64RegClass); Opc = Mips::LDC1; break; @@ -218,7 +225,7 @@ unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { MVT VT = CEVT.getSimpleVT(); if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) - return MaterializeFP(CFP, VT); + return (UnsupportedFPMode) ? 0 : MaterializeFP(CFP, VT); else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) return MaterializeGV(GV, VT); else if (isa<ConstantInt>(C)) @@ -244,9 +251,13 @@ bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr, Opc = Mips::SW; break; case MVT::f32: + if (UnsupportedFPMode) + return false; Opc = Mips::SWC1; break; case MVT::f64: + if (UnsupportedFPMode) + return false; Opc = Mips::SDC1; break; default: @@ -388,6 +399,8 @@ bool MipsFastISel::SelectRet(const Instruction *I) { // Attempt to fast-select a floating-point extend instruction. bool MipsFastISel::SelectFPExt(const Instruction *I) { + if (UnsupportedFPMode) + return false; Value *Src = I->getOperand(0); EVT SrcVT = TLI.getValueType(Src->getType(), true); EVT DestVT = TLI.getValueType(I->getType(), true); @@ -409,6 +422,8 @@ bool MipsFastISel::SelectFPExt(const Instruction *I) { // Attempt to fast-select a floating-point truncate instruction. bool MipsFastISel::SelectFPTrunc(const Instruction *I) { + if (UnsupportedFPMode) + return false; Value *Src = I->getOperand(0); EVT SrcVT = TLI.getValueType(Src->getType(), true); EVT DestVT = TLI.getValueType(I->getType(), true); @@ -481,6 +496,53 @@ bool MipsFastISel::SelectTrunc(const Instruction *I) { return true; } +// Attempt to fast-select a floating-point-to-integer conversion. +bool MipsFastISel::SelectFPToI(const Instruction *I, bool IsSigned) { + if (UnsupportedFPMode) + return false; + MVT DstVT, SrcVT; + if (!IsSigned) + return false; // We don't handle this case yet. There is no native + // instruction for this but it can be synthesized. + Type *DstTy = I->getType(); + if (!isTypeLegal(DstTy, DstVT)) + return false; + + if (DstVT != MVT::i32) + return false; + + Value *Src = I->getOperand(0); + Type *SrcTy = Src->getType(); + if (!isTypeLegal(SrcTy, SrcVT)) + return false; + + if (SrcVT != MVT::f32 && SrcVT != MVT::f64) + return false; + + unsigned SrcReg = getRegForValue(Src); + if (SrcReg == 0) + return false; + + // Determine the opcode for the conversion, which takes place + // entirely within FPRs. + unsigned DestReg = createResultReg(&Mips::GPR32RegClass); + unsigned TempReg = createResultReg(&Mips::FGR32RegClass); + unsigned Opc; + + if (SrcVT == MVT::f32) + Opc = Mips::TRUNC_W_S; + else + Opc = Mips::TRUNC_W_D32; + + // Generate the convert. + EmitInst(Opc, TempReg).addReg(SrcReg); + + EmitInst(Mips::MFC1, DestReg).addReg(TempReg); + + updateValueMap(I, DestReg); + return true; +} + bool MipsFastISel::fastSelectInstruction(const Instruction *I) { if (!TargetSupported) return false; @@ -502,11 +564,17 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) { return SelectFPTrunc(I); case Instruction::FPExt: return SelectFPExt(I); + case Instruction::FPToSI: + return SelectFPToI(I, /*isSigned*/ true); + case Instruction::FPToUI: + return SelectFPToI(I, /*isSigned*/ false); } return false; } unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) { + if (UnsupportedFPMode) + return 0; int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); if (VT == MVT::f32) { const TargetRegisterClass *RC = &Mips::FGR32RegClass; |

