Reworked the Intel disassembler to support instructions
authorSean Callanan <scallanan@apple.com>
Fri, 12 Feb 2010 23:39:46 +0000 (23:39 +0000)
committerSean Callanan <scallanan@apple.com>
Fri, 12 Feb 2010 23:39:46 +0000 (23:39 +0000)
whose opcodes extend into the ModR/M field using the
Form field of the instruction rather than by special
casing each instruction.  Commented out the special
casing of VMCALL, which is the first instruction to use
this special form.  While I was in the neighborhood,
added a few comments for people modifying the Intel
disassembler.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96043 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/X86RecognizableInstr.cpp

index 1e14cd19b91ec3cc206330e520a07a9476192bd1..535cd6c7d0f1127da1ab759017180f4c7888683e 100644 (file)
 
 using namespace llvm;
 
+#define MRM_MAPPING     \
+  MAP(C1, 33)           \
+  MAP(C8, 34)           \
+  MAP(C9, 35)           \
+  MAP(E8, 36)           \
+  MAP(F0, 37)
+
 // A clone of X86 since we can't depend on something that is generated.
 namespace X86Local {
   enum {
@@ -38,7 +45,12 @@ namespace X86Local {
     MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
     MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
     MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
-    MRMInitReg  = 32
+    MRMInitReg  = 32,
+    
+#define MAP(from, to) MRM_##from = to,
+    MRM_MAPPING
+#undef MAP
+    lastMRM
   };
   
   enum {
@@ -51,7 +63,24 @@ namespace X86Local {
     P_0F_AE = 16, P_0F_01 = 17
   };
 }
-  
+
+// If rows are added to the opcode extension tables, then corresponding entries
+// must be added here.  
+//
+// If the row corresponds to a single byte (i.e., 8f), then add an entry for
+// that byte to ONE_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to two bytes where the first is 0f, add an entry for 
+// the second byte to TWO_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to some other set of bytes, you will need to modify
+// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
+// to the X86 TD files, except in two cases: if the first two bytes of such a 
+// new combination are 0f 38 or 0f 3a, you just have to add maps called
+// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
+// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
+// in RecognizableInstr::emitDecodePath().
+
 #define ONE_BYTE_EXTENSION_TABLES \
   EXTENSION_TABLE(80)             \
   EXTENSION_TABLE(81)             \
@@ -82,10 +111,6 @@ namespace X86Local {
   EXTENSION_TABLE(b9)             \
   EXTENSION_TABLE(ba)             \
   EXTENSION_TABLE(c7)
-  
-#define TWO_BYTE_FULL_EXTENSION_TABLES \
-  EXTENSION_TABLE(01)
-  
 
 using namespace X86Disassembler;
 
@@ -550,23 +575,28 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
 void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
   // Special cases where the LLVM tables are not complete
 
-#define EXACTCASE(class, name, lastbyte)         \
-  if (Name == name) {                           \
-    tables.setTableFields(class,                 \
-                          insnContext(),         \
-                          Opcode,               \
-                          ExactFilter(lastbyte), \
-                          UID);                 \
-    Spec->modifierBase = Opcode;               \
-    return;                                      \
-  } 
+#define MAP(from, to)                     \
+  case X86Local::MRM_##from:              \
+    filter = new ExactFilter(0x##from);   \
+    break;
+  
+#define EXACTCASE(class, name, lastbyte)          \
+  if (Name == name) {                             \
+    tables.setTableFields(class,                  \
+                          insnContext(),          \
+                          Opcode,                 \
+                          ExactFilter(lastbyte),  \
+                          UID);                   \
+    Spec->modifierBase = Opcode;                  \
+    return;                                       \
+  }
 
   EXACTCASE(TWOBYTE, "MONITOR",  0xc8)
   EXACTCASE(TWOBYTE, "MWAIT",    0xc9)
   EXACTCASE(TWOBYTE, "SWPGS",    0xf8)
   EXACTCASE(TWOBYTE, "INVEPT",   0x80)
   EXACTCASE(TWOBYTE, "INVVPID",  0x81)
-  EXACTCASE(TWOBYTE, "VMCALL",   0xc1)
+  //EXACTCASE(TWOBYTE, "VMCALL",   0xc1) - Handled by MRM_ form; safe to remove
   EXACTCASE(TWOBYTE, "VMLAUNCH", 0xc2)
   EXACTCASE(TWOBYTE, "VMRESUME", 0xc3)
   EXACTCASE(TWOBYTE, "VMXOFF",   0xc4)
@@ -620,6 +650,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
       case X86Local::MRM7m:
         filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
         break;
+      MRM_MAPPING
       } // switch (Form)
       break;
     default:
@@ -697,6 +728,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
       case X86Local::MRM7m:
         filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
         break;
+      MRM_MAPPING
       } // switch (Form)
       break;
     case 0xd8:
@@ -761,6 +793,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
   }
   
   delete filter;
+  
+#undef MAP
 }
 
 #define TYPE(str, type) if (s == str) return type;