[X86] Teach the disassembler that some instructions use VEX.W==0 without a correspond...
authorCraig Topper <craig.topper@intel.com>
Sun, 22 Oct 2017 06:18:26 +0000 (06:18 +0000)
committerCraig Topper <craig.topper@intel.com>
Sun, 22 Oct 2017 06:18:26 +0000 (06:18 +0000)
Fixes PR11304.

llvm-svn: 316285

llvm/test/MC/Disassembler/X86/x86-64-err.txt
llvm/utils/TableGen/X86DisassemblerTables.cpp
llvm/utils/TableGen/X86DisassemblerTables.h
llvm/utils/TableGen/X86RecognizableInstr.cpp

index 8dd43ed..9674ea0 100644 (file)
@@ -4,3 +4,14 @@
 # 64: warning: invalid instruction encoding
 # 32: into
 0xce
+
+# 64: invalid instruction encoding
+0xc4,0x62,0xf9,0x18,0x20
+# 64: invalid instruction encoding
+0xc4,0x62,0xfd,0x18,0x20
+# 64: invalid instruction encoding
+0xc4,0xc2,0xfd,0x19,0xcc
+# 64: invalid instruction encoding
+0xc4,0xe2,0xfd,0x1a,0x08
+# 64: invalid instruction encoding
+0xc4,0xe3,0xfd,0x39,0xc5,0x01
index c80b969..d4ba4f7 100644 (file)
@@ -75,7 +75,8 @@ static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
 /// @return       - True if child is a subset of parent, false otherwise.
 static inline bool inheritsFrom(InstructionContext child,
                                 InstructionContext parent,
-                                bool VEX_LIG = false, bool AdSize64 = false) {
+                                bool VEX_LIG = false, bool VEX_WIG = false,
+                                bool AdSize64 = false) {
   if (child == parent)
     return true;
 
@@ -133,20 +134,20 @@ static inline bool inheritsFrom(InstructionContext child,
   case IC_64BIT_REXW_ADSIZE:
     return false;
   case IC_VEX:
-    return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W)) ||
-           inheritsFrom(child, IC_VEX_W) ||
+    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W)) ||
+           (VEX_WIG && inheritsFrom(child, IC_VEX_W)) ||
            (VEX_LIG && inheritsFrom(child, IC_VEX_L));
   case IC_VEX_XS:
-    return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||
-           inheritsFrom(child, IC_VEX_W_XS) ||
+    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||
+           (VEX_WIG && inheritsFrom(child, IC_VEX_W_XS)) ||
            (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));
   case IC_VEX_XD:
-    return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||
-           inheritsFrom(child, IC_VEX_W_XD) ||
+    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||
+           (VEX_WIG && inheritsFrom(child, IC_VEX_W_XD)) ||
            (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));
   case IC_VEX_OPSIZE:
-    return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
-           inheritsFrom(child, IC_VEX_W_OPSIZE) ||
+    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
+           (VEX_WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) ||
            (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
   case IC_VEX_W:
     return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);
@@ -157,13 +158,13 @@ static inline bool inheritsFrom(InstructionContext child,
   case IC_VEX_W_OPSIZE:
     return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
   case IC_VEX_L:
-    return inheritsFrom(child, IC_VEX_L_W);
+    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W);
   case IC_VEX_L_XS:
-    return inheritsFrom(child, IC_VEX_L_W_XS);
+    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS);
   case IC_VEX_L_XD:
-    return inheritsFrom(child, IC_VEX_L_W_XD);
+    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD);
   case IC_VEX_L_OPSIZE:
-    return inheritsFrom(child, IC_VEX_L_W_OPSIZE);
+    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
   case IC_VEX_L_W:
   case IC_VEX_L_W_XS:
   case IC_VEX_L_W_XD:
@@ -909,6 +910,7 @@ void DisassemblerTables::setTableFields(OpcodeType          type,
                                         InstrUID            uid,
                                         bool                is32bit,
                                         bool                ignoresVEX_L,
+                                        bool                ignoresVEX_W,
                                         unsigned            addressSize) {
   ContextDecision &decision = *Tables[type];
 
@@ -920,7 +922,7 @@ void DisassemblerTables::setTableFields(OpcodeType          type,
     bool adSize64 = addressSize == 64;
     if (inheritsFrom((InstructionContext)index,
                      InstructionSpecifiers[uid].insnContext, ignoresVEX_L,
-                     adSize64))
+                     ignoresVEX_W, adSize64))
       setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
                      filter,
                      uid,
index 1171c79..f2215a8 100644 (file)
@@ -253,6 +253,7 @@ public:
                       InstrUID uid,
                       bool is32bit,
                       bool ignoresVEX_L,
+                      bool ignoresVEX_W,
                       unsigned AddrSize);
 
   /// specForUID - Returns the instruction specifier for a given unique
index 0bb26f7..ec85802 100644 (file)
@@ -800,13 +800,15 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
                             insnContext(),
                             currentOpcode,
                             *filter,
-                            UID, Is32Bit, IgnoresVEX_L, AddressSize);
+                            UID, Is32Bit, IgnoresVEX_L,
+                            VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
   } else {
     tables.setTableFields(opcodeType,
                           insnContext(),
                           opcodeToSet,
                           *filter,
-                          UID, Is32Bit, IgnoresVEX_L, AddressSize);
+                          UID, Is32Bit, IgnoresVEX_L,
+                          VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
   }
 
   delete filter;