[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