mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-17 07:22:54 +00:00
add initial support for converting select_cc -> fsel in the legalizer
instead of in the backend. This currently handles fsel cases with registers, but doesn't have the 0.0 and -0.0 optimization enabled yet. Once this is finished, special hack for fp immediates can go away. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23075 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d7050a9c50
commit
e4bc9ea0a5
@ -17,8 +17,15 @@
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
cl::opt<bool> FSELTMP("ppc-fsel-custom-legalizer", cl::Hidden,
|
||||
cl::desc("Use a custom expander for fsel on ppc"));
|
||||
}
|
||||
|
||||
|
||||
PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
|
||||
: TargetLowering(TM) {
|
||||
|
||||
@ -66,6 +73,12 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::SELECT, MVT::f32, Expand);
|
||||
setOperationAction(ISD::SELECT, MVT::f64, Expand);
|
||||
|
||||
// PowerPC wants to turn select_cc of FP into fsel.
|
||||
if (FSELTMP) {
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
||||
}
|
||||
|
||||
// PowerPC does not have BRCOND* which requires SetCC
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
|
||||
@ -78,12 +91,54 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
|
||||
|
||||
setSetCCResultContents(ZeroOrOneSetCCResult);
|
||||
if (!FSELTMP) {
|
||||
addLegalFPImmediate(+0.0); // Necessary for FSEL
|
||||
addLegalFPImmediate(-0.0); //
|
||||
}
|
||||
|
||||
computeRegisterProperties();
|
||||
}
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
switch (Op.getOpcode()) {
|
||||
default: assert(0 && "Wasn't expecting to be able to lower this!");
|
||||
case ISD::SELECT_CC:
|
||||
// Turn FP only select_cc's into fsel instructions.
|
||||
if (MVT::isFloatingPoint(Op.getOperand(0).getValueType()) &&
|
||||
MVT::isFloatingPoint(Op.getOperand(2).getValueType())) {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
|
||||
MVT::ValueType ResVT = Op.getValueType();
|
||||
MVT::ValueType CmpVT = Op.getOperand(0).getValueType();
|
||||
SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1);
|
||||
SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3);
|
||||
|
||||
switch (CC) {
|
||||
default: assert(0 && "Invalid FSEL condition"); abort();
|
||||
case ISD::SETULT:
|
||||
case ISD::SETLT:
|
||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
||||
DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV,TV);
|
||||
case ISD::SETUGE:
|
||||
case ISD::SETGE:
|
||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
||||
DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV,FV);
|
||||
case ISD::SETUGT:
|
||||
case ISD::SETGT:
|
||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
||||
DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV,TV);
|
||||
case ISD::SETULE:
|
||||
case ISD::SETLE:
|
||||
return DAG.getTargetNode(PPC::FSEL, ResVT,
|
||||
DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV,FV);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
std::vector<SDOperand>
|
||||
PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
||||
//
|
||||
|
@ -24,6 +24,10 @@ namespace llvm {
|
||||
public:
|
||||
PPC32TargetLowering(TargetMachine &TM);
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||
|
||||
/// LowerArguments - This hook must be implemented to indicate how we should
|
||||
/// lower the arguments for the specified function, into the specified DAG.
|
||||
virtual std::vector<SDOperand>
|
||||
|
@ -829,6 +829,12 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
default:
|
||||
Node->dump(); std::cerr << '\n';
|
||||
assert(0 && "Node not handled!\n");
|
||||
case ISD::BUILTIN_OP_END+PPC::FSEL:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 = SelectExpr(N.getOperand(1));
|
||||
Tmp3 = SelectExpr(N.getOperand(2));
|
||||
BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
|
||||
return Result;
|
||||
case ISD::UNDEF:
|
||||
if (Node->getValueType(0) == MVT::i32)
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result);
|
||||
|
Loading…
x
Reference in New Issue
Block a user