aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib/Target/X86/X86ATTAsmPrinter.cpp13
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp38
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp1
-rw-r--r--lib/Target/X86/X86InstrInfo.td32
-rwxr-xr-xlib/Target/X86/X86IntelAsmPrinter.cpp13
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp24
-rw-r--r--lib/Target/X86/X86RegisterInfo.td4
7 files changed, 100 insertions, 25 deletions
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp
index 326251ccc2..7baa8f8717 100755
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp
@@ -115,7 +115,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
unsigned Reg = MO.getReg();
if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) {
MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0)
- ? MVT::i16 : MVT::i32;
+ ? MVT::i16 : MVT::i8;
Reg = getX86SubSuperRegister(Reg, VT);
}
for (const char *Name = RI.get(Reg).Name; *Name; ++Name)
@@ -366,12 +366,13 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
const MachineOperand &MO1 = MI->getOperand(1);
unsigned Reg0 = MO0.getReg();
unsigned Reg1 = MO1.getReg();
- if (MI->getOpcode() == X86::TRUNC_R16_R8)
- Reg0 = getX86SubSuperRegister(Reg0, MVT::i16);
+ if (MI->getOpcode() == X86::TRUNC_R32_R16)
+ Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
else
- Reg0 = getX86SubSuperRegister(Reg0, MVT::i32);
- if (Reg0 == Reg1)
- O << CommentString << " TRUNCATE ";
+ Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
+ O << CommentString << " TRUNCATE ";
+ if (Reg0 != Reg1)
+ O << "\n\t";
break;
}
}
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index c0c9704c04..20534beb75 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -791,6 +791,44 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
#endif
return;
}
+
+ case ISD::TRUNCATE: {
+ if (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_R16_R8;
+ break;
+ case MVT::i32:
+ Opc = X86::MOV32to32_;
+ VT = MVT::i32;
+ if (NVT == MVT::i16)
+ Opc2 = X86::TRUNC_R32_R16;
+ else
+ Opc2 = X86::TRUNC_R32_R8;
+ break;
+ }
+
+ SDOperand Tmp0, Tmp1;
+ Select(Tmp0, Node->getOperand(0));
+ Tmp1 = SDOperand(CurDAG->getTargetNode(Opc, VT, Tmp0), 0);
+ Result = CodeGenMap[N] =
+ SDOperand(CurDAG->getTargetNode(Opc2, NVT, Tmp1), 0);
+
+#ifndef NDEBUG
+ DEBUG(std::cerr << std::string(Indent-2, ' '));
+ DEBUG(std::cerr << "== ");
+ DEBUG(Result.Val->dump(CurDAG));
+ DEBUG(std::cerr << "\n");
+ Indent -= 2;
+#endif
+ return;
+ }
+ }
}
SelectCode(Result, N);
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 31a4f6fe2e..cc30bfe063 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -28,6 +28,7 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
unsigned& destReg) const {
MachineOpCode oc = MI.getOpcode();
if (oc == X86::MOV8rr || oc == X86::MOV16rr || oc == X86::MOV32rr ||
+ oc == X86::MOV16to16_ || oc == X86::MOV32to32_ ||
oc == X86::FpMOV || oc == X86::MOVSSrr || oc == X86::MOVSDrr ||
oc == X86::FsMOVAPSrr || oc == X86::FsMOVAPDrr ||
oc == X86::MOVAPSrr || oc == X86::MOVAPDrr ||
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 73baba9a57..6729e7db7b 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -357,15 +357,13 @@ def IMPLICIT_DEF_R32 : I<0, Pseudo, (ops R32:$dst),
def NOOP : I<0x90, RawFrm, (ops), "nop", []>;
// Truncate
-def TRUNC_R32_R8 : I<0x89, MRMDestReg, (ops R8:$dst, R32:$src),
- "mov{l} {$src, ${dst:trunc32}|${dst:trunc32}, $src}",
- [(set R8:$dst, (trunc R32:$src))]>;
+def TRUNC_R32_R8 : I<0x88, MRMDestReg, (ops R8:$dst, R32_:$src),
+ "mov{b} {${src:trunc8}, $dst|$dst, ${src:trunc8}", []>;
+def TRUNC_R16_R8 : I<0x88, MRMDestReg, (ops R8:$dst, R16_:$src),
+ "mov{b} {${src:trunc8}, $dst|$dst, ${src:trunc8}}", []>;
def TRUNC_R32_R16 : I<0x89, MRMDestReg, (ops R16:$dst, R32:$src),
- "mov{l} {$src, ${dst:trunc32}|${dst:trunc32}, $src}",
+ "mov{w} {${src:trunc16}, $dst|$dst, ${src:trunc16}}",
[(set R16:$dst, (trunc R32:$src))]>;
-def TRUNC_R16_R8 : I<0x89, MRMDestReg, (ops R8:$dst, R16:$src),
- "mov{w} {$src, ${dst:trunc16}|${dst:trunc16}, $src}",
- [(set R8:$dst, (trunc R16:$src))]>;
//===----------------------------------------------------------------------===//
// Control Flow Instructions...
@@ -2310,6 +2308,26 @@ def MOV32r0 : I<0x31, MRMInitReg, (ops R32:$dst),
"xor{l} $dst, $dst",
[(set R32:$dst, 0)]>;
+// Basic operations on R16 / R32 subclasses R16_ and R32_ which contains only
+// those registers that have R8 sub-registers (i.e. AX - DX, EAX - EDX).
+def MOV16to16_ : I<0x89, MRMDestReg, (ops R16_:$dst, R16:$src),
+ "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
+def MOV32to32_ : I<0x89, MRMDestReg, (ops R32_:$dst, R32:$src),
+ "mov{l} {$src, $dst|$dst, $src}", []>;
+
+def MOV16_rr : I<0x89, MRMDestReg, (ops R16_:$dst, R16_:$src),
+ "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
+def MOV32_rr : I<0x89, MRMDestReg, (ops R32_:$dst, R32_:$src),
+ "mov{l} {$src, $dst|$dst, $src}", []>;
+def MOV16_rm : I<0x8B, MRMSrcMem, (ops R16_:$dst, i16mem:$src),
+ "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
+def MOV32_rm : I<0x8B, MRMSrcMem, (ops R32_:$dst, i32mem:$src),
+ "mov{l} {$src, $dst|$dst, $src}", []>;
+def MOV16_mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16_:$src),
+ "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
+def MOV32_mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32_:$src),
+ "mov{l} {$src, $dst|$dst, $src}", []>;
+
//===----------------------------------------------------------------------===//
// DWARF Pseudo Instructions
//
diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp
index fc42797d6c..952f73206e 100755
--- a/lib/Target/X86/X86IntelAsmPrinter.cpp
+++ b/lib/Target/X86/X86IntelAsmPrinter.cpp
@@ -89,7 +89,7 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
unsigned Reg = MO.getReg();
if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) {
MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0)
- ? MVT::i16 : MVT::i32;
+ ? MVT::i16 : MVT::i8;
Reg = getX86SubSuperRegister(Reg, VT);
}
O << RI.get(Reg).Name;
@@ -268,12 +268,13 @@ void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
const MachineOperand &MO1 = MI->getOperand(1);
unsigned Reg0 = MO0.getReg();
unsigned Reg1 = MO1.getReg();
- if (MI->getOpcode() == X86::TRUNC_R16_R8)
- Reg0 = getX86SubSuperRegister(Reg0, MVT::i16);
+ if (MI->getOpcode() == X86::TRUNC_R32_R16)
+ Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
else
- Reg0 = getX86SubSuperRegister(Reg0, MVT::i32);
- if (Reg0 == Reg1)
- O << CommentString << " TRUNCATE ";
+ Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
+ O << CommentString << " TRUNCATE ";
+ if (Reg0 != Reg1)
+ O << "\n\t";
break;
}
}
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index dac71a02f1..57e6b17e6a 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -52,10 +52,14 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
unsigned Opc;
if (RC == &X86::R32RegClass) {
Opc = X86::MOV32mr;
- } else if (RC == &X86::R8RegClass) {
- Opc = X86::MOV8mr;
} else if (RC == &X86::R16RegClass) {
Opc = X86::MOV16mr;
+ } else if (RC == &X86::R8RegClass) {
+ Opc = X86::MOV8mr;
+ } else if (RC == &X86::R32_RegClass) {
+ Opc = X86::MOV32_mr;
+ } else if (RC == &X86::R16_RegClass) {
+ Opc = X86::MOV16_mr;
} else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) {
Opc = X86::FpST64m;
} else if (RC == &X86::FR32RegClass) {
@@ -78,10 +82,14 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
unsigned Opc;
if (RC == &X86::R32RegClass) {
Opc = X86::MOV32rm;
- } else if (RC == &X86::R8RegClass) {
- Opc = X86::MOV8rm;
} else if (RC == &X86::R16RegClass) {
Opc = X86::MOV16rm;
+ } else if (RC == &X86::R8RegClass) {
+ Opc = X86::MOV8rm;
+ } else if (RC == &X86::R32_RegClass) {
+ Opc = X86::MOV32_rm;
+ } else if (RC == &X86::R16_RegClass) {
+ Opc = X86::MOV16_rm;
} else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) {
Opc = X86::FpLD64m;
} else if (RC == &X86::FR32RegClass) {
@@ -104,10 +112,14 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned Opc;
if (RC == &X86::R32RegClass) {
Opc = X86::MOV32rr;
- } else if (RC == &X86::R8RegClass) {
- Opc = X86::MOV8rr;
} else if (RC == &X86::R16RegClass) {
Opc = X86::MOV16rr;
+ } else if (RC == &X86::R8RegClass) {
+ Opc = X86::MOV8rr;
+ } else if (RC == &X86::R32_RegClass) {
+ Opc = X86::MOV32_rr;
+ } else if (RC == &X86::R16_RegClass) {
+ Opc = X86::MOV16_rr;
} else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) {
Opc = X86::FpMOV;
} else if (RC == &X86::FR32RegClass) {
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index 5b20c1c392..64ac727883 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -136,6 +136,10 @@ def R32 : RegisterClass<"X86", [i32], 32,
}];
}
+// R16, R32 subclasses which contain registers that have R8 sub-registers.
+def R16_ : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]>;
+def R32_ : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]>;
+
// Scalar SSE2 floating point registers.
def FR32 : RegisterClass<"X86", [f32], 32,
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;