diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 30 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 15 |
3 files changed, 40 insertions, 9 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ed62da5ecb..b344ddabc9 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -156,6 +156,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::FPCmp: return "MipsISD::FPCmp"; case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; + case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP"; case MipsISD::ExtractLOHI: return "MipsISD::ExtractLOHI"; case MipsISD::InsertLOHI: return "MipsISD::InsertLOHI"; case MipsISD::Mult: return "MipsISD::Mult"; @@ -249,6 +250,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); if (!TM.Options.NoNaNsFPMath) { setOperationAction(ISD::FABS, MVT::f32, Custom); @@ -264,6 +266,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SELECT, MVT::i64, Custom); setOperationAction(ISD::LOAD, MVT::i64, Custom); setOperationAction(ISD::STORE, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); } if (!HasMips64) { @@ -743,6 +746,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::LOAD: return lowerLOAD(Op, DAG); case ISD::STORE: return lowerSTORE(Op, DAG); case ISD::ADD: return lowerADD(Op, DAG); + case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG); } return SDValue(); } @@ -2027,6 +2031,22 @@ static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7); } +// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr). +static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG) { + SDValue Val = SD->getValue(); + + if (Val.getOpcode() != ISD::FP_TO_SINT) + return SDValue(); + + EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits()); + SDValue Tr = DAG.getNode(MipsISD::TruncIntFP, Val.getDebugLoc(), FPTy, + Val.getOperand(0)); + + return DAG.getStore(SD->getChain(), SD->getDebugLoc(), Tr, SD->getBasePtr(), + SD->getPointerInfo(), SD->isVolatile(), + SD->isNonTemporal(), SD->getAlignment()); +} + SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { StoreSDNode *SD = cast<StoreSDNode>(Op); EVT MemVT = SD->getMemoryVT(); @@ -2036,7 +2056,7 @@ SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { ((MemVT == MVT::i32) || (MemVT == MVT::i64))) return lowerUnalignedIntStore(SD, DAG, Subtarget->isLittle()); - return SDValue(); + return lowerFP_TO_SINT_STORE(SD, DAG); } SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { @@ -2060,6 +2080,14 @@ SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { DAG.getConstant(0, ValTy)); } +SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, + SelectionDAG &DAG) const { + EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); + SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, Op.getDebugLoc(), FPTy, + Op.getOperand(0)); + return DAG.getNode(ISD::BITCAST, Op.getDebugLoc(), Op.getValueType(), Trunc); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 68f05ff80a..ff645e27e2 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -60,6 +60,9 @@ namespace llvm { CMovFP_T, CMovFP_F, + // FP-to-int truncation node. + TruncIntFP, + // Return Ret, @@ -361,6 +364,7 @@ namespace llvm { SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerADD(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; /// isEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 6dc57e0709..e2acf284da 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -30,6 +30,7 @@ def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>, SDTCisVT<2, i32>]>; def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; +def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; @@ -42,6 +43,7 @@ def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, [SDNPHasChain, SDNPOptInGlue]>; +def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>; def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>; def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64", SDT_MipsExtractElementF64>; @@ -485,13 +487,12 @@ def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>; def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (PseudoCVT_S_W CPURegs:$src)>; -def : MipsPat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S FGR32:$src))>; +def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_W_S FGR32:$src)>; let Predicates = [NotFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), (PseudoCVT_D32_W CPURegs:$src)>; - def : MipsPat<(i32 (fp_to_sint AFGR64:$src)), - (MFC1 (TRUNC_W_D32 AFGR64:$src))>; + def : MipsPat<(MipsTruncIntFP AFGR64:$src), (TRUNC_W_D32 AFGR64:$src)>; def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_D32 AFGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D32_S FGR32:$src)>; } @@ -507,11 +508,9 @@ let Predicates = [IsFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)), (PseudoCVT_D64_L CPU64Regs:$src)>; - def : MipsPat<(i32 (fp_to_sint FGR64:$src)), - (MFC1 (TRUNC_W_D64 FGR64:$src))>; - def : MipsPat<(i64 (fp_to_sint FGR32:$src)), (DMFC1 (TRUNC_L_S FGR32:$src))>; - def : MipsPat<(i64 (fp_to_sint FGR64:$src)), - (DMFC1 (TRUNC_L_D64 FGR64:$src))>; + def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_W_D64 FGR64:$src)>; + def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_L_S FGR32:$src)>; + def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_L_D64 FGR64:$src)>; def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_D64 FGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>; |