aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-08-17 23:46:35 +0000
committerNate Begeman <natebegeman@mac.com>2005-08-17 23:46:35 +0000
commit26653500bbbc21cd1c2d12ecc433fa439536b657 (patch)
tree7305fc93c7f4b8c27b91f236595f732ee7eda91c /lib/Target/PowerPC/PPCISelDAGToDAG.cpp
parent0f66a9172175aa7c3055333358170581c999219b (diff)
Teach the DAG->DAG ISel about FNEG, and how it can be used to invert
several of the PowerPC opcodes that come in both negated and non-negated forms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22845 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 974f266d8b..2b7dd32aa8 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -199,7 +199,6 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
break;
}
}
-
case ISD::ADD: {
MVT::ValueType Ty = N->getValueType(0);
if (Ty == MVT::i32) {
@@ -281,7 +280,35 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
Select(N->getOperand(0)),
Select(N->getOperand(1)));
break;
- }
+ }
+ case ISD::FNEG: {
+ SDOperand Val = Select(N->getOperand(0));
+ MVT::ValueType Ty = N->getValueType(0);
+ if (Val.Val->hasOneUse()) {
+ unsigned Opc;
+ switch (Val.getTargetOpcode()) {
+ default: Opc = 0; break;
+ case PPC::FABS: Opc = PPC::FNABS; break;
+ case PPC::FMADD: Opc = PPC::FNMADD; break;
+ case PPC::FMADDS: Opc = PPC::FNMADDS; break;
+ case PPC::FMSUB: Opc = PPC::FNMSUB; break;
+ case PPC::FMSUBS: Opc = PPC::FNMSUBS; break;
+ }
+ // If we inverted the opcode, then emit the new instruction with the
+ // inverted opcode and the original instruction's operands. Otherwise,
+ // fall through and generate a fneg instruction.
+ if (Opc) {
+ if (PPC::FNABS == Opc)
+ CurDAG->SelectNodeTo(N, Ty, Opc, Val.getOperand(0));
+ else
+ CurDAG->SelectNodeTo(N, Ty, Opc, Val.getOperand(0),
+ Val.getOperand(1), Val.getOperand(2));
+ break;
+ }
+ }
+ CurDAG->SelectNodeTo(N, Ty, PPC::FNEG, Val);
+ break;
+ }
case ISD::RET: {
SDOperand Chain = Select(N->getOperand(0)); // Token chain.