[llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86ISelDAGToDAG.cpp X86InstrInfo.td X86IntelAsmPrinter.cpp X86RegisterInfo.cpp X86RegisterInfo.h

Evan Cheng evan.cheng at apple.com
Thu May 4 22:40:32 PDT 2006



Changes in directory llvm/lib/Target/X86:

X86ATTAsmPrinter.cpp updated: 1.42 -> 1.43
X86ISelDAGToDAG.cpp updated: 1.57 -> 1.58
X86InstrInfo.td updated: 1.263 -> 1.264
X86IntelAsmPrinter.cpp updated: 1.41 -> 1.42
X86RegisterInfo.cpp updated: 1.149 -> 1.150
X86RegisterInfo.h updated: 1.37 -> 1.38
---
Log message:

Better implementation of truncate. ISel matches it to a pseudo instruction
that gets emitted as movl (for r32 to i16, i8) or a movw (for r16 to i8). And
if the destination gets allocated a subregister of the source operand, then
the instruction will not be emitted at all.


---
Diffs of the changes:  (+162 -240)

 X86ATTAsmPrinter.cpp   |  136 ++++++++++++-------------------------------------
 X86ISelDAGToDAG.cpp    |   39 --------------
 X86InstrInfo.td        |   11 +++
 X86IntelAsmPrinter.cpp |  135 ++++++++++++------------------------------------
 X86RegisterInfo.cpp    |   76 +++++++++++++++++++++++++++
 X86RegisterInfo.h      |    5 +
 6 files changed, 162 insertions(+), 240 deletions(-)


Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.42 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.43
--- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.42	Thu May  4 13:05:43 2006
+++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp	Fri May  5 00:40:20 2006
@@ -108,13 +108,20 @@
   const MachineOperand &MO = MI->getOperand(OpNo);
   const MRegisterInfo &RI = *TM.getRegisterInfo();
   switch (MO.getType()) {
-  case MachineOperand::MO_Register:
+  case MachineOperand::MO_Register: {
     assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
            "Virtual registers should not make it this far!");
     O << '%';
-    for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
+    unsigned Reg = MO.getReg();
+    if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) {
+      MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0)
+        ? MVT::i16 : MVT::i32;
+      Reg = getX86SubSuperRegister(Reg, VT);
+    }
+    for (const char *Name = RI.get(Reg).Name; *Name; ++Name)
       O << (char)tolower(*Name);
     return;
+  }
 
   case MachineOperand::MO_Immediate:
     if (!Modifier || strcmp(Modifier, "debug") != 0)
@@ -263,116 +270,25 @@
                                          const char Mode) {
   const MRegisterInfo &RI = *TM.getRegisterInfo();
   unsigned Reg = MO.getReg();
-  const char *Name = RI.get(Reg).Name;
   switch (Mode) {
   default: return true;  // Unknown mode.
   case 'b': // Print QImode register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "al";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "dl";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "cl";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "bl";
-      break;
-    case X86::ESI:
-      Name = "sil";
-      break;
-    case X86::EDI:
-      Name = "dil";
-      break;
-    case X86::EBP:
-      Name = "bpl";
-      break;
-    case X86::ESP:
-      Name = "spl";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i8);
     break;
   case 'h': // Print QImode high register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "al";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "dl";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "cl";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "bl";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
     break;
   case 'w': // Print HImode register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "ax";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "dx";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "cx";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "bx";
-      break;
-    case X86::ESI:
-      Name = "si";
-      break;
-    case X86::EDI:
-      Name = "di";
-      break;
-    case X86::EBP:
-      Name = "bp";
-      break;
-    case X86::ESP:
-      Name = "sp";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i16);
     break;
   case 'k': // Print SImode register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "eax";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "edx";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "ecx";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "ebx";
-      break;
-    case X86::ESI:
-      Name = "esi";
-      break;
-    case X86::EDI:
-      Name = "edi";
-      break;
-    case X86::EBP:
-      Name = "ebp";
-      break;
-    case X86::ESP:
-      Name = "esp";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i32);
     break;
   }
 
-  O << '%' << Name;
+  O << '%';
+  for (const char *Name = RI.get(Reg).Name; *Name; ++Name)
+    O << (char)tolower(*Name);
   return false;
 }
 
@@ -440,6 +356,26 @@
     }
   }
 
