Fix disassembler handling of CRC32 which is an odd instruction that uses 0xf2 as...
authorCraig Topper <craig.topper@gmail.com>
Sat, 1 Oct 2011 19:54:56 +0000 (19:54 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sat, 1 Oct 2011 19:54:56 +0000 (19:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140954 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
test/MC/Disassembler/X86/simple-tests.txt
test/MC/Disassembler/X86/x86-32.txt
utils/TableGen/X86DisassemblerTables.cpp
utils/TableGen/X86RecognizableInstr.cpp

index 70315ed572b40c3f37e954ea98da2e40859a8dc6..b1eef6c1a91364426e878578dd16524377448799 100644 (file)
@@ -81,12 +81,15 @@ enum attributeBits {
                                         "but not the operands")                \
   ENUM_ENTRY(IC_XS,                 2,  "may say something about the opcode "  \
                                         "but not the operands")                \
+  ENUM_ENTRY(IC_XD_OPSIZE,          3,  "requires an OPSIZE prefix, so "       \
+                                        "operands change width")               \
   ENUM_ENTRY(IC_64BIT_REXW,         4,  "requires a REX.W prefix, so operands "\
                                         "change width; overrides IC_OPSIZE")   \
   ENUM_ENTRY(IC_64BIT_OPSIZE,       3,  "Just as meaningful as IC_OPSIZE")     \
   ENUM_ENTRY(IC_64BIT_XD,           5,  "XD instructions are SSE; REX.W is "   \
                                         "secondary")                           \
   ENUM_ENTRY(IC_64BIT_XS,           5,  "Just as meaningful as IC_64BIT_XD")   \
+  ENUM_ENTRY(IC_64BIT_XD_OPSIZE,    3,  "Just as meaningful as IC_XD_OPSIZE")  \
   ENUM_ENTRY(IC_64BIT_REXW_XS,      6,  "OPSIZE could mean a different "       \
                                         "opcode")                              \
   ENUM_ENTRY(IC_64BIT_REXW_XD,      6,  "Just as meaningful as "               \
index 55ac9ab168c1af49c682b6d8ee25c140a2e0770d..4f88caa4b5c5d8df8d6891f7ec2faa47872b15d4 100644 (file)
 
 # CHECK: vroundsd $0, %xmm0, %xmm0, %xmm0
 0xc4 0xe3 0x79 0x0b 0xc0 0x00
+
+# CHECK: crc32b %al, %eax
+0xf2 0x0f 0x38 0xf0 0xc0
+
+# CHECK: crc32w %ax, %eax
+0x66 0xf2 0x0f 0x38 0xf1 0xc0
+
+# CHECK: crc32l %eax, %eax
+0xf2 0x0f 0x38 0xf1 0xc0
+
+# CHECK: crc32q %rax, %rax
+0xf2 0x48 0x0f 0x38 0xf1 0xc0
index 5c2a95d078d96ed62dbbd520553a694d6a8dec40..7df29546e8ac480f1a77a368c007184a80abc683 100644 (file)
@@ -31,6 +31,9 @@
 # CHECK: crc32w %ax, %eax
 0x66 0xf2 0x0f 0x38 0xf1 0xc0
 
+# CHECK: crc32l %eax, %eax
+0xf2 0x0f 0x38 0xf1 0xc0
+
 
 # CHECK: int   $33
 0xCD 0x21 
index e7b608306c8d4522c774a8206a8481fd7058509b..14de3682a5154408ac14444f77d15b574eb870dd 100644 (file)
@@ -51,8 +51,11 @@ static inline bool inheritsFrom(InstructionContext child,
     return inheritsFrom(child, IC_64BIT_OPSIZE);
   case IC_XD:
     return inheritsFrom(child, IC_64BIT_XD);
+           inheritsFrom(child, IC_XD_OPSIZE);
   case IC_XS:
     return inheritsFrom(child, IC_64BIT_XS);
+  case IC_XD_OPSIZE:
+    return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
   case IC_64BIT_REXW:
     return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
            inheritsFrom(child, IC_64BIT_REXW_XD) ||
@@ -63,6 +66,8 @@ static inline bool inheritsFrom(InstructionContext child,
     return(inheritsFrom(child, IC_64BIT_REXW_XD));
   case IC_64BIT_XS:
     return(inheritsFrom(child, IC_64BIT_REXW_XS));
+  case IC_64BIT_XD_OPSIZE:
+    return false;
   case IC_64BIT_REXW_XD:
     return false;
   case IC_64BIT_REXW_XS:
@@ -521,6 +526,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 
              (index & ATTR_OPSIZE))
       o << "IC_64BIT_REXW_OPSIZE";
+    else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
+      o << "IC_64BIT_XD_OPSIZE";
     else if ((index & ATTR_64BIT) && (index & ATTR_XS))
       o << "IC_64BIT_XS";
     else if ((index & ATTR_64BIT) && (index & ATTR_XD))
@@ -531,6 +538,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
       o << "IC_64BIT_REXW";
     else if ((index & ATTR_64BIT))
       o << "IC_64BIT";
+    else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
+      o << "IC_XD_OPSIZE";
     else if (index & ATTR_XS)
       o << "IC_XS";
     else if (index & ATTR_XD)
index 4118293ae5677ee85a61391ecefbe8f3c77f36ec..532e7307050a9a5c4db7b1a537a0c2ec173f7538 100644 (file)
@@ -309,13 +309,15 @@ InstructionContext RecognizableInstr::insnContext() const {
   } else if (Is64Bit || HasREX_WPrefix) {
     if (HasREX_WPrefix && HasOpSizePrefix)
       insnContext = IC_64BIT_REXW_OPSIZE;
+    else if (HasOpSizePrefix && (Prefix == X86Local::XD || Prefix == X86Local::TF))
+      insnContext = IC_64BIT_XD_OPSIZE;
     else if (HasOpSizePrefix)
       insnContext = IC_64BIT_OPSIZE;
     else if (HasREX_WPrefix && Prefix == X86Local::XS)
       insnContext = IC_64BIT_REXW_XS;
-    else if (HasREX_WPrefix && Prefix == X86Local::XD)
+    else if (HasREX_WPrefix && (Prefix == X86Local::XD || Prefix == X86Local::TF))
       insnContext = IC_64BIT_REXW_XD;
-    else if (Prefix == X86Local::XD)
+    else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
       insnContext = IC_64BIT_XD;
     else if (Prefix == X86Local::XS)
       insnContext = IC_64BIT_XS;
@@ -324,11 +326,12 @@ InstructionContext RecognizableInstr::insnContext() const {
     else
       insnContext = IC_64BIT;
   } else {
-    if (HasOpSizePrefix && Prefix == X86Local::TF)
-      insnContext = IC_XD;
+    if (HasOpSizePrefix &&
+        (Prefix == X86Local::XD || Prefix == X86Local::TF))
+      insnContext = IC_XD_OPSIZE;
     else if (HasOpSizePrefix)
       insnContext = IC_OPSIZE;
-    else if (Prefix == X86Local::XD)
+    else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
       insnContext = IC_XD;
     else if (Prefix == X86Local::XS || Prefix == X86Local::REP)
       insnContext = IC_XS;
@@ -402,7 +405,7 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const {
   // Filter out alternate forms of AVX instructions
   if (Name.find("_alt") != Name.npos ||
       Name.find("XrYr") != Name.npos ||
-      Name.find("r64r") != Name.npos ||
+      (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos) ||
       Name.find("_64mr") != Name.npos ||
       Name.find("Xrr") != Name.npos ||
       Name.find("rr64") != Name.npos)