Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -73,6 +73,9 @@ // FP-to-int truncation node. TruncIntFP, + // int-to-FP conversion node. + ConvertIntFP, + // Return Ret, @@ -492,6 +495,8 @@ bool IsSRA) const; SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) const; /// isEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -127,6 +127,7 @@ case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP"; + case MipsISD::ConvertIntFP: return "MipsISD::ConvertIntFP"; case MipsISD::MFHI: return "MipsISD::MFHI"; case MipsISD::MFLO: return "MipsISD::MFLO"; case MipsISD::MTLOHI: return "MipsISD::MTLOHI"; @@ -287,6 +288,14 @@ setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + if (!Subtarget.isGP64bit() && Subtarget.hasMips32r2() && Subtarget.isFP64bit()) { + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom); + } else { + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); + setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); + } + if (Subtarget.isGP64bit()) { setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); setOperationAction(ISD::BlockAddress, MVT::i64, Custom); @@ -297,9 +306,11 @@ setOperationAction(ISD::LOAD, MVT::i64, Custom); setOperationAction(ISD::STORE, MVT::i64, Custom); setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom); setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom); setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom); setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Legal); } if (!Subtarget.isGP64bit()) { @@ -330,10 +341,7 @@ setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); - setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); - setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); - setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); if (Subtarget.hasCnMips()) { setOperationAction(ISD::CTPOP, MVT::i32, Legal); @@ -934,7 +942,9 @@ case ISD::LOAD: return lowerLOAD(Op, DAG); case ISD::STORE: return lowerSTORE(Op, DAG); case ISD::EH_DWARF_CFA: return lowerEH_DWARF_CFA(Op, DAG); + case ISD::FP_TO_UINT: return lowerFP_TO_SINT(Op, DAG); case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG); + case ISD::UINT_TO_FP: return lowerUINT_TO_FP(Op, DAG); } return SDValue(); } @@ -2271,9 +2281,32 @@ SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const { EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); - SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Op), FPTy, - Op.getOperand(0)); - return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc); + SDValue Trunc = + DAG.getNode(MipsISD::TruncIntFP, SDLoc(Op), FPTy, Op.getOperand(0)); + + if (FPTy == MVT::f32 || (Subtarget.isGP64bit() && FPTy == MVT::f64)) { + return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc); + } else { + SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, SDLoc(Op), MVT::i32, + Trunc, DAG.getConstant(0, SDLoc(Op), MVT::i32)); + SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, SDLoc(Op), MVT::i32, + Trunc, DAG.getConstant(1, SDLoc(Op), MVT::i32)); + SDValue Ops[] = {Lo, Hi}; + return DAG.getMergeValues(Ops, SDLoc(Op)); + } +} + +SDValue MipsTargetLowering::lowerUINT_TO_FP(SDValue Op, + SelectionDAG &DAG) const { + + SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(Op), MVT::i32, Op.getOperand(0), + DAG.getConstant(0, SDLoc(Op), MVT::i32)); + SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(Op), MVT::i32, Op.getOperand(0), + DAG.getConstant(1, SDLoc(Op), MVT::i32)); + + SDValue V = DAG.getNode(MipsISD::BuildPairF64, SDLoc(Op), Op.getValueType(), Lo, Hi); + + return DAG.getNode(MipsISD::ConvertIntFP, SDLoc(Op), Op.getValueType(), V); } //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -32,6 +32,7 @@ def SDT_MipsCMovFP : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisVT<2, i32>, SDTCisSameAs<1, 3>]>; def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; +def SDT_MipsConvertIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; @@ -45,6 +46,7 @@ def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, [SDNPHasChain, SDNPOptInGlue]>; def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>; +def MipsConvertIntFP : SDNode<"MipsISD::ConvertIntFP", SDT_MipsConvertIntFP>; def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>; def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64", SDT_MipsExtractElementF64>; @@ -247,6 +249,12 @@ let hasFCCRegOperand = 1; } +class UIntToFp_FT : + PseudoSE<(outs OutRC:$dst), (ins InRC:$src), + [(set OutRC:$dst, (uint_to_fp InRC:$src))]> { + let usesCustomInserter = 1; +} + multiclass C_COND_M fmt, InstrItinClass itin> { @@ -420,6 +428,11 @@ def PseudoCVT_D64_L : ABSS_FT<"", FGR64Opnd, GPR64Opnd, II_CVT>; } +def UInt32ToFp32Pseudo : UIntToFp_FT; +def UInt32ToFp64Pseudo_32 : UIntToFp_FT, FGR_32; +def UInt32ToFp64Pseudo_64 : UIntToFp_FT, FGR_64; +def UInt64ToFp64Pseudo_64 : UIntToFp_FT, FGR_64; + def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>, ABSS_FM<0x5, 16>; def FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>, @@ -783,6 +796,8 @@ def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>; def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; +def : MipsPat<(MipsConvertIntFP FGR64Opnd:$src), (CVT_D64_L FGR64Opnd:$src)>, FGR_64; + def : MipsPat<(f32 (sint_to_fp GPR32Opnd:$src)), (PseudoCVT_S_W GPR32Opnd:$src)>; def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src), Index: lib/Target/Mips/MipsMSAInstrInfo.td =================================================================== --- lib/Target/Mips/MipsMSAInstrInfo.td +++ lib/Target/Mips/MipsMSAInstrInfo.td @@ -3772,6 +3772,11 @@ let usesCustomInserter = 1; } + def MSA_UINT_TO_FP : MipsPseudo <(outs MSA128F16:$wd), (ins GPR32Opnd:$rs), [(set MSA128F16:$wd, (f16 (uint_to_fp GPR32Opnd:$rs)))]> { + + let usesCustomInserter = 1; + } + def : MipsPat<(MipsTruncIntFP MSA128F16:$ws), (TRUNC_W_D64 (MSA_FP_EXTEND_D_PSEUDO MSA128F16:$ws))>; Index: lib/Target/Mips/MipsSEISelLowering.h =================================================================== --- lib/Target/Mips/MipsSEISelLowering.h +++ lib/Target/Mips/MipsSEISelLowering.h @@ -125,6 +125,11 @@ MachineBasicBlock *emitFPROUND_PSEUDO(MachineInstr &MI, MachineBasicBlock *BBi, bool IsFGR64) const; + MachineBasicBlock *emitUINT_TO_FP_MSA(MachineInstr &MI, + MachineBasicBlock *BB) const; + MachineBasicBlock *emitUINT_TO_FP(MachineInstr &MI, MachineBasicBlock *BB, + unsigned CvtOp, unsigned FaddOp, + bool isFP64) const; }; } Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -1224,6 +1224,16 @@ return emitFPEXTEND_PSEUDO(MI, BB, true); case Mips::MSA_FP_ROUND_D_PSEUDO: return emitFPROUND_PSEUDO(MI, BB, true); + case Mips::MSA_UINT_TO_FP: + return emitUINT_TO_FP_MSA(MI, BB); + case Mips::UInt32ToFp32Pseudo: + return emitUINT_TO_FP(MI, BB, Mips::CVT_S_W, Mips::FADD_S, false); + case Mips::UInt32ToFp64Pseudo_32: + return emitUINT_TO_FP(MI, BB, Mips::CVT_D32_W, Mips::FADD_D32, false); + case Mips::UInt32ToFp64Pseudo_64: + return emitUINT_TO_FP(MI, BB, Mips::CVT_D64_W, Mips::FADD_D64, true); + case Mips::UInt64ToFp64Pseudo_64: + return emitUINT_TO_FP(MI, BB, Mips::CVT_D64_L, Mips::FADD_D64, true); } } @@ -3844,6 +3854,121 @@ return BB; } +// Emit the MSA_UINT_TO_FP pseudo instruction. +MachineBasicBlock * +MipsSETargetLowering::emitUINT_TO_FP_MSA(MachineInstr &MI, + MachineBasicBlock *BB) const { + + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); + const TargetRegisterClass *RC = &Mips::MSA128WRegClass; + DebugLoc DL = MI.getDebugLoc(); + unsigned Wd1 = RegInfo.createVirtualRegister(RC); + unsigned Wd2 = RegInfo.createVirtualRegister(RC); + unsigned Wd3 = RegInfo.createVirtualRegister(&Mips::MSA128HRegClass); + BuildMI(*BB, MI, DL, TII->get(Mips::FILL_W), Wd1) + .addReg(MI.getOperand(1).getReg()); + BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_W), Wd2).addReg(Wd1); + BuildMI(*BB, MI, DL, TII->get(Mips::FEXDO_H), MI.getOperand(0).getReg()) + .addReg(Wd2) + .addReg(Wd2); + + MI.eraseFromParent(); + return BB; +} + +// Emit the UIntToFpPseudo pseudo instruction. +MachineBasicBlock *MipsSETargetLowering::emitUINT_TO_FP(MachineInstr &MI, + MachineBasicBlock *BB, + unsigned CvtOp, + unsigned FaddOp, + bool IsFP64) const { + + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); + DebugLoc DL = MI.getDebugLoc(); + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction *MF = BB->getParent(); + MachineBasicBlock *newMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineFunction::iterator It = ++BB->getIterator(); + MF->insert(It, newMBB); + MF->insert(It, exitMBB); + + // Transfer the remainder of BB and its successor edges to exitMBB. + exitMBB->splice(exitMBB->begin(), BB, + std::next(MachineBasicBlock::iterator(MI)), BB->end()); + exitMBB->transferSuccessorsAndUpdatePHIs(BB); + + BB->addSuccessor(newMBB); + BB->addSuccessor(exitMBB); + newMBB->addSuccessor(exitMBB); + + unsigned Dest = MI.getOperand(0).getReg(); + unsigned Src = MI.getOperand(1).getReg(); + + const TargetRegisterClass *FPRegClass = RegInfo.getRegClass(Dest); + const TargetRegisterClass *GPRegClass = RegInfo.getRegClass(Src); + + const bool IsSrc64 = GPRegClass == &Mips::GPR64RegClass; + const bool IsDest64 = FPRegClass != &Mips::FGR32RegClass; + + const bool IsFGR64onMips64 = Subtarget.hasMips64() && IsFP64; + const bool IsFGR64onMips32 = !Subtarget.hasMips64() && IsFP64; + + unsigned FPVReg1 = RegInfo.createVirtualRegister(FPRegClass); + unsigned FPVReg2 = RegInfo.createVirtualRegister(FPRegClass); + unsigned FPVReg3 = RegInfo.createVirtualRegister(FPRegClass); + unsigned FPVReg4 = RegInfo.createVirtualRegister(FPRegClass); + unsigned GPVReg1 = RegInfo.createVirtualRegister(GPRegClass); + unsigned GPVReg2 = RegInfo.createVirtualRegister(GPRegClass); + + const uint64_t AddValue = IsSrc64 ? 0x43F0 : 0x41F0; + + if (Subtarget.hasMips64() && IsSrc64) + BuildMI(BB, DL, TII->get(Mips::DMTC1), FPVReg1).addReg(Src); + else + BuildMI(BB, DL, TII->get(Mips::MTC1), FPVReg1).addReg(Src); + + BuildMI(BB, DL, TII->get(CvtOp), FPVReg2).addReg(FPVReg1); + BuildMI(BB, DL, TII->get(Mips::BGEZ)) + .addReg(Src, RegState::Kill) + .addMBB(exitMBB); + + BuildMI(newMBB, DL, TII->get(Mips::LUi), GPVReg1).addImm(AddValue); + + if (IsDest64) { + if (!IsFP64) + BuildMI(newMBB, DL, TII->get(Mips::BuildPairF64), FPVReg3) + .addReg(Mips::ZERO) + .addReg(GPVReg1); + else if (IsFGR64onMips32) + BuildMI(newMBB, DL, TII->get(Mips::BuildPairF64_64), FPVReg3) + .addReg(Mips::ZERO_64) + .addReg(GPVReg1); + else if (IsFGR64onMips64) { + BuildMI(newMBB, DL, TII->get(Mips::DSLL), GPVReg2) + .addReg(GPVReg1) + .addImm(32); + BuildMI(newMBB, DL, TII->get(Mips::DMTC1), FPVReg3).addReg(GPVReg2); + } + } else + BuildMI(newMBB, DL, TII->get(Mips::MTC1), FPVReg3).addReg(GPVReg1); + + BuildMI(newMBB, DL, TII->get(FaddOp), FPVReg4) + .addReg(FPVReg2) + .addReg(FPVReg3); + + BuildMI(*exitMBB, exitMBB->begin(), DL, TII->get(Mips::PHI), Dest) + .addReg(FPVReg2) + .addMBB(BB) + .addReg(FPVReg4) + .addMBB(newMBB); + + MI.eraseFromParent(); + return exitMBB; +} + // Emit the FEXP2_W_1 pseudo instructions. // // fexp2_w_1_pseudo $wd, $wt Index: test/CodeGen/Mips/2008-07-07-Float2Int.ll =================================================================== --- test/CodeGen/Mips/2008-07-07-Float2Int.ll +++ test/CodeGen/Mips/2008-07-07-Float2Int.ll @@ -11,7 +11,6 @@ entry: ; CHECK: fptouint ; CHECK: trunc.w.s -; CHECK: trunc.w.s fptoui float %a to i32 ; :0 [#uses=1] ret i32 %0 } Index: test/CodeGen/Mips/llvm-ir/fpcvt.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/llvm-ir/fpcvt.ll @@ -0,0 +1,120 @@ +; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck --check-prefixes=FP32,ALL %s +; RUN: llc < %s -march=mips -mcpu=mips32r2 -mattr=+fp64 | FileCheck --check-prefixes=FP64,FP64EB,ALL %s +; RUN: llc < %s -march=mips64 -mcpu=mips64r2 -target-abi n64 | FileCheck --check-prefixes=MIPS64,ALL %s +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck --check-prefixes=FP32,ALL %s +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -mattr=+fp64 | FileCheck --check-prefixes=FP64,FP64EL,ALL %s +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -target-abi n64 | FileCheck --check-prefixes=MIPS64,ALL %s + + +define float @uitofp32(i32 %a) { +entry: +; ALL-LABEL: uitofp32: +; FP32: mtc1 $[[R0:[0-9]+]], $f[[F0:[0-9]+]] +; FP32: bgez $[[R0]], $BB0_2 +; FP32: cvt.s.w $f[[F1:[0-9]+]], $f[[F0]] +; FP32: lui $1, 16880 +; FP32: mtc1 $1, $f[[F2:[0-9]+]] +; FP32: add.s $f0, $f[[F1]], $f[[F2]] + +; FP64: mtc1 $[[R0:[0-9]+]], $f[[F0:[0-9]+]] +; FP64: bgez $[[R0]], $BB0_2 +; FP64: cvt.s.w $f[[F1:[0-9]+]], $f[[F0]] +; FP64: lui $1, 16880 +; FP64: mtc1 $1, $f[[F2:[0-9]+]] +; FP64: add.s $f0, $f[[F1]], $f[[F2]] + +; MIPS64: mtc1 $[[R0:[0-9]+]], $f[[F0:[0-9]+]] +; MIPS64: bgez $[[R0]], +; MIPS64: cvt.s.w $f[[F1:[0-9]+]], $f[[F0]] +; MIPS64: lui $1, 16880 +; MIPS64: mtc1 $1, $f[[F2:[0-9]+]] +; MIPS64: add.s $f0, $f[[F1]], $f[[F2]] + + %0 = uitofp i32 %a to float + ret float %0 +} + +define i32 @fptoui32(float %a) { +entry: +; ALL-LABEL: fptoui32: +; FP32: sub.s $f[[F0:[0-9]+]], $f[[F1:[0-9]+]], $f[[F2:[0-9]+]] +; FP32: trunc.w.s $f[[F3:[0-9]+]], $f[[F0]] +; FP32: mfc1 $[[R1:.*]], $f[[F3]] +; FP32: lui $[[R3:.*]], 32768 +; FP32: xor $[[R4:.*]], $[[R1]], $[[R3]] +; FP32: trunc.w.s $f[[F4:[0-9]+]], $f[[F1]] +; FP32: mfc1 $[[R2:.*]], $f[[F4]] +; FP32: c.olt.s $f[[F1]], $f[[F2]] +; FP32: jr $ra +; FP32: movt $[[R4]], $[[R2]], $fcc0 + +; FP64: sub.s $f[[F0:[0-9]+]], $f[[F1:[0-9]+]], $f[[F2:[0-9]+]] +; FP64: trunc.w.s $f[[F3:[0-9]+]], $f[[F0]] +; FP64: mfc1 $[[R1:.*]], $f[[F3]] +; FP64: lui $[[R3:.*]], 32768 +; FP64: xor $[[R4:.*]], $[[R1]], $[[R3]] +; FP64: trunc.w.s $f[[F4:[0-9]+]], $f[[F1]] +; FP64: mfc1 $[[R2:.*]], $f[[F4]] +; FP64: c.olt.s $f[[F1]], $f[[F2]] +; FP64: jr $ra +; FP64: movt $[[R4]], $[[R2]], $fcc0 + +; MIPS64: sub.s $f[[F0:[0-9]+]], $f[[F1:[0-9]+]], $f[[F2:[0-9]+]] +; MIPS64: trunc.w.s $f[[F3:[0-9]+]], $f[[F0]] +; MIPS64: trunc.w.s $f[[F4:[0-9]+]], $f[[F1]] +; MIPS64: mfc1 $[[R1:.*]], $f[[F3]] +; MIPS64: mfc1 $[[R2:.*]], $f[[F4]] +; MIPS64: lui $[[R3:.*]], 32768 +; MIPS64: xor $[[R4:.*]], $[[R1]], $[[R3]] +; MIPS64: c.olt.s $f[[F1]], $f[[F2]] +; MIPS64: jr $ra +; MIPS64: movt $[[R4]], $[[R2]], $fcc0 + + %0 = fptoui float %a to i32 + ret i32 %0 +} + +define double @uitofp64(i64 %a) { +entry: +; ALL-LABEL: uitofp64: +; FP32: jal __floatundidf + +; FP64EB: mtc1 $5, $f[[F0:[0-9]+]] +; FP64EB: mthc1 $4, $f[[F0]] + +; FP64EL: mtc1 $4, $f[[F0:[0-9]+]] +; FP64EL: mthc1 $5, $f[[F0]] + +; FP64: cvt.d.l $f0, $f[[F0]] + +; MIPS64: dmtc1 $[[R0:.*]], $f[[F0:[0-9]+]] +; MIPS64: bgez $[[R0]], .L{{.*}} +; MIPS64: cvt.d.l $f[[F1:[0-9]+]], $f[[F0]] +; MIPS64: lui $[[R1:.*]], 17392 +; MIPS64: dsll $[[R2:.*]], $[[R1]], 32 +; MIPS64: dmtc1 $[[R2]], $f[[F2:[0-9]+]] +; MIPS64: add.d $f{{.*}}, $f[[F1]], $f[[F2]] + + %0 = uitofp i64 %a to double + ret double %0 +} + +define i64 @fptoui64(double %a) { +entry: +; ALL-LABEL: fptoui64: +; FP32: jal __fixunsdfdi + +; FP64: trunc.l.d $f[[F0:[0-9]+]], $f12 +; FP64EB: mfhc1 $2, $f[[F0]] +; FP64EB: mfc1 $3, $f[[F0]] + +; FP64EL: mfc1 $2, $f[[F0]] +; FP64EL: mfhc1 $3, $f[[F0]] + +; MIPS64: trunc.l.d $f[[F0:[0-9]+]], $f12 +; MIPS64: dmfc1 $2, $f[[F0]] + + %0 = fptoui double %a to i64 + ret i64 %0 +} + Index: test/CodeGen/Mips/msa/f16-llvm-ir.ll =================================================================== --- test/CodeGen/Mips/msa/f16-llvm-ir.ll +++ test/CodeGen/Mips/msa/f16-llvm-ir.ll @@ -118,20 +118,8 @@ %0 = load half, half * @h, align 2 %1 = fptoui half %0 to i32 -; MIPS32: lwc1 $f[[FC:[0-9]+]], %lo($CPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS64-N32: lwc1 $f[[FC:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS64-N64: lwc1 $f[[FC:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}}) - ; ALL: lh $[[R0:[0-9]+]] ; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]] -; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]] -; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0] -; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]] -; MIPSR6: cmp.lt.s $f[[F1:[0-9]+]], $f[[F0]], $f[[FC]] -; ALL: sub.s $f[[F2:[0-9]+]], $f[[F0]], $f[[FC]] -; ALL: mfc1 $[[R2:[0-9]]], $f[[F2]] -; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]] -; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]] ; ALL: fexupr.w $w[[W4:[0-9]+]], $w[[W3]] ; ALL: fexupr.d $w[[W5:[0-9]+]], $w[[W4]] @@ -145,43 +133,6 @@ ; ALL: trunc.w.d $f[[F4:[0-9]+]], $f[[F3]] ; ALL: mfc1 $[[R4:[0-9]+]], $f[[F4]] -; ALL: fexupr.d $w[[W6:[0-9]+]], $w[[W1]] - -; MIPS32: copy_s.w $[[R5:[0-9]+]], $w[[W6]][0] -; MIPS32: mtc1 $[[R5]], $f[[F5:[0-9]+]] -; MIPS32: copy_s.w $[[R6:[0-9]+]], $w[[W6]][1] -; MIPS32: mthc1 $[[R6]], $f[[F5]] - -; MIPS64: copy_s.d $[[R2:[0-9]+]], $w[[W2]][0] -; MIPS64: dmtc1 $[[R2]], $f[[F5:[0-9]+]] - -; ALL: trunc.w.d $f[[F6:[0-9]]], $f[[F5]] -; ALL: mfc1 $[[R7:[0-9]]], $f[[F6]] - -; MIPS32R5-O32: lw $[[R13:[0-9]+]], %got($CPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS32R5-O32: addiu $[[R14:[0-9]+]], $[[R13]], %lo($CPI{{[0-9]+}}_{{[0-9]+}}) - -; MIPS64R5-N32: lw $[[R13:[0-9]+]], %got_page(.LCPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS64R5-N32: addiu $[[R14:[0-9]+]], $[[R13]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}}) - -; MIPS64R5-N64: ld $[[R13:[0-9]+]], %got_page(.LCPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS64R5-N64: daddiu $[[R14:[0-9]+]], $[[R13]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}}) - -; ALL: lui $[[R8:[0-9]+]], 32768 -; ALL: xor $[[R9:[0-9]+]], $[[R4]], $[[R8]] - -; MIPSR5: lh $[[R15:[0-9]+]], 0($[[R14]]) -; MIPSR5: fill.h $w[[W7:[0-9]+]], $[[R15]] -; MIPSR5: fexupr.w $w[[W8:[0-9]+]], $w[[W7]] -; MIPSR5: copy_s.w $[[R16:[0-9]+]], $w[[W8]][0] -; MIPSR5: mtc1 $[[R16]], $f[[F7:[0-9]+]] -; MIPSR5: c.olt.s $f[[F0]], $f[[F7]] -; MIPSR5: movt $[[R9]], $[[R7]], $fcc0 - -; MIPSR6: mfc1 $[[R10:[0-9]+]], $f[[F1]] -; MIPSR6: seleqz $[[R11:[0-9]]], $[[R9]], $[[R10]] -; MIPSR6: selnez $[[R12:[0-9]]], $[[R7]], $[[R10]] -; MIPSR6: or $2, $[[R12]], $[[R11]] ret i32 %1 } @@ -214,36 +165,17 @@ entry: ; ALL-LABEL: uitofp: -; MIPS32-O32: ldc1 $f[[F0:[0-9]+]], %lo($CPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS32-O32: ldc1 $f[[F1:[0-9]+]], 0($sp) - -; MIPS64-N32: ldc1 $f[[F0:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS64-N32: ldc1 $f[[F1:[0-9]+]], 8($sp) - -; MIPS64-N64: ldc1 $f[[F0:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}}) -; MIPS64-N64: ldc1 $f[[F1:[0-9]+]], 8($sp) - -; MIPSR5: sub.d $f[[F2:[0-9]+]], $f[[F1]], $f[[F0]] -; MIPSR6-O32: sub.d $f[[F2:[0-9]+]], $f[[F0]], $f[[F1]] -; MIPSR6-N32: sub.d $f[[F2:[0-9]+]], $f[[F1]], $f[[F0]] -; MIPSR6-N64: sub.d $f[[F2:[0-9]+]], $f[[F1]], $f[[F0]] - -; MIPS32: mfc1 $[[R0:[0-9]+]], $f[[F2]] -; MIPS32: fill.w $w[[W0:[0-9]+]], $[[R0]] -; MIPS32: mfhc1 $[[R1:[0-9]+]], $f[[F2]] -; MIPS32: insert.w $w[[W0]][1], $[[R1]] -; MIPS32: insert.w $w[[W0]][3], $[[R1]] +; MIPS32: lw $[[R3:[0-9]+]], %got(h) +; MIPS32: fill.w $w[[W0:[0-9]+]], $4 +; MIPS32: ffint_u.w $w[[W1:[0-9]+]], $w[[W0]] -; MIPS64-N64: ld $[[R3:[0-9]+]], %got_disp(h) -; MIPS64-N32: lw $[[R3:[0-9]+]], %got_disp(h) -; MIPS64: dmfc1 $[[R1:[0-9]+]], $f[[F2]] -; MIPS64: fill.d $w[[W0:[0-9]+]], $[[R1]] +; MIPS64-DAG: sll $[[R1:[0-9]+]], $4, 0 +; MIPS64-N32-DAG: lw $[[R3:[0-9]+]], %got_disp(h) +; MIPS64-N64-DAG: ld $[[R3:[0-9]+]], %got_disp(h) +; MIPS64-DAG: fill.w $w[[W0:[0-9]+]], $[[R1]] -; ALL: fexdo.w $w[[W1:[0-9]+]], $w[[W0]], $w[[W0]] ; ALL: fexdo.h $w[[W2:[0-9]+]], $w[[W1]], $w[[W1]] -; MIPS32: lw $[[R3:[0-9]+]], %got(h) - ; ALL: copy_u.h $[[R2:[0-9]+]], $w[[W2]] ; ALL: sh $[[R2]], 0($[[R3]]) %0 = uitofp i32 %a to half