+  // See if a truncate instruction can be turned into a nop.
+  switch (MI->getOpcode()) {
+  default: break;
+  case X86::TRUNC_R32_R16:
+  case X86::TRUNC_R32_R8:
+  case X86::TRUNC_R16_R8: {
+    const MachineOperand &MO0 = MI->getOperand(0);
+    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);
+    else
+      Reg0 = getX86SubSuperRegister(Reg0, MVT::i32);
+    if (Reg0 == Reg1)
+      O << CommentString << " TRUNCATE ";
+    break;
+  }
+  }
+
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);
 }


Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.57 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.58
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.57	Sat Mar 25 00:47:10 2006
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp	Fri May  5 00:40:20 2006
@@ -791,45 +791,6 @@
 #endif
       return;
     }
-
-    case ISD::TRUNCATE: {
-      unsigned Reg;
-      MVT::ValueType VT;
-      switch (Node->getOperand(0).getValueType()) {
-        default: assert(0 && "Unknown truncate!");
-        case MVT::i16: Reg = X86::AX;  Opc = X86::MOV16rr; VT = MVT::i16; break;
-        case MVT::i32: Reg = X86::EAX; Opc = X86::MOV32rr; VT = MVT::i32; break;
-      }
-      SDOperand Tmp0, Tmp1;
-      Select(Tmp0, Node->getOperand(0));
-      Select(Tmp1, SDOperand(CurDAG->getTargetNode(Opc, VT, Tmp0), 0));
-      SDOperand InFlag = SDOperand(0,0);
-      Result = CurDAG->getCopyToReg(CurDAG->getEntryNode(), Reg, Tmp1, InFlag);
-      SDOperand Chain = Result.getValue(0);
-      InFlag = Result.getValue(1);
-
-      switch (NVT) {
-        default: assert(0 && "Unknown truncate!");
-        case MVT::i8:  Reg = X86::AL;  Opc = X86::MOV8rr;  VT = MVT::i8;  break;
-        case MVT::i16: Reg = X86::AX;  Opc = X86::MOV16rr; VT = MVT::i16; break;
-      }
-
-      Result = CurDAG->getCopyFromReg(Chain, Reg, VT, InFlag);
-      if (N.Val->hasOneUse())
-        Result = CurDAG->SelectNodeTo(N.Val, Opc, VT, Result);
-      else
-        Result = CodeGenMap[N] =
-          SDOperand(CurDAG->getTargetNode(Opc, VT, Result), 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.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.263 llvm/lib/Target/X86/X86InstrInfo.td:1.264
--- llvm/lib/Target/X86/X86InstrInfo.td:1.263	Thu Apr 27 03:40:39 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td	Fri May  5 00:40:20 2006
@@ -351,6 +351,17 @@
 // Nop
 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_R16 : I<0x89, MRMDestReg, (ops R16:$dst, R32:$src),
+                      "mov{l} {$src, ${dst:trunc32}|${dst:trunc32}, $src}",
+                      [(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...
 //


Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.41 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.42
--- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.41	Thu May  4 13:05:43 2006
+++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp	Fri May  5 00:40:20 2006
@@ -101,9 +101,15 @@
   const MRegisterInfo &RI = *TM.getRegisterInfo();
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
-    if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
-      O << RI.get(MO.getReg()).Name;
-    else
+    if (MRegisterInfo::isPhysicalRegister(MO.getReg())) {
+      unsigned Reg = MO.getReg();
+      if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) {
+        MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0)
+          ? MVT::i16 : MVT::i32;
+        Reg = getX86SubSuperRegister(Reg, VT);
+      }
+      O << RI.get(Reg).Name;
+    } else
       O << "reg" << MO.getReg();
     return;
 
@@ -240,116 +246,23 @@
                                            const char Mode) {
   const MRegisterInfo &RI = *TM.getRegisterInfo();
   unsigned Reg = MO.getReg();
-  const char *Name = RI.get(Reg).Name;
   switch (Mode) {
   default: return true;  // Unknown mode.
   case 'b': // Print QImode register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "AL";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "DL";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "CL";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "BL";
-      break;
-    case X86::ESI:
-      Name = "SIL";
-      break;
-    case X86::EDI:
-      Name = "DIL";
-      break;
-    case X86::EBP:
-      Name = "BPL";
-      break;
-    case X86::ESP:
-      Name = "SPL";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i8);
     break;
   case 'h': // Print QImode high register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "AL";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "DL";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "CL";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "BL";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
     break;
   case 'w': // Print HImode register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "AX";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "DX";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "CX";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "BX";
-      break;
-    case X86::ESI:
-      Name = "SI";
-      break;
-    case X86::EDI:
-      Name = "DI";
-      break;
-    case X86::EBP:
-      Name = "BP";
-      break;
-    case X86::ESP:
-      Name = "SP";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i16);
     break;
   case 'k': // Print SImode register
-    switch (Reg) {
-    default: return true;
-    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
-      Name = "EAX";
-      break;
-    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
-      Name = "EDX";
-      break;
-    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
-      Name = "ECX";
-      break;
-    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
-      Name = "EBX";
-      break;
-    case X86::ESI:
-      Name = "ESI";
-      break;
-    case X86::EDI:
-      Name = "EDI";
-      break;
-    case X86::EBP:
-      Name = "EBP";
-      break;
-    case X86::ESP:
-      Name = "ESP";
-      break;
-    }
+    Reg = getX86SubSuperRegister(Reg, MVT::i32);
     break;
   }
 
