[llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86ISelDAGToDAG.cpp X86InstrInfo.cpp X86InstrInfo.td X86IntelAsmPrinter.cpp X86RegisterInfo.cpp X86RegisterInfo.td
Evan Cheng
evan.cheng at apple.com
Mon May 8 01:01:40 PDT 2006
Changes in directory llvm/lib/Target/X86:
X86ATTAsmPrinter.cpp updated: 1.43 -> 1.44
X86ISelDAGToDAG.cpp updated: 1.58 -> 1.59
X86InstrInfo.cpp updated: 1.49 -> 1.50
X86InstrInfo.td updated: 1.265 -> 1.266
X86IntelAsmPrinter.cpp updated: 1.43 -> 1.44
X86RegisterInfo.cpp updated: 1.150 -> 1.151
X86RegisterInfo.td updated: 1.33 -> 1.34
---
Log message:
Fixing truncate. Previously we were emitting truncate from r16 to r8 as
movw. That is we promote the destination operand to r16. So
%CH = TRUNC_R16_R8 %BP
is emitted as
movw %bp, %cx.
This is incorrect. If %cl is live, it would be clobbered.
Ideally we want to do the opposite, that is emitted it as
movb ??, %ch
But this is not possible since %bp does not have a r8 sub-register.
We are now defining a new register class R16_ which is a subclass of R16
containing only those 16-bit registers that have r8 sub-registers (i.e.
AX - DX). We isel the truncate to two instructions, a MOV16to16_ to copy the
value to the R16_ class, followed by a TRUNC_R16_R8.
Due to bug 770: http://llvm.cs.uiuc.edu/PR770 , the register colaescer is not going to coalesce between R16 and
R16_. That will be fixed later so we can eliminate the MOV16to16_. Right now, it
can only be eliminated if we are lucky that source and destination registers are
the same.
---
Diffs of the changes: (+100 -25)
X86ATTAsmPrinter.cpp | 13 +++++++------
X86ISelDAGToDAG.cpp | 38 ++++++++++++++++++++++++++++++++++++++
X86InstrInfo.cpp | 1 +
X86InstrInfo.td | 32 +++++++++++++++++++++++++-------
X86IntelAsmPrinter.cpp | 13 +++++++------
X86RegisterInfo.cpp | 24 ++++++++++++++++++------
X86RegisterInfo.td | 4 ++++
7 files changed, 100 insertions(+), 25 deletions(-)
Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.43 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.44
--- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.43 Fri May 5 00:40:20 2006
+++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Mon May 8 03:01:26 2006
@@ -115,7 +115,7 @@
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 @@
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;
}
}
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.58 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.59
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.58 Fri May 5 00:40:20 2006
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Mon May 8 03:01:26 2006
@@ -791,6 +791,44 @@
#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);
Index: llvm/lib/Target/X86/X86InstrInfo.cpp
diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.49 llvm/lib/Target/X86/X86InstrInfo.cpp:1.50
--- llvm/lib/Target/X86/X86InstrInfo.cpp:1.49 Tue Apr 18 11:44:51 2006
+++ llvm/lib/Target/X86/X86InstrInfo.cpp Mon May 8 03:01:26 2006
@@ -28,6 +28,7 @@
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 ||
Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.265 llvm/lib/Target/X86/X86InstrInfo.td:1.266
--- llvm/lib/Target/X86/X86InstrInfo.td:1.265 Fri May 5 03:23:07 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td Mon May 8 03:01:26 2006
@@ -357,15 +357,13 @@
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 @@
"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
//
Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.43 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.44
--- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.43 Sat May 6 16:27:14 2006
+++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Mon May 8 03:01:26 2006
@@ -89,7 +89,7 @@
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 @@
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;
}
}
Index: llvm/lib/Target/X86/X86RegisterInfo.cpp
diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.150 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.151
--- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.150 Fri May 5 00:40:20 2006
+++ llvm/lib/Target/X86/X86RegisterInfo.cpp Mon May 8 03:01:26 2006
@@ -52,10 +52,14 @@
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 @@
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 @@
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) {
Index: llvm/lib/Target/X86/X86RegisterInfo.td
diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.33 llvm/lib/Target/X86/X86RegisterInfo.td:1.34
--- llvm/lib/Target/X86/X86RegisterInfo.td:1.33 Sun May 7 05:10:20 2006
+++ llvm/lib/Target/X86/X86RegisterInfo.td Mon May 8 03:01:26 2006
@@ -136,6 +136,10 @@
}];
}
+// 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]>;
More information about the llvm-commits
mailing list