Don't allow 32-bit only instructions to be disassembled in 64-bit mode. Fixes part...
authorCraig Topper <craig.topper@gmail.com>
Fri, 23 Sep 2011 06:57:25 +0000 (06:57 +0000)
committerCraig Topper <craig.topper@gmail.com>
Fri, 23 Sep 2011 06:57:25 +0000 (06:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140370 91177308-0d34-0410-b5e6-96231b3b80d8

test/MC/Disassembler/X86/intel-syntax.txt
utils/TableGen/X86DisassemblerTables.cpp
utils/TableGen/X86DisassemblerTables.h
utils/TableGen/X86RecognizableInstr.cpp
utils/TableGen/X86RecognizableInstr.h

index b848418a52ee7290bad7ea2b3e4200abc6a281a5..c04dcd099ba1a694c6c9049199e56f9fd3f284d0 100644 (file)
 # CHECK: movsq
 0x48 0xa5
 
 # CHECK: movsq
 0x48 0xa5
 
-# CHECK: pop DS
-0x1f
+# CHECK: pop FS
+0x0f 0xa1
 
 
-# CHECK: pop ES
-0x07
-
-# CHECK: pop SS
-0x17
+# CHECK: pop GS
+0x0f 0xa9
 
 # CHECK: in AL, DX
 0xec
 
 # CHECK: in AL, DX
 0xec
index aed27279a51bca36d3178a13b5e14234af02f48e..b12660eea218f590be3b0bf2c8fad97b5c54fe6d 100644 (file)
@@ -642,12 +642,16 @@ void DisassemblerTables::setTableFields(OpcodeType          type,
                                         InstructionContext  insnContext,
                                         uint8_t             opcode,
                                         const ModRMFilter   &filter,
                                         InstructionContext  insnContext,
                                         uint8_t             opcode,
                                         const ModRMFilter   &filter,
-                                        InstrUID            uid) {
+                                        InstrUID            uid,
+                                        bool                is32bit) {
   unsigned index;
   
   ContextDecision &decision = *Tables[type];
 
   for (index = 0; index < IC_max; ++index) {
   unsigned index;
   
   ContextDecision &decision = *Tables[type];
 
   for (index = 0; index < IC_max; ++index) {
+    if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT))
+      continue;
+
     if (inheritsFrom((InstructionContext)index, 
                      InstructionSpecifiers[uid].insnContext))
       setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 
     if (inheritsFrom((InstructionContext)index, 
                      InstructionSpecifiers[uid].insnContext))
       setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 
index d16ebfca419e3c0430cae62f6cb939fc5d7c6185..ae126be5696163c17e45706dfee849fe6ae35da0 100644 (file)
@@ -260,11 +260,13 @@ public:
   /// @param filter       - The ModRMFilter that decides which ModR/M byte values
   ///                       correspond to the desired instruction.
   /// @param uid          - The unique ID of the instruction.
   /// @param filter       - The ModRMFilter that decides which ModR/M byte values
   ///                       correspond to the desired instruction.
   /// @param uid          - The unique ID of the instruction.
+  /// @param is32bit      - Instructon is only 32-bit
   void setTableFields(OpcodeType type,
                       InstructionContext insnContext,
                       uint8_t opcode,
                       const ModRMFilter &filter,
   void setTableFields(OpcodeType type,
                       InstructionContext insnContext,
                       uint8_t opcode,
                       const ModRMFilter &filter,
-                      InstrUID uid);  
+                      InstrUID uid,
+                      bool is32bit);  
   
   /// specForUID - Returns the instruction specifier for a given unique
   ///   instruction ID.  Used when resolving collisions.
   
   /// specForUID - Returns the instruction specifier for a given unique
   ///   instruction ID.  Used when resolving collisions.
index ab402228986cf90fd91846e1ce3a4918156baa09..4118293ae5677ee85a61391ecefbe8f3c77f36ec 100644 (file)
@@ -231,10 +231,15 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
   HasVEX_LPrefix   = has256BitOperands() || Rec->getValueAsBit("hasVEX_L");
   
   // Check for 64-bit inst which does not require REX
   HasVEX_LPrefix   = has256BitOperands() || Rec->getValueAsBit("hasVEX_L");
   
   // Check for 64-bit inst which does not require REX
+  Is32Bit = false;
   Is64Bit = false;
   // FIXME: Is there some better way to check for In64BitMode?
   std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
   for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
   Is64Bit = false;
   // FIXME: Is there some better way to check for In64BitMode?
   std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
   for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
+    if (Predicates[i]->getName().find("32Bit") != Name.npos) {
+      Is32Bit = true;
+      break;
+    }
     if (Predicates[i]->getName().find("64Bit") != Name.npos) {
       Is64Bit = true;
       break;
     if (Predicates[i]->getName().find("64Bit") != Name.npos) {
       Is64Bit = true;
       break;
@@ -947,7 +952,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
                               insnContext(), 
                               currentOpcode, 
                               *filter, 
                               insnContext(), 
                               currentOpcode, 
                               *filter, 
-                              UID);
+                              UID, Is32Bit);
     
       Spec->modifierType = MODIFIER_OPCODE;
       Spec->modifierBase = opcodeToSet;
     
       Spec->modifierType = MODIFIER_OPCODE;
       Spec->modifierBase = opcodeToSet;
@@ -957,14 +962,14 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
                             insnContext(), 
                             opcodeToSet, 
                             *filter, 
                             insnContext(), 
                             opcodeToSet, 
                             *filter, 
-                            UID);
+                            UID, Is32Bit);
     }
   } else {
     tables.setTableFields(opcodeType,
                           insnContext(),
                           opcodeToSet,
                           *filter,
     }
   } else {
     tables.setTableFields(opcodeType,
                           insnContext(),
                           opcodeToSet,
                           *filter,
-                          UID);
+                          UID, Is32Bit);
     
     Spec->modifierType = MODIFIER_NONE;
     Spec->modifierBase = opcodeToSet;
     
     Spec->modifierType = MODIFIER_NONE;
     Spec->modifierBase = opcodeToSet;
index 677d9f01554e02a04887e3bea229864e184333ec..390b89e03261a9942c0fc7f47ccc2518b063224b 100644 (file)
@@ -64,8 +64,10 @@ private:
   bool HasLockPrefix;
   /// The isCodeGenOnly filed from the record
   bool IsCodeGenOnly;
   bool HasLockPrefix;
   /// The isCodeGenOnly filed from the record
   bool IsCodeGenOnly;
-  // Whether the instruction has the predicate "Mode64Bit"
+  // Whether the instruction has the predicate "In64BitMode"
   bool Is64Bit;
   bool Is64Bit;
+  // Whether the instruction has the predicate "In32BitMode"
+  bool Is32Bit;
   
   /// The instruction name as listed in the tables
   std::string Name;
   
   /// The instruction name as listed in the tables
   std::string Name;