diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-09-06 22:03:27 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-09-06 22:03:27 +0000 |
commit | c09eeec0ebc378644bafd04916e5efafa7d98152 (patch) | |
tree | d78613977511e6d8bfc0da57a58164ea62430d2b /lib/Target/PowerPC/PPCISelLowering.cpp | |
parent | 46a780056b4b8a76773836a05b3f64f0781b2622 (diff) |
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
Diffstat (limited to 'lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index d01dc05a85..bf8dbed006 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<PPCSubtarget>().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. |