[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPC.h PowerPCTargetMachine.cpp
Nate Begeman
natebegeman at mac.com
Tue Jul 19 09:51:16 PDT 2005
Changes in directory llvm/lib/Target/PowerPC:
PPC32ISelPattern.cpp updated: 1.99 -> 1.100
PowerPC.h updated: 1.15 -> 1.16
PowerPCTargetMachine.cpp updated: 1.52 -> 1.53
---
Log message:
Integrate SelectFPExpr into SelectExpr. This gets PPC32 closer to being
automatically generated from a target description.
---
Diffs of the changes: (+242 -346)
PPC32ISelPattern.cpp | 580 +++++++++++++++++++----------------------------
PowerPC.h | 2
PowerPCTargetMachine.cpp | 6
3 files changed, 242 insertions(+), 346 deletions(-)
Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.99 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.100
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.99 Sat Jul 9 20:56:13 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Jul 19 11:51:05 2005
@@ -17,9 +17,9 @@
#include "PowerPCInstrBuilder.h"
#include "PowerPCInstrInfo.h"
#include "PPC32TargetMachine.h"
-#include "llvm/Constants.h" // FIXME: REMOVE
+#include "llvm/Constants.h"
#include "llvm/Function.h"
-#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
@@ -563,7 +563,6 @@
unsigned SelectCC(SDOperand CC, unsigned &Opc, bool &Inv, unsigned &Idx);
unsigned SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv, unsigned &Idx);
unsigned SelectExpr(SDOperand N, bool Recording=false);
- unsigned SelectExprFP(SDOperand N, unsigned Result);
void Select(SDOperand N);
bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
@@ -1155,8 +1154,6 @@
BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
} else {
- if (PPCCRopts)
- return SelectCCExpr(CC, Opc, Inv, Idx);
// If this isn't a SetCC, then select the value and compare it against zero,
// treating it as if it were a boolean.
Opc = PPC::BNE;
@@ -1271,307 +1268,6 @@
return;
}
-unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
-{
- unsigned Tmp1, Tmp2, Tmp3;
- unsigned Opc = 0;
- SDNode *Node = N.Val;
- MVT::ValueType DestType = N.getValueType();
- unsigned opcode = N.getOpcode();
-
- switch (opcode) {
- default:
- Node->dump();
- assert(0 && "Node not handled!\n");
-
- case ISD::SELECT: {
- // Attempt to generate FSEL. We can do this whenever we have an FP result,
- // and an FP comparison in the SetCC node.
- SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(N.getOperand(0).Val);
- if (SetCC && N.getOperand(0).getOpcode() == ISD::SETCC &&
- !MVT::isInteger(SetCC->getOperand(0).getValueType()) &&
- SetCC->getCondition() != ISD::SETEQ &&
- SetCC->getCondition() != ISD::SETNE) {
- MVT::ValueType VT = SetCC->getOperand(0).getValueType();
- unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE
- unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE
-
- ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1));
- if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) {
- switch(SetCC->getCondition()) {
- default: assert(0 && "Invalid FSEL condition"); abort();
- case ISD::SETULT:
- case ISD::SETLT:
- std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
- case ISD::SETUGE:
- case ISD::SETGE:
- Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
- BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV);
- return Result;
- case ISD::SETUGT:
- case ISD::SETGT:
- std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
- case ISD::SETULE:
- case ISD::SETLE: {
- if (SetCC->getOperand(0).getOpcode() == ISD::FNEG) {
- Tmp2 = SelectExpr(SetCC->getOperand(0).getOperand(0));
- } else {
- Tmp2 = MakeReg(VT);
- Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
- BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1);
- }
- BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV);
- return Result;
- }
- }
- } else {
- Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS;
- Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
- Tmp2 = SelectExpr(SetCC->getOperand(1));
- Tmp3 = MakeReg(VT);
- switch(SetCC->getCondition()) {
- default: assert(0 && "Invalid FSEL condition"); abort();
- case ISD::SETULT:
- case ISD::SETLT:
- BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
- BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
- return Result;
- case ISD::SETUGE:
- case ISD::SETGE:
- BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
- BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
- return Result;
- case ISD::SETUGT:
- case ISD::SETGT:
- BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
- BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
- return Result;
- case ISD::SETULE:
- case ISD::SETLE:
- BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
- BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
- return Result;
- }
- }
- assert(0 && "Should never get here");
- return 0;
- }
-
- bool Inv;
- unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
- unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
- unsigned CCReg = SelectCC(N.getOperand(0), Opc, Inv, Tmp3);
-
- // Create an iterator with which to insert the MBB for copying the false
- // value and the MBB to hold the PHI instruction for this SetCC.
- MachineBasicBlock *thisMBB = BB;
- const BasicBlock *LLVM_BB = BB->getBasicBlock();
- ilist<MachineBasicBlock>::iterator It = BB;
- ++It;
-
- // thisMBB:
- // ...
- // TrueVal = ...
- // cmpTY ccX, r1, r2
- // bCC copy1MBB
- // fallthrough --> copy0MBB
- MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
- MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
- BuildMI(BB, Opc, 2).addReg(CCReg).addMBB(sinkMBB);
- MachineFunction *F = BB->getParent();
- F->getBasicBlockList().insert(It, copy0MBB);
- F->getBasicBlockList().insert(It, sinkMBB);
- // Update machine-CFG edges
- BB->addSuccessor(copy0MBB);
- BB->addSuccessor(sinkMBB);
-
- // copy0MBB:
- // %FalseValue = ...
- // # fallthrough to sinkMBB
- BB = copy0MBB;
- // Update machine-CFG edges
- BB->addSuccessor(sinkMBB);
-
- // sinkMBB:
- // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
- // ...
- BB = sinkMBB;
- BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
- .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
- return Result;
- }
-
- case ISD::FNEG:
- if (!NoExcessFPPrecision &&
- ISD::ADD == N.getOperand(0).getOpcode() &&
- N.getOperand(0).Val->hasOneUse() &&
- ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
- N.getOperand(0).getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
- Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
- } else if (!NoExcessFPPrecision &&
- ISD::ADD == N.getOperand(0).getOpcode() &&
- N.getOperand(0).Val->hasOneUse() &&
- ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() &&
- N.getOperand(0).getOperand(1).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(0).getOperand(0));
- Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
- } else if (ISD::FABS == N.getOperand(0).getOpcode()) {
- Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
- BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
- } else {
- Tmp1 = SelectExpr(N.getOperand(0));
- BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
- }
- return Result;
-
- case ISD::FABS:
- Tmp1 = SelectExpr(N.getOperand(0));
- BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
- return Result;
-
- case ISD::FP_ROUND:
- assert (DestType == MVT::f32 &&
- N.getOperand(0).getValueType() == MVT::f64 &&
- "only f64 to f32 conversion supported here");
- Tmp1 = SelectExpr(N.getOperand(0));
- BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1);
- return Result;
-
- case ISD::FP_EXTEND:
- assert (DestType == MVT::f64 &&
- N.getOperand(0).getValueType() == MVT::f32 &&
- "only f32 to f64 conversion supported here");
- Tmp1 = SelectExpr(N.getOperand(0));
- BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
- return Result;
-
- case ISD::CopyFromReg:
- if (Result == 1)
- Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
- Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
- BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
- return Result;
-
- case ISD::ConstantFP: {
- ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
- Result = getConstDouble(CN->getValue(), Result);
- return Result;
- }
-
- case ISD::ADD:
- if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
- N.getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(1));
- Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
- return Result;
- }
- if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL &&
- N.getOperand(1).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(0));
- Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
- return Result;
- }
- Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS;
- Tmp1 = SelectExpr(N.getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
- return Result;
-
- case ISD::SUB:
- if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
- N.getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(1));
- Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
- return Result;
- }
- if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL &&
- N.getOperand(1).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(0));
- Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
- return Result;
- }
- Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS;
- Tmp1 = SelectExpr(N.getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
- return Result;
-
- case ISD::MUL:
- case ISD::SDIV:
- switch( opcode ) {
- case ISD::MUL: Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break;
- case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break;
- };
- Tmp1 = SelectExpr(N.getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
- return Result;
-
- case ISD::UINT_TO_FP:
- case ISD::SINT_TO_FP: {
- assert (N.getOperand(0).getValueType() == MVT::i32
- && "int to float must operate on i32");
- bool IsUnsigned = (ISD::UINT_TO_FP == opcode);
- Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
- Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into
- Tmp3 = MakeReg(MVT::i32); // temp reg to hold the conversion constant
-
- int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
- MachineConstantPool *CP = BB->getParent()->getConstantPool();
-
- if (IsUnsigned) {
- unsigned ConstF = getConstDouble(0x1.000000p52);
- // Store the hi & low halves of the fp value, currently in int regs
- BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
- addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
- addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp1), FrameIdx, 4);
- addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
- // Generate the return value with a subtract
- BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
- } else {
- unsigned ConstF = getConstDouble(0x1.000008p52);
- unsigned TmpL = MakeReg(MVT::i32);
- // Store the hi & low halves of the fp value, currently in int regs
- BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
- addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
- BuildMI(BB, PPC::XORIS, 2, TmpL).addReg(Tmp1).addImm(0x8000);
- addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(TmpL), FrameIdx, 4);
- addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
- // Generate the return value with a subtract
- BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
- }
- return Result;
- }
- }
- assert(0 && "Should never get here");
- return 0;
-}
-
unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
unsigned Result;
unsigned Tmp1, Tmp2, Tmp3;
@@ -1620,14 +1316,6 @@
break;
}
- if (ISD::CopyFromReg == opcode)
- DestType = N.getValue(0).getValueType();
-
- if (DestType == MVT::f64 || DestType == MVT::f32)
- if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode &&
- ISD::UNDEF != opcode && ISD::CALL != opcode && ISD::TAILCALL != opcode)
- return SelectExprFP(N, Result);
-
switch (opcode) {
default:
Node->dump();
@@ -1843,10 +1531,14 @@
return Result;
case ISD::CopyFromReg:
+ DestType = N.getValue(0).getValueType();
if (Result == 1)
- Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
+ Result = ExprMap[N.getValue(0)] = MakeReg(DestType);
Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
- BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
+ if (MVT::isInteger(DestType))
+ BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
+ else
+ BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
return Result;
case ISD::SHL:
@@ -1890,7 +1582,33 @@
return Result;
case ISD::ADD:
- assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
+ if (!MVT::isInteger(DestType)) {
+ if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
+ N.getOperand(0).Val->hasOneUse()) {
+ ++FusedFP; // Statistic
+ Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(1));
+ Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+ return Result;
+ }
+ if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL &&
+ N.getOperand(1).Val->hasOneUse()) {
+ ++FusedFP; // Statistic
+ Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(0));
+ Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+ return Result;
+ }
+ Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS;
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
+ return Result;
+ }
Tmp1 = SelectExpr(N.getOperand(0));
switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
default: assert(0 && "unhandled result code");
@@ -1908,15 +1626,6 @@
return Result;
case ISD::AND:
- if (PPCCRopts) {
- if (N.getOperand(0).getOpcode() == ISD::SETCC ||
- N.getOperand(1).getOpcode() == ISD::SETCC) {
- bool Inv;
- Tmp1 = SelectCCExpr(N, Opc, Inv, Tmp2);
- MoveCRtoGPR(Tmp1, Inv, Tmp2, Result);
- return Result;
- }
- }
// FIXME: should add check in getImmediateForOpcode to return a value
// indicating the immediate is a run of set bits so we can emit a bitfield
// clear with RLWINM instead.
@@ -1977,15 +1686,6 @@
case ISD::OR:
if (SelectBitfieldInsert(N, Result))
return Result;
- if (PPCCRopts) {
- if (N.getOperand(0).getOpcode() == ISD::SETCC ||
- N.getOperand(1).getOpcode() == ISD::SETCC) {
- bool Inv;
- Tmp1 = SelectCCExpr(N, Opc, Inv, Tmp2);
- MoveCRtoGPR(Tmp1, Inv, Tmp2, Result);
- return Result;
- }
- }
Tmp1 = SelectExpr(N.getOperand(0));
switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
default: assert(0 && "unhandled result code");
@@ -2058,6 +1758,33 @@
}
case ISD::SUB:
+ if (!MVT::isInteger(DestType)) {
+ if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
+ N.getOperand(0).Val->hasOneUse()) {
+ ++FusedFP; // Statistic
+ Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(1));
+ Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS;
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+ return Result;
+ }
+ if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL &&
+ N.getOperand(1).Val->hasOneUse()) {
+ ++FusedFP; // Statistic
+ Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(0));
+ Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS;
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+ return Result;
+ }
+ Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS;
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
+ return Result;
+ }
if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1, true)) {
Tmp2 = SelectExpr(N.getOperand(1));
BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1);
@@ -2077,7 +1804,13 @@
BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
else {
Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
+ switch (DestType) {
+ default: assert(0 && "Unknown type to ISD::MUL"); break;
+ case MVT::i32: Opc = PPC::MULLW; break;
+ case MVT::f32: Opc = PPC::FMULS; break;
+ case MVT::f64: Opc = PPC::FMUL; break;
+ }
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
@@ -2115,10 +1848,15 @@
return SelectExpr(BuildSDIVSequence(N));
else
return SelectExpr(BuildUDIVSequence(N));
- }
+ }
Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1));
- Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW;
+ switch (DestType) {
+ default: assert(0 && "Unknown type to ISD::SDIV"); break;
+ case MVT::i32: Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break;
+ case MVT::f32: Opc = PPC::FDIVS; break;
+ case MVT::f64: Opc = PPC::FDIV; break;
+ }
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
@@ -2355,6 +2093,78 @@
return 0;
case ISD::SELECT: {
+ SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(N.getOperand(0).Val);
+ if (SetCC && N.getOperand(0).getOpcode() == ISD::SETCC &&
+ !MVT::isInteger(SetCC->getOperand(0).getValueType()) &&
+ !MVT::isInteger(N.getOperand(1).getValueType()) &&
+ !MVT::isInteger(N.getOperand(2).getValueType()) &&
+ SetCC->getCondition() != ISD::SETEQ &&
+ SetCC->getCondition() != ISD::SETNE) {
+ MVT::ValueType VT = SetCC->getOperand(0).getValueType();
+ unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE
+ unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE
+
+ ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1));
+ if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) {
+ switch(SetCC->getCondition()) {
+ default: assert(0 && "Invalid FSEL condition"); abort();
+ case ISD::SETULT:
+ case ISD::SETLT:
+ std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
+ case ISD::SETUGE:
+ case ISD::SETGE:
+ Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
+ BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV);
+ return Result;
+ case ISD::SETUGT:
+ case ISD::SETGT:
+ std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
+ case ISD::SETULE:
+ case ISD::SETLE: {
+ if (SetCC->getOperand(0).getOpcode() == ISD::FNEG) {
+ Tmp2 = SelectExpr(SetCC->getOperand(0).getOperand(0));
+ } else {
+ Tmp2 = MakeReg(VT);
+ Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
+ BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1);
+ }
+ BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV);
+ return Result;
+ }
+ }
+ } else {
+ Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS;
+ Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
+ Tmp2 = SelectExpr(SetCC->getOperand(1));
+ Tmp3 = MakeReg(VT);
+ switch(SetCC->getCondition()) {
+ default: assert(0 && "Invalid FSEL condition"); abort();
+ case ISD::SETULT:
+ case ISD::SETLT:
+ BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+ BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
+ return Result;
+ case ISD::SETUGE:
+ case ISD::SETGE:
+ BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+ BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
+ return Result;
+ case ISD::SETUGT:
+ case ISD::SETGT:
+ BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
+ BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
+ return Result;
+ case ISD::SETULE:
+ case ISD::SETLE:
+ BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
+ BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
+ return Result;
+ }
+ }
+ assert(0 && "Should never get here");
+ return 0;
+ }
+
bool Inv;
unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
@@ -2419,8 +2229,102 @@
}
}
return Result;
+
+ case ISD::ConstantFP: {
+ ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
+ Result = getConstDouble(CN->getValue(), Result);
+ return Result;
}
+ case ISD::FNEG:
+ if (!NoExcessFPPrecision &&
+ ISD::ADD == N.getOperand(0).getOpcode() &&
+ N.getOperand(0).Val->hasOneUse() &&
+ ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
+ N.getOperand(0).getOperand(0).Val->hasOneUse()) {
+ ++FusedFP; // Statistic
+ Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
+ Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+ } else if (!NoExcessFPPrecision &&
+ ISD::ADD == N.getOperand(0).getOpcode() &&
+ N.getOperand(0).Val->hasOneUse() &&
+ ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() &&
+ N.getOperand(0).getOperand(1).Val->hasOneUse()) {
+ ++FusedFP; // Statistic
+ Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(0).getOperand(0));
+ Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+ } else if (ISD::FABS == N.getOperand(0).getOpcode()) {
+ Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
+ BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
+ }
+ return Result;
+
+ case ISD::FABS:
+ Tmp1 = SelectExpr(N.getOperand(0));
+ BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
+ return Result;
+
+ case ISD::FP_ROUND:
+ assert (DestType == MVT::f32 &&
+ N.getOperand(0).getValueType() == MVT::f64 &&
+ "only f64 to f32 conversion supported here");
+ Tmp1 = SelectExpr(N.getOperand(0));
+ BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1);
+ return Result;
+
+ case ISD::FP_EXTEND:
+ assert (DestType == MVT::f64 &&
+ N.getOperand(0).getValueType() == MVT::f32 &&
+ "only f32 to f64 conversion supported here");
+ Tmp1 = SelectExpr(N.getOperand(0));
+ BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
+ return Result;
+
+ case ISD::UINT_TO_FP:
+ case ISD::SINT_TO_FP: {
+ assert (N.getOperand(0).getValueType() == MVT::i32
+ && "int to float must operate on i32");
+ bool IsUnsigned = (ISD::UINT_TO_FP == opcode);
+ Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
+ Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into
+ Tmp3 = MakeReg(MVT::i32); // temp reg to hold the conversion constant
+
+ int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
+ MachineConstantPool *CP = BB->getParent()->getConstantPool();
+
+ if (IsUnsigned) {
+ unsigned ConstF = getConstDouble(0x1.000000p52);
+ // Store the hi & low halves of the fp value, currently in int regs
+ BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
+ addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
+ addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp1), FrameIdx, 4);
+ addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
+ // Generate the return value with a subtract
+ BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
+ } else {
+ unsigned ConstF = getConstDouble(0x1.000008p52);
+ unsigned TmpL = MakeReg(MVT::i32);
+ // Store the hi & low halves of the fp value, currently in int regs
+ BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
+ addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
+ BuildMI(BB, PPC::XORIS, 2, TmpL).addReg(Tmp1).addImm(0x8000);
+ addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(TmpL), FrameIdx, 4);
+ addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
+ // Generate the return value with a subtract
+ BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
+ }
+ return Result;
+ }
+ }
return 0;
}
Index: llvm/lib/Target/PowerPC/PowerPC.h
diff -u llvm/lib/Target/PowerPC/PowerPC.h:1.15 llvm/lib/Target/PowerPC/PowerPC.h:1.16
--- llvm/lib/Target/PowerPC/PowerPC.h:1.15 Thu Apr 21 18:20:02 2005
+++ llvm/lib/Target/PowerPC/PowerPC.h Tue Jul 19 11:51:05 2005
@@ -28,8 +28,6 @@
FunctionPass *createPPC64ISelPattern(TargetMachine &TM);
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM);
FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM);
-
-extern bool PPCCRopts;
} // end namespace llvm;
// GCC #defines PPC on Linux but we use it as our namespace name
Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp
diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.52 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.53
--- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.52 Fri Jun 24 21:48:37 2005
+++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Tue Jul 19 11:51:05 2005
@@ -30,18 +30,12 @@
using namespace llvm;
namespace llvm {
- bool PPCCRopts;
cl::opt<bool> AIX("aix",
cl::desc("Generate AIX/xcoff instead of Darwin/MachO"),
cl::Hidden);
cl::opt<bool> EnablePPCLSR("enable-lsr-for-ppc",
cl::desc("Enable LSR for PPC (beta)"),
cl::Hidden);
- cl::opt<bool, true> EnablePPCCRopts("enable-cc-opts",
- cl::desc("Enable opts using condition regs (beta)"),
- cl::location(PPCCRopts),
- cl::init(false),
- cl::Hidden);
}
namespace {
More information about the llvm-commits
mailing list