diff --git a/llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp b/llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp index b2dd07e5138b..637e8565b251 100644 --- a/llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp +++ b/llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp @@ -2315,68 +2315,60 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB, // Handle casts from integer to floating point now... if (DestClass == cFP32 || DestClass == cFP64) { - // Emit a library call for long to float conversion - if (SrcClass == cLong) { - std::vector Args; - Args.push_back(ValueRecord(SrcReg, SrcTy)); - Function *floatFn = (DestClass == cFP32) ? __floatdisfFn : __floatdidfFn; - MachineInstr *TheCall = - BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true); - doCall(ValueRecord(DestReg, DestTy), TheCall, Args, false); - return; - } - - // Make sure we're dealing with a full 32 bits - unsigned TmpReg = makeAnotherReg(Type::IntTy); - promote32(TmpReg, ValueRecord(SrcReg, SrcTy)); - - SrcReg = TmpReg; - // Spill the integer to memory and reload it from there. - // Also spill room for a special conversion constant - int ConstantFrameIndex = - F->getFrameInfo()->CreateStackObject(Type::DoubleTy, TM.getTargetData()); + unsigned TmpReg = makeAnotherReg(Type::DoubleTy); int ValueFrameIdx = F->getFrameInfo()->CreateStackObject(Type::DoubleTy, TM.getTargetData()); - unsigned constantHi = makeAnotherReg(Type::IntTy); - unsigned constantLo = makeAnotherReg(Type::IntTy); - unsigned ConstF = makeAnotherReg(Type::DoubleTy); - unsigned TempF = makeAnotherReg(Type::DoubleTy); - - if (!SrcTy->isSigned()) { - BuildMI(*BB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330); - BuildMI(*BB, IP, PPC::LI, 1, constantLo).addSImm(0); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi), - ConstantFrameIndex); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantLo), - ConstantFrameIndex, 4); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi), - ValueFrameIdx); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(SrcReg), - ValueFrameIdx, 4); - addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, ConstF), - ConstantFrameIndex); - addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, TempF), ValueFrameIdx); - BuildMI(*BB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF); - } else { - unsigned TempLo = makeAnotherReg(Type::IntTy); - BuildMI(*BB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330); - BuildMI(*BB, IP, PPC::LIS, 1, constantLo).addSImm(0x8000); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi), - ConstantFrameIndex); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantLo), - ConstantFrameIndex, 4); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi), - ValueFrameIdx); - BuildMI(*BB, IP, PPC::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000); - addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(TempLo), - ValueFrameIdx, 4); - addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, ConstF), - ConstantFrameIndex); - addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, TempF), ValueFrameIdx); - BuildMI(*BB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF); + if (SrcClass == cLong) { + if (SrcTy->isSigned()) { + addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(SrcReg), + ValueFrameIdx); + addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TmpReg), + ValueFrameIdx); + BuildMI(*MBB, IP, PPC::FCFID, 1, DestReg).addReg(TmpReg); + } else { + unsigned Scale = getReg(ConstantFP::get(Type::DoubleTy, 0x1p32)); + unsigned TmpHi = makeAnotherReg(Type::IntTy); + unsigned TmpLo = makeAnotherReg(Type::IntTy); + unsigned FPLow = makeAnotherReg(Type::DoubleTy); + unsigned FPTmpHi = makeAnotherReg(Type::DoubleTy); + unsigned FPTmpLo = makeAnotherReg(Type::DoubleTy); + int OtherFrameIdx = F->getFrameInfo()->CreateStackObject(Type::DoubleTy, + TM.getTargetData()); + BuildMI(*MBB, IP, PPC::RLDICL, 3, TmpHi).addReg(SrcReg).addImm(32) + .addImm(32); + BuildMI(*MBB, IP, PPC::RLDICL, 3, TmpLo).addReg(SrcReg).addImm(0) + .addImm(32); + addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(TmpHi), + ValueFrameIdx); + addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(TmpLo), + OtherFrameIdx); + addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TmpReg), + ValueFrameIdx); + addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, FPLow), + OtherFrameIdx); + BuildMI(*MBB, IP, PPC::FCFID, 1, FPTmpHi).addReg(TmpReg); + BuildMI(*MBB, IP, PPC::FCFID, 1, FPTmpLo).addReg(FPLow); + BuildMI(*MBB, IP, PPC::FMADD, 3, DestReg).addReg(Scale).addReg(FPTmpHi) + .addReg(FPTmpLo); + } + return; } + + // FIXME: really want a promote64 + unsigned IntTmp = makeAnotherReg(Type::IntTy); + + if (SrcTy->isSigned()) + BuildMI(*MBB, IP, PPC::EXTSW, 1, IntTmp).addReg(SrcReg); + else + BuildMI(*MBB, IP, PPC::RLDICL, 3, IntTmp).addReg(SrcReg).addImm(0) + .addImm(32); + addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(IntTmp), + ValueFrameIdx); + addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TmpReg), + ValueFrameIdx); + BuildMI(*MBB, IP, PPC::FCFID, 1, DestReg).addReg(TmpReg); return; } diff --git a/llvm/lib/Target/PowerPC/PowerPCInstrInfo.td b/llvm/lib/Target/PowerPC/PowerPCInstrInfo.td index 8629824ab2d0..6319167638cb 100644 --- a/llvm/lib/Target/PowerPC/PowerPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PowerPCInstrInfo.td @@ -104,6 +104,7 @@ def FADD : AForm_2<"fadd", 63, 21, 0, 0, 0>; def FADDS : AForm_2<"fadds", 59, 21, 0, 0, 0>; def FSUB : AForm_2<"fsub", 63, 20, 0, 0, 0>; def FSUBS : AForm_2<"fsubs", 59, 20, 0, 0, 0>; +def FMADD : AForm_2<"fmul", 63, 29, 0, 0, 0>; def FMUL : AForm_3<"fmul", 63, 25, 0, 0, 0>; def FMULS : AForm_3<"fmuls", 59, 25, 0, 0, 0>; def FDIV : AForm_2<"fdiv", 63, 18, 0, 0, 0>; @@ -232,18 +233,24 @@ def EXTSB : XForm_11<31, 954, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS), "extsb $rA, $rS">; def EXTSH : XForm_11<31, 922, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS), "extsh $rA, $rS">; +def EXTSW : XForm_11<31, 986, 0, 1, 0, (ops GPRC:$rA, GPRC:$rS), + "extsw $rA, $rS">; def LFSX : XForm_25<31, 535, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index), "lfsx $dst, $base, $index">; def LFDX : XForm_25<31, 599, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index), "lfdx $dst, $base, $index">; +def FCFID : XForm_26<63, 846, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB), + "fcfid $frD, $frB">; +def FCTIDZ : XForm_26<63, 815, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB), + "fctidz $frD, $frB">; +def FCTIWZ : XForm_26<63, 15, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB), + "fctiwz $frD, $frB">; def FMR : XForm_26<63, 72, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB), "fmr $frD, $frB">; def FNEG : XForm_26<63, 80, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB), "fneg $frD, $frB">; def FRSP : XForm_26<63, 12, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB), "frsp $frD, $frB">; -def FCTIWZ : XForm_26<63, 15, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB), - "fctiwz $frD, $frB">; def STFSX : XForm_28<31, 663, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB), "stfsx $frS, $rA, $rB">; def STFDX : XForm_28<31, 727, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB), diff --git a/llvm/lib/Target/PowerPC/README.txt b/llvm/lib/Target/PowerPC/README.txt index 222780b87c6c..356251d111ef 100644 --- a/llvm/lib/Target/PowerPC/README.txt +++ b/llvm/lib/Target/PowerPC/README.txt @@ -1,10 +1,10 @@ TODO: * switch to auto-generated asm writer -* use stfiwx in float->int +* fix rlwimi generation to be use-and-def * implement scheduling info * implement powerpc-64 for darwin * implement powerpc-64 for aix -* fix rlwimi generation to be use-and-def +* use stfiwx in float->int * should hint to the branch select pass that it doesn't need to print the second unconditional branch, so we don't end up with things like: b .LBBl42__2E_expand_function_8_674 ; loopentry.24