aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCISelLowering.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-09-06 22:03:27 +0000
committerNate Begeman <natebegeman@mac.com>2005-09-06 22:03:27 +0000
commitc09eeec0ebc378644bafd04916e5efafa7d98152 (patch)
treed78613977511e6d8bfc0da57a58164ea62430d2b /lib/Target/PowerPC/PPCISelLowering.cpp
parent46a780056b4b8a76773836a05b3f64f0781b2622 (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.cpp45
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.