More tweaks to get the size of the X86 disassembler tables down.
authorCraig Topper <craig.topper@gmail.com>
Thu, 9 Feb 2012 08:58:07 +0000 (08:58 +0000)
committerCraig Topper <craig.topper@gmail.com>
Thu, 9 Feb 2012 08:58:07 +0000 (08:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150167 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
utils/TableGen/X86DisassemblerTables.cpp

index 9a628f2163d0ba3b2c3391b1238b402c2b6dacff..a7becdb2c70cb4bd4fb35a747e7128fd29789616 100644 (file)
@@ -136,6 +136,10 @@ static InstrUID decode(OpcodeType type,
     if (modFromModRM(modRM) == 0x3)
       return modRMTable[dec->instructionIDs+1];
     return modRMTable[dec->instructionIDs];
+  case MODRM_SPLITREG:
+    if (modFromModRM(modRM) == 0x3)
+      return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)+8];
+    return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
   case MODRM_FULL:
     return modRMTable[dec->instructionIDs+modRM];
   }
index a7ef0cc4325dafdfa79f5ee4144b0263590452e0..d6b23c0af4f1dc183c995c9a66991c7bd5cbbab5 100644 (file)
@@ -156,6 +156,8 @@ typedef uint16_t InstrUID;
  * MODRM_SPLITRM  - If the ModR/M byte is between 0x00 and 0xbf, the opcode
  *                  corresponds to one instruction; otherwise, it corresponds to
  *                  a different instruction.
+ * MODRM_SPLITREG - ModR/M byte divided by 8 is used to select instruction. This
+                    corresponds to instructions that use reg field as opcode
  * MODRM_FULL     - Potentially, each value of the ModR/M byte could correspond
  *                  to a different instruction.
  */
@@ -163,6 +165,7 @@ typedef uint16_t InstrUID;
 #define MODRMTYPES            \
   ENUM_ENTRY(MODRM_ONEENTRY)  \
   ENUM_ENTRY(MODRM_SPLITRM)   \
+  ENUM_ENTRY(MODRM_SPLITREG)  \
   ENUM_ENTRY(MODRM_FULL)
 
 #define ENUM_ENTRY(n) n,    
index 7db39b8481d631413bbf510f88414585aee2bf65..b5f970d3548cfe4df94ec427ec5ef19044e006dc 100644 (file)
@@ -208,28 +208,40 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision)
 {
   bool satisfiesOneEntry = true;
   bool satisfiesSplitRM = true;
-  
+  bool satisfiesSplitReg = true;
+
   uint16_t index;
-  
+
   for (index = 0; index < 256; ++index) {
     if (decision.instructionIDs[index] != decision.instructionIDs[0])
       satisfiesOneEntry = false;
-    
+
     if (((index & 0xc0) == 0xc0) &&
        (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
       satisfiesSplitRM = false;
-    
+
     if (((index & 0xc0) != 0xc0) &&
        (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
       satisfiesSplitRM = false;
+
+    if (((index & 0xc0) == 0xc0) &&
+       (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8]))
+      satisfiesSplitReg = false;
+
+    if (((index & 0xc0) != 0xc0) &&
+       (decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
+      satisfiesSplitReg = false;
   }
-  
+
   if (satisfiesOneEntry)
     return MODRM_ONEENTRY;
-  
+
   if (satisfiesSplitRM)
     return MODRM_SPLITRM;
-  
+
+  if (satisfiesSplitReg)
+    return MODRM_SPLITREG;
+
   return MODRM_FULL;
 }
 
@@ -322,6 +334,12 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1,
       emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
       emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11
       break;
+    case MODRM_SPLITREG:
+      for (index = 0; index < 64; index += 8)
+        emitOneID(o1, i1, decision.instructionIDs[index], true);
+      for (index = 0xc0; index < 256; index += 8)
+        emitOneID(o1, i1, decision.instructionIDs[index], true);
+      break;
     case MODRM_FULL:
       for (index = 0; index < 256; ++index)
         emitOneID(o1, i1, decision.instructionIDs[index], true);
@@ -348,6 +366,9 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1,
     case MODRM_SPLITRM:
       sEntryNumber += 2;
       break;
+    case MODRM_SPLITREG:
+      sEntryNumber += 16;
+      break;
     case MODRM_FULL:
       sEntryNumber += 256;
       break;