-  O << Name;
+  O << '%' << RI.get(Reg).Name;
   return false;
 }
 
@@ -392,6 +305,26 @@
 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
 
+  // See if a truncate instruction can be turned into a nop.
+  switch (MI->getOpcode()) {
+  default: break;
+  case X86::TRUNC_R32_R16:
+  case X86::TRUNC_R32_R8:
+  case X86::TRUNC_R16_R8: {
+    const MachineOperand &MO0 = MI->getOperand(0);
+    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);
+    else
+      Reg0 = getX86SubSuperRegister(Reg0, MVT::i32);
+    if (Reg0 == Reg1)
+      O << CommentString << " TRUNCATE ";
+    break;
+  }
+  }
+
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);
 }


Index: llvm/lib/Target/X86/X86RegisterInfo.cpp
diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.149 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.150
--- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.149	Thu May  4 13:16:01 2006
+++ llvm/lib/Target/X86/X86RegisterInfo.cpp	Fri May  5 00:40:20 2006
@@ -811,5 +811,81 @@
   return hasFP(MF) ? X86::EBP : X86::ESP;
 }
 
+namespace llvm {
+unsigned getX86SubSuperRegister(unsigned Reg, MVT::ValueType VT, bool High) {
+  switch (VT) {
+  default: return Reg;
+  case MVT::i8:
+    if (High) {
+      switch (Reg) {
+      default: return Reg;
+      case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+        return X86::AH;
+      case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+        return X86::DH;
+      case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+        return X86::CH;
+      case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+        return X86::BH;
+      }
+    } else {
+      switch (Reg) {
+      default: return Reg;
+      case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+        return X86::AL;
+      case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+        return X86::DL;
+      case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+        return X86::CL;
+      case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+        return X86::BL;
+      }
+    }
+  case MVT::i16:
+    switch (Reg) {
+    default: return Reg;
+    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+      return X86::AX;
+    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+      return X86::DX;
+    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+      return X86::CX;
+    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+      return X86::BX;
+    case X86::ESI:
+      return X86::SI;
+    case X86::EDI:
+      return X86::DI;
+    case X86::EBP:
+      return X86::BP;
+    case X86::ESP:
+      return X86::SP;
+    }
+  case MVT::i32:
+    switch (Reg) {
+    default: return true;
+    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+      return X86::EAX;
+    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+      return X86::EDX;
+    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+      return X86::ECX;
+    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+      return X86::EBX;
+    case X86::SI:
+      return X86::ESI;
+    case X86::DI:
+      return X86::EDI;
+    case X86::BP:
+      return X86::EBP;
+    case X86::SP:
+      return X86::ESP;
+    }
+  }
+
+  return Reg;
+}
+}
+
 #include "X86GenRegisterInfo.inc"
 


Index: llvm/lib/Target/X86/X86RegisterInfo.h
diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.37 llvm/lib/Target/X86/X86RegisterInfo.h:1.38
--- llvm/lib/Target/X86/X86RegisterInfo.h:1.37	Fri Apr  7 11:34:46 2006
+++ llvm/lib/Target/X86/X86RegisterInfo.h	Fri May  5 00:40:20 2006
@@ -68,6 +68,11 @@
   unsigned getFrameRegister(MachineFunction &MF) const;
 };
 
+// getX86SubSuperRegister - X86 utility function. It returns the sub or super
+// register of a specific X86 register.
+// e.g. getX86SubSuperRegister(X86::EAX, MVT::i16) return X86:AX
+unsigned getX86SubSuperRegister(unsigned, MVT::ValueType, bool High=false);
+
 } // End llvm namespace
 
 #endif






More information about the llvm-commits mailing list