mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Make fsel emission work with both the pattern and dag-dag selectors, by
giving it a non-instruction opcode. The dag->dag selector used to not select the operands of the fsel, because it thought that whole tree was already selected. llvm-svn: 23091
This commit is contained in:
parent
17f0f9beae
commit
04b88ca768
@ -811,7 +811,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
default:
|
default:
|
||||||
Node->dump(); std::cerr << '\n';
|
Node->dump(); std::cerr << '\n';
|
||||||
assert(0 && "Node not handled!\n");
|
assert(0 && "Node not handled!\n");
|
||||||
case ISD::BUILTIN_OP_END+PPC::FSEL:
|
case PPCISD::FSEL:
|
||||||
Tmp1 = SelectExpr(N.getOperand(0));
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
Tmp2 = SelectExpr(N.getOperand(1));
|
Tmp2 = SelectExpr(N.getOperand(1));
|
||||||
Tmp3 = SelectExpr(N.getOperand(2));
|
Tmp3 = SelectExpr(N.getOperand(2));
|
||||||
|
@ -629,7 +629,8 @@ SDOperand PPC32DAGToDAGISel::BuildUDIVSequence(SDNode *N) {
|
|||||||
// target-specific node if it hasn't already been changed.
|
// target-specific node if it hasn't already been changed.
|
||||||
SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
if (N->getOpcode() >= ISD::BUILTIN_OP_END)
|
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
||||||
|
N->getOpcode() < PPCISD::FIRST_NUMBER)
|
||||||
return Op; // Already selected.
|
return Op; // Already selected.
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
@ -747,6 +748,12 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
assert(N->getValueType(0) == MVT::i32);
|
assert(N->getValueType(0) == MVT::i32);
|
||||||
CurDAG->SelectNodeTo(N, PPC::CNTLZW, MVT::i32, Select(N->getOperand(0)));
|
CurDAG->SelectNodeTo(N, PPC::CNTLZW, MVT::i32, Select(N->getOperand(0)));
|
||||||
break;
|
break;
|
||||||
|
case PPCISD::FSEL:
|
||||||
|
CurDAG->SelectNodeTo(N, PPC::FSEL, N->getValueType(0),
|
||||||
|
Select(N->getOperand(0)),
|
||||||
|
Select(N->getOperand(1)),
|
||||||
|
Select(N->getOperand(2)));
|
||||||
|
break;
|
||||||
case ISD::ADD: {
|
case ISD::ADD: {
|
||||||
MVT::ValueType Ty = N->getValueType(0);
|
MVT::ValueType Ty = N->getValueType(0);
|
||||||
if (Ty == MVT::i32) {
|
if (Ty == MVT::i32) {
|
||||||
|
@ -125,34 +125,34 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
|
std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
|
||||||
case ISD::SETUGE:
|
case ISD::SETUGE:
|
||||||
case ISD::SETGE:
|
case ISD::SETGE:
|
||||||
return DAG.getTargetNode(PPC::FSEL, ResVT, LHS, TV, FV);
|
return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV);
|
||||||
case ISD::SETUGT:
|
case ISD::SETUGT:
|
||||||
case ISD::SETGT:
|
case ISD::SETGT:
|
||||||
std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
|
std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
|
||||||
case ISD::SETULE:
|
case ISD::SETULE:
|
||||||
case ISD::SETLE:
|
case ISD::SETLE:
|
||||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
return DAG.getNode(PPCISD::FSEL, ResVT,
|
||||||
DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV);
|
DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (CC) {
|
switch (CC) {
|
||||||
default: assert(0 && "Invalid FSEL condition"); abort();
|
default: assert(0 && "Invalid FSEL condition"); abort();
|
||||||
case ISD::SETULT:
|
case ISD::SETULT:
|
||||||
case ISD::SETLT:
|
case ISD::SETLT:
|
||||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
return DAG.getNode(PPCISD::FSEL, ResVT,
|
||||||
DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV,TV);
|
DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV);
|
||||||
case ISD::SETUGE:
|
case ISD::SETUGE:
|
||||||
case ISD::SETGE:
|
case ISD::SETGE:
|
||||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
return DAG.getNode(PPCISD::FSEL, ResVT,
|
||||||
DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV,FV);
|
DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV);
|
||||||
case ISD::SETUGT:
|
case ISD::SETUGT:
|
||||||
case ISD::SETGT:
|
case ISD::SETGT:
|
||||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
return DAG.getNode(PPCISD::FSEL, ResVT,
|
||||||
DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV,TV);
|
DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV);
|
||||||
case ISD::SETULE:
|
case ISD::SETULE:
|
||||||
case ISD::SETLE:
|
case ISD::SETLE:
|
||||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
return DAG.getNode(PPCISD::FSEL, ResVT,
|
||||||
DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV,FV);
|
DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===-- PPC32ISelLowering.cpp - PPC32 DAG Lowering Impl. --------*- C++ -*-===//
|
//===-- PPC32ISelLowering.h - PPC32 DAG Lowering Interface ------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@ -16,8 +16,21 @@
|
|||||||
#define LLVM_TARGET_POWERPC_PPC32ISELLOWERING_H
|
#define LLVM_TARGET_POWERPC_PPC32ISELLOWERING_H
|
||||||
|
|
||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
|
#include "PowerPC.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
namespace PPCISD {
|
||||||
|
enum NodeType {
|
||||||
|
// Start the numbering where the builting ops and target ops leave off.
|
||||||
|
FIRST_NUMBER = ISD::BUILTIN_OP_END+PPC::INSTRUCTION_LIST_END,
|
||||||
|
|
||||||
|
/// FSEL - Traditional three-operand fsel node.
|
||||||
|
///
|
||||||
|
FSEL,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class PPC32TargetLowering : public TargetLowering {
|
class PPC32TargetLowering : public TargetLowering {
|
||||||
int VarArgsFrameIndex; // FrameIndex for start of varargs area.
|
int VarArgsFrameIndex; // FrameIndex for start of varargs area.
|
||||||
int ReturnAddrIndex; // FrameIndex for return slot.
|
int ReturnAddrIndex; // FrameIndex for return slot.
|
||||||
|
Loading…
Reference in New Issue
Block a user