aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorChristopher Lamb <christopher.lamb@gmail.com>2007-07-29 01:24:57 +0000
committerChristopher Lamb <christopher.lamb@gmail.com>2007-07-29 01:24:57 +0000
commit444336cb6ba3c1fcfef3438898b5a1edeef29ed4 (patch)
tree0ca7d8243585fccef5439a69d56b6a94d8fee754 /lib/Target
parent8e47beb42eab28a4f7ed1db13f2574129eeffae8 (diff)
downloadexternal_llvm-444336cb6ba3c1fcfef3438898b5a1edeef29ed4.zip
external_llvm-444336cb6ba3c1fcfef3438898b5a1edeef29ed4.tar.gz
external_llvm-444336cb6ba3c1fcfef3438898b5a1edeef29ed4.tar.bz2
Change the x86 backend to use extract_subreg for truncation operations. Passes DejaGnu, SingleSource and MultiSource.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/X86/X86ATTAsmPrinter.cpp23
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp12
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp62
-rw-r--r--lib/Target/X86/X86InstrInfo.td8
-rw-r--r--lib/Target/X86/X86InstrX86-64.td22
-rw-r--r--lib/Target/X86/X86IntelAsmPrinter.cpp23
6 files changed, 37 insertions, 113 deletions
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp
index 4c707df..f2f640a 100644
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp
@@ -580,29 +580,6 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
// See if a truncate instruction can be turned into a nop.
switch (MI->getOpcode()) {
default: break;
- case X86::TRUNC_64to32:
- case X86::TRUNC_64to16:
- case X86::TRUNC_32to16:
- case X86::TRUNC_32to8:
- case X86::TRUNC_16to8:
- case X86::TRUNC_32_to8:
- case X86::TRUNC_16_to8: {
- const MachineOperand &MO0 = MI->getOperand(0);
- const MachineOperand &MO1 = MI->getOperand(1);
- unsigned Reg0 = MO0.getReg();
- unsigned Reg1 = MO1.getReg();
- unsigned Opc = MI->getOpcode();
- if (Opc == X86::TRUNC_64to32)
- Reg1 = getX86SubSuperRegister(Reg1, MVT::i32);
- else if (Opc == X86::TRUNC_32to16 || Opc == X86::TRUNC_64to16)
- Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
- else
- Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
- O << TAI->getCommentString() << " TRUNCATE ";
- if (Reg0 != Reg1)
- O << "\n\t";
- break;
- }
case X86::PsMOVZX64rr32:
O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
break;
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 9d51804..0a7beb2 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -448,12 +448,6 @@ bool Emitter::isX86_64ExtendedReg(const MachineOperand &MO) {
return false;
}
-inline static bool isX86_64TruncToByte(unsigned oc) {
- return (oc == X86::TRUNC_64to8 || oc == X86::TRUNC_32to8 ||
- oc == X86::TRUNC_16to8);
-}
-
-
inline static bool isX86_64NonExtLowByteReg(unsigned reg) {
return (reg == X86::SPL || reg == X86::BPL ||
reg == X86::SIL || reg == X86::DIL);
@@ -465,7 +459,6 @@ inline static bool isX86_64NonExtLowByteReg(unsigned reg) {
unsigned Emitter::determineREX(const MachineInstr &MI) {
unsigned REX = 0;
const TargetInstrDescriptor *Desc = MI.getInstrDescriptor();
- unsigned Opcode = Desc->Opcode;
// Pseudo instructions do not need REX prefix byte.
if ((Desc->TSFlags & X86II::FormMask) == X86II::Pseudo)
@@ -479,16 +472,11 @@ unsigned Emitter::determineREX(const MachineInstr &MI) {
Desc->getOperandConstraint(1, TOI::TIED_TO) != -1;
// If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
- bool isTrunc8 = isX86_64TruncToByte(Opcode);
unsigned i = isTwoAddr ? 1 : 0;
for (unsigned e = NumOps; i != e; ++i) {
const MachineOperand& MO = MI.getOperand(i);
if (MO.isRegister()) {
unsigned Reg = MO.getReg();
- // Trunc to byte are actually movb. The real source operand is the low
- // byte of the register.
- if (isTrunc8 && i == 1)
- Reg = getX86SubSuperRegister(Reg, MVT::i8);
if (isX86_64NonExtLowByteReg(Reg))
REX |= 0x40;
}
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;
}
}
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 906e7b2..0f5a1dc 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -388,14 +388,6 @@ def IMPLICIT_DEF_GR32 : I<0, Pseudo, (outs GR32:$dst), (ins),
// Nop
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
-// Truncate
-def TRUNC_32_to8 : I<0x88, MRMDestReg, (outs GR8:$dst), (ins GR32_:$src),
- "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}", []>;
-def TRUNC_16_to8 : I<0x88, MRMDestReg, (outs GR8:$dst), (ins GR16_:$src),
- "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}}", []>;
-def TRUNC_32to16 : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR32:$src),
- "mov{w} {${src:subreg16}, $dst|$dst, ${src:subreg16}}",
- [(set GR16:$dst, (trunc GR32:$src))]>;
//===----------------------------------------------------------------------===//
// Control Flow Instructions...
diff --git a/lib/Target/X86/X86InstrX86-64.td b/lib/Target/X86/X86InstrX86-64.td
index 16930b4..ec0f470 100644
--- a/lib/Target/X86/X86InstrX86-64.td
+++ b/lib/Target/X86/X86InstrX86-64.td
@@ -1005,28 +1005,6 @@ let isTwoAddress = 1 in {
// Alias Instructions
//===----------------------------------------------------------------------===//
-// Truncate
-// In 64-mode, each 64-bit and 32-bit registers has a low 8-bit sub-register.
-def TRUNC_64to8 : I<0x88, MRMDestReg, (outs GR8:$dst), (ins GR64:$src),
- "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}",
- [(set GR8:$dst, (trunc GR64:$src))]>;
-def TRUNC_32to8 : I<0x88, MRMDestReg, (outs GR8:$dst), (ins GR32:$src),
- "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}",
- [(set GR8:$dst, (trunc GR32:$src))]>,
- Requires<[In64BitMode]>;
-def TRUNC_16to8 : I<0x88, MRMDestReg, (outs GR8:$dst), (ins GR16:$src),
- "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}}",
- [(set GR8:$dst, (trunc GR16:$src))]>,
- Requires<[In64BitMode]>;
-
-def TRUNC_64to16 : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR64:$src),
- "mov{w} {${src:subreg16}, $dst|$dst, ${src:subreg16}}",
- [(set GR16:$dst, (trunc GR64:$src))]>;
-
-def TRUNC_64to32 : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR64:$src),
- "mov{l} {${src:subreg32}, $dst|$dst, ${src:subreg32}}",
- [(set GR32:$dst, (trunc GR64:$src))]>;
-
// Zero-extension
// TODO: Remove this after proper i32 -> i64 zext support.
def PsMOVZX64rr32: I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp
index 60d7ed6..72ba1b0 100644
--- a/lib/Target/X86/X86IntelAsmPrinter.cpp
+++ b/lib/Target/X86/X86IntelAsmPrinter.cpp
@@ -306,29 +306,6 @@ void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
// See if a truncate instruction can be turned into a nop.
switch (MI->getOpcode()) {
default: break;
- case X86::TRUNC_64to32:
- case X86::TRUNC_64to16:
- case X86::TRUNC_32to16:
- case X86::TRUNC_32to8:
- case X86::TRUNC_16to8:
- case X86::TRUNC_32_to8:
- case X86::TRUNC_16_to8: {
- const MachineOperand &MO0 = MI->getOperand(0);
- const MachineOperand &MO1 = MI->getOperand(1);
- unsigned Reg0 = MO0.getReg();
- unsigned Reg1 = MO1.getReg();
- unsigned Opc = MI->getOpcode();
- if (Opc == X86::TRUNC_64to32)
- Reg1 = getX86SubSuperRegister(Reg1, MVT::i32);
- else if (Opc == X86::TRUNC_32to16 || Opc == X86::TRUNC_64to16)
- Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
- else
- Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
- O << TAI->getCommentString() << " TRUNCATE ";
- if (Reg0 != Reg1)
- O << "\n\t";
- break;
- }
case X86::PsMOVZX64rr32:
O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
break;