aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp10
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp22
-rw-r--r--lib/Target/X86/X86ISelLowering.h8
3 files changed, 39 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index c5b7bf9f54..dae6af4f56 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1325,6 +1325,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
Tmp2, Tmp3, ISD::SETNE);
}
break;
+ case TargetLowering::Custom: {
+ SDOperand Tmp =
+ TLI.LowerOperation(DAG.getNode(ISD::SELECT, Node->getValueType(0),
+ Tmp1, Tmp2, Tmp3), DAG);
+ if (Tmp.Val) {
+ Result = LegalizeOp(Tmp);
+ break;
+ }
+ // FALLTHROUGH if the target thinks it is legal.
+ }
case TargetLowering::Legal:
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
Tmp3 != Node->getOperand(2))
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 292f00af37..1facdd35cf 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -113,6 +113,11 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
// These should be promoted to a larger select which is supported.
setOperationAction(ISD::SELECT , MVT::i1 , Promote);
setOperationAction(ISD::SELECT , MVT::i8 , Promote);
+ // X86 wants to expand cmov itself.
+ if (X86DAGIsel) {
+ setOperationAction(ISD::SELECT , MVT::i16 , Custom);
+ setOperationAction(ISD::SELECT , MVT::i32 , Custom);
+ }
// We don't have line number support yet.
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
@@ -930,5 +935,22 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
Tys.push_back(MVT::Other);
return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
}
+ case ISD::SELECT: {
+ unsigned Opc;
+ SDOperand Cond = Op.getOperand(0);
+ SDOperand True = Op.getOperand(1);
+ SDOperand False = Op.getOperand(2);
+ SDOperand CC;
+ if (Cond.getOpcode() == ISD::SETCC) {
+ CC = Cond.getOperand(2);
+ Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
+ Cond.getOperand(0), Cond.getOperand(1));
+ } else {
+ CC = DAG.getCondCode(ISD::SETEQ);
+ Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond);
+ }
+ return DAG.getNode(X86ISD::CMOV, Op.getValueType(),
+ Op.getOperand(1), Op.getOperand(2), CC, Cond);
+ }
}
}
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index ccec6ea23f..26cc7d5ec6 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -23,7 +23,7 @@ namespace llvm {
namespace X86ISD {
enum NodeType {
// Start the numbering where the builtin ops leave off.
- FIRST_NUMBER = ISD::BUILTIN_OP_END,
+ FIRST_NUMBER = ISD::BUILTIN_OP_END+X86::INSTRUCTION_LIST_END,
/// FILD64m - This instruction implements SINT_TO_FP with a
/// 64-bit source in memory and a FP reg result. This corresponds to
@@ -66,6 +66,12 @@ namespace llvm {
/// RDTSC_DAG - This operation implements the lowering for
/// readcyclecounter
RDTSC_DAG,
+
+ /// X86 compare and logical compare instructions.
+ CMP, TEST,
+
+ /// X86 conditional moves.
+ CMOV,
};
}