aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/X86ISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86ISelDAGToDAG.cpp')
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp62
1 files changed, 37 insertions, 25 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 5ea12aa..6195676 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1258,39 +1258,51 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
return NULL;
}
-
+
case ISD::TRUNCATE: {
- if (!Subtarget->is64Bit() && NVT == MVT::i8) {
- unsigned Opc2;
- MVT::ValueType VT;
- switch (Node->getOperand(0).getValueType()) {
- default: assert(0 && "Unknown truncate!");
- case MVT::i16:
- Opc = X86::MOV16to16_;
- VT = MVT::i16;
- Opc2 = X86::TRUNC_16_to8;
- break;
- case MVT::i32:
- Opc = X86::MOV32to32_;
- VT = MVT::i32;
- Opc2 = X86::TRUNC_32_to8;
- break;
+ SDOperand Tmp;
+ SDOperand Input = Node->getOperand(0);
+ AddToISelQueue(Node->getOperand(0));
+ switch (NVT) {
+ case MVT::i8:
+ Tmp = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+ // Ensure that the source register has an 8-bit subreg on 32-bit targets
+ if (!Subtarget->is64Bit()) {
+ unsigned Opc;
+ MVT::ValueType VT;
+ switch (Node->getOperand(0).getValueType()) {
+ default: assert(0 && "Unknown truncate!");
+ case MVT::i16:
+ Opc = X86::MOV16to16_;
+ VT = MVT::i16;
+ break;
+ case MVT::i32:
+ Opc = X86::MOV32to32_;
+ VT = MVT::i32;
+ break;
+ }
+ Input =
+ SDOperand(CurDAG->getTargetNode(Opc, VT, Node->getOperand(0)), 0);
}
-
- AddToISelQueue(Node->getOperand(0));
- SDOperand Tmp =
- SDOperand(CurDAG->getTargetNode(Opc, VT, Node->getOperand(0)), 0);
- SDNode *ResNode = CurDAG->getTargetNode(Opc2, NVT, Tmp);
-
+ break;
+ case MVT::i16:
+ Tmp = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+ break;
+ case MVT::i32:
+ Tmp = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+ break;
+ default: assert(0 && "Unknown truncate!");
+ }
+ SDNode *ResNode = CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
+ NVT,
+ Input, Tmp);
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "=> ";
DEBUG(ResNode->dump(CurDAG));
DOUT << "\n";
Indent -= 2;
#endif
- return ResNode;
- }
-
+ return ResNode;
break;
}
}