aboutsummaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/Target.td12
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp13
-rw-r--r--lib/Target/X86/X86InstrInfo.h8
-rw-r--r--lib/Target/X86/X86InstrInfo.td4
-rw-r--r--lib/Target/X86/X86RegisterInfo.h9
-rw-r--r--lib/Target/X86/X86RegisterInfo.td4
6 files changed, 42 insertions, 8 deletions
diff --git a/lib/Target/Target.td b/lib/Target/Target.td
index cebac7a263..ea8f6ec3a1 100644
--- a/lib/Target/Target.td
+++ b/lib/Target/Target.td
@@ -263,6 +263,10 @@ def variable_ops;
/// flags. But currently we have but one flag.
def ptr_rc;
+/// unknown definition - Mark this operand as being of unknown type, causing
+/// it to be resolved by inference in the context it is used.
+def unknown;
+
/// Operand Types - These provide the built-in operand types that may be used
/// by a target. Targets can optionally provide their own operand types as
/// needed, though this should not be needed for RISC targets.
@@ -351,15 +355,15 @@ def DECLARE : Instruction {
let hasCtrlDep = 1;
}
def EXTRACT_SUBREG : Instruction {
- let OutOperandList = (ops variable_ops);
- let InOperandList = (ops variable_ops);
+ let OutOperandList = (ops unknown:$dst);
+ let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetInstrInfo";
let neverHasSideEffects = 1;
}
def INSERT_SUBREG : Instruction {
- let OutOperandList = (ops variable_ops);
- let InOperandList = (ops variable_ops);
+ let OutOperandList = (ops unknown:$dst);
+ let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetInstrInfo";
let neverHasSideEffects = 1;
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index ea1bed19ce..d5601b74ea 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1533,22 +1533,27 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
AddToISelQueue(N0);
if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
SDOperand SRIdx;
+ SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF,
+ MVT::i32);
switch(N0.getValueType()) {
case MVT::i32:
- SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+ SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
+ // x86-64 zero extends 32-bit inserts int 64-bit registers
+ if (Subtarget->is64Bit())
+ ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32);
break;
case MVT::i16:
- SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+ SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
break;
case MVT::i8:
if (Subtarget->is64Bit())
- SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+ SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
break;
default: assert(0 && "Unknown any_extend!");
}
if (SRIdx.Val) {
SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
- NVT, N0, SRIdx);
+ NVT, ImplVal, N0, SRIdx);
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "=> ";
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index 839a0f248b..e0d0342ae6 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -46,6 +46,14 @@ namespace X86 {
COND_INVALID
};
+ // X86 specific implict values used for subregister inserts.
+ // This can be used to model the fact that x86-64 by default
+ // inserts 32-bit values into 64-bit registers implicitly containing zeros.
+ enum ImplicitVal {
+ IMPL_VAL_UNDEF = 0,
+ IMPL_VAL_ZERO = 1
+ };
+
// Turn condition code into conditional branch opcode.
unsigned GetCondBranchFromCond(CondCode CC);
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index e32fb9c4b5..4d03dba32d 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -161,6 +161,10 @@ def i32i8imm : Operand<i32>;
// Branch targets have OtherVT type.
def brtarget : Operand<OtherVT>;
+// These should match the enum X86::ImplicitVal
+def x86_impl_val_undef : PatLeaf<(i32 0)>;
+def x86_impl_val_zero : PatLeaf<(i32 1)>;
+
//===----------------------------------------------------------------------===//
// X86 Complex Pattern Definitions.
//
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index 8b010a9240..1c8f5e28b9 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -32,6 +32,15 @@ namespace N86 {
};
}
+namespace X86 {
+ /// SubregIndex - The index of various sized subregister classes. Note that
+ /// these indices must be kept in sync with the class indices in the
+ /// X86RegisterInfo.td file.
+ enum SubregIndex {
+ SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3
+ };
+}
+
/// DWARFFlavour - Flavour of dwarf regnumbers
///
namespace DWARFFlavour {
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index 24402386c8..b713c892ba 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -176,6 +176,10 @@ let Namespace = "X86" in {
// sub registers for each register.
//
+def x86_subreg_8bit : PatLeaf<(i32 1)>;
+def x86_subreg_16bit : PatLeaf<(i32 2)>;
+def x86_subreg_32bit : PatLeaf<(i32 3)>;
+
def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI,
R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
[AL, CL, DL, BL, SPL, BPL, SIL, DIL,