From: Nate Begeman Date: Tue, 6 Sep 2005 22:03:27 +0000 (+0000) Subject: Implement i64<->fp using the fctidz/fcfid instructions on PowerPC when we X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c09eeec0ebc378644bafd04916e5efafa7d98152;p=oota-llvm.git Implement i64<->fp using the fctidz/fcfid instructions on PowerPC when we are allowed to generate 64-bit-only PowerPC instructions for 32 bit hosts, such as the PowerPC 970. This speeds up 189.lucas from 81.99 to 32.64 seconds. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23250 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index dc87b05e8e1..dd3fe514df2 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -795,6 +795,14 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { Select(N->getOperand(1)), Select(N->getOperand(2))); return SDOperand(N, 0); + case PPCISD::FCFID: + CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0), + Select(N->getOperand(0))); + return SDOperand(N, 0); + case PPCISD::FCTIDZ: + CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0), + Select(N->getOperand(0))); + return SDOperand(N, 0); case PPCISD::FCTIWZ: CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), Select(N->getOperand(0))); @@ -1085,10 +1093,11 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { isRotateAndMask(N, Imm, true, SH, MB, ME)) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0).getOperand(0)), - getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); + getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME)); else if (isIntImmediate(N->getOperand(1), Imm)) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)), - getI32Imm(32-Imm), getI32Imm(Imm), getI32Imm(31)); + getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm), + getI32Imm(31)); else CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index d01dc05a851..bf8dbed006d 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -86,11 +86,18 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); - + // PowerPC does not have [U|S]INT_TO_FP setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); + // 64 bit PowerPC implementations have instructions to facilitate conversion + // between i64 and fp. + if (TM.getSubtarget().is64Bit()) { + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); + setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); + } + setSetCCResultContents(ZeroOrOneSetCCResult); computeRegisterProperties(); @@ -115,17 +122,43 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Wasn't expecting to be able to lower this!"); case ISD::FP_TO_SINT: { - assert(Op.getValueType() == MVT::i32 && - MVT::isFloatingPoint(Op.getOperand(0).getValueType())); - Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); + assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType())); + switch (Op.getValueType()) { + default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!"); + case MVT::i32: + Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); + break; + case MVT::i64: + Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Op.getOperand(0)); + break; + } int FrameIdx = DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), Op, FI, DAG.getSrcValue(0)); - FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); - return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); + if (Op.getOpcode() == PPCISD::FCTIDZ) { + Op = DAG.getLoad(MVT::i64, ST, FI, DAG.getSrcValue(0)); + } else { + FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); + Op = DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); + } + return Op; + } + case ISD::SINT_TO_FP: { + assert(MVT::i64 == Op.getOperand(0).getValueType() && + "Unhandled SINT_TO_FP type in custom expander!"); + int FrameIdx = + DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); + SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); + SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op.getOperand(0), FI, DAG.getSrcValue(0)); + SDOperand LD = DAG.getLoad(MVT::f64, ST, FI, DAG.getSrcValue(0)); + SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, LD); + if (MVT::f32 == Op.getValueType()) + FP = DAG.getNode(ISD::FP_ROUND, MVT::f32, FP); + return FP; } case ISD::SELECT_CC: { // Turn FP only select_cc's into fsel instructions. diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 924a672d2cc..eecbfda01d3 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -29,9 +29,15 @@ namespace llvm { /// FSEL, - /// FCTIWZ - The FCTIWZ instruction, taking an f32 or f64 operand, - /// producing an f64 value. - FCTIWZ, + /// FCFID - The FCFID instruction, taking an f64 operand and producing + /// and f64 value containing the FP representation of the integer that + /// was temporarily in the f64 operand. + FCFID, + + /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 + /// operand, producing an f64 value containing the integer representation + /// of that FP value. + FCTIDZ, FCTIWZ, }; } diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp index 8c4b2b6a9a8..2cb3d8fbd1e 100644 --- a/lib/Target/PowerPC/PPCISelPattern.cpp +++ b/lib/Target/PowerPC/PPCISelPattern.cpp @@ -817,6 +817,14 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { Tmp3 = SelectExpr(N.getOperand(2)); BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; + case PPCISD::FCFID: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp1); + return Result; + case PPCISD::FCTIDZ: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FCTIDZ, 1, Result).addReg(Tmp1); + return Result; case PPCISD::FCTIWZ: Tmp1 = SelectExpr(N.getOperand(0)); BuildMI(BB, PPC::FCTIWZ, 1, Result).addReg(Tmp1); @@ -1084,13 +1092,13 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { if (isOpcWithIntImmediate(N.getOperand(0), ISD::AND, Tmp3) && isRotateAndMask(ISD::SRL, Tmp2, Tmp3, true, SH, MB, ME)) { Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH) + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH & 0x1F) .addImm(MB).addImm(ME); return Result; } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 &= 0x1F; - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(32-Tmp2) + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm((32-Tmp2) & 0x1F) .addImm(Tmp2).addImm(31); } else { Tmp1 = SelectExpr(N.getOperand(0));