Remove dead code. Improve llvm_unreachable text. Simplify some control flow.
[oota-llvm.git] / utils / TableGen / X86DisassemblerTables.cpp
index f42119c07405a04a628bff97dd34ab6d6b388eda..33cc017abaf36f5e1b7b2ff8ad5ed331b132eb2c 100644 (file)
@@ -56,6 +56,8 @@ static inline bool inheritsFrom(InstructionContext child,
     return inheritsFrom(child, IC_64BIT_XS);
   case IC_XD_OPSIZE:
     return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
+  case IC_XS_OPSIZE:
+    return inheritsFrom(child, IC_64BIT_XS_OPSIZE);
   case IC_64BIT_REXW:
     return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
            inheritsFrom(child, IC_64BIT_REXW_XD) ||
@@ -67,6 +69,7 @@ static inline bool inheritsFrom(InstructionContext child,
   case IC_64BIT_XS:
     return(inheritsFrom(child, IC_64BIT_REXW_XS));
   case IC_64BIT_XD_OPSIZE:
+  case IC_64BIT_XS_OPSIZE:
     return false;
   case IC_64BIT_REXW_XD:
   case IC_64BIT_REXW_XS:
@@ -92,11 +95,13 @@ static inline bool inheritsFrom(InstructionContext child,
   case IC_VEX_L:
   case IC_VEX_L_XS:
   case IC_VEX_L_XD:
+    return false;
   case IC_VEX_L_OPSIZE:
+    return inheritsFrom(child, IC_VEX_L_W_OPSIZE);
+  case IC_VEX_L_W_OPSIZE:
     return false;
   default:
     llvm_unreachable("Unknown instruction class");
-    return false;
   }
 }
 
@@ -135,8 +140,6 @@ static inline const char* stringForContext(InstructionContext insnContext) {
   INSTRUCTION_CONTEXTS
 #undef ENUM_ENTRY
   }
-
-  return 0;
 }
 
 /// stringForOperandType - Like stringForContext, but for OperandTypes.
@@ -191,8 +194,7 @@ void DisassemblerTables::emitOneID(raw_ostream &o,
 /// @param i        - The indentation level for that output stream.
 static void emitEmptyTable(raw_ostream &o, uint32_t &i)
 {
-  o.indent(i * 2) << "static const InstrUID modRMEmptyTable[1] = { 0 };\n";
-  o << "\n";
+  o.indent(i * 2) << "0x0, /* EmptyTable */\n";
 }
 
 /// getDecisionType - Determines whether a ModRM decision with 255 entries can
@@ -204,28 +206,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;
 }
 
@@ -288,71 +302,76 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1,
                                            ModRMDecision &decision)
   const {
   static uint64_t sTableNumber = 0;
-  uint64_t thisTableNumber = sTableNumber;
+  static uint64_t sEntryNumber = 1;
   ModRMDecisionType dt = getDecisionType(decision);
   uint16_t index;
-  
+
   if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
   {
     o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
     i2++;
-    
+
     o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
-    o2.indent(i2) << "modRMEmptyTable";
-    
+    o2.indent(i2) << 0 << " /* EmptyTable */\n";
+
     i2--;
     o2.indent(i2) << "}";
     return;
   }
-    
-  o1.indent(i1) << "static const InstrUID modRMTable" << thisTableNumber;
-    
-  switch (dt) {
-    default:
-      llvm_unreachable("Unknown decision type");
-    case MODRM_ONEENTRY:
-      o1 << "[1]";
-      break;
-    case MODRM_SPLITRM:
-      o1 << "[2]";
-      break;
-    case MODRM_FULL:
-      o1 << "[256]";
-      break;      
-  }
 
-  o1 << " = {" << "\n";
+  o1 << "/* Table" << sTableNumber << " */\n";
   i1++;
-    
+
   switch (dt) {
     default:
       llvm_unreachable("Unknown decision type");
     case MODRM_ONEENTRY:
-      emitOneID(o1, i1, decision.instructionIDs[0], false);
+      emitOneID(o1, i1, decision.instructionIDs[0], true);
       break;
     case MODRM_SPLITRM:
       emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
-      emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11
+      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], index < 255);
+        emitOneID(o1, i1, decision.instructionIDs[index], true);
       break;
   }
-    
+
   i1--;
-  o1.indent(i1) << "};" << "\n";
-  o1 << "\n";
-    
+
   o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
   i2++;
-    
+
   o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
-  o2.indent(i2) << "modRMTable" << sTableNumber << "\n";
-    
+  o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n";
+
   i2--;
   o2.indent(i2) << "}";
-    
+
+  switch (dt) {
+    default:
+      llvm_unreachable("Unknown decision type");
+    case MODRM_ONEENTRY:
+      sEntryNumber += 1;
+      break;
+    case MODRM_SPLITRM:
+      sEntryNumber += 2;
+      break;
+    case MODRM_SPLITREG:
+      sEntryNumber += 16;
+      break;
+    case MODRM_FULL:
+      sEntryNumber += 256;
+      break;
+  }
+
   ++sTableNumber;
 }
 
@@ -465,7 +484,7 @@ void DisassemblerTables::emitInstructionInfo(raw_ostream &o, uint32_t &i)
     i--;
     o.indent(i * 2) << "}," << "\n";
     
-    o.indent(i * 2) << "\"" << InstructionSpecifiers[index].name << "\"";
+    o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */";
     o << "\n";
 
     i--;
@@ -491,7 +510,9 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
   for (index = 0; index < 256; ++index) {
     o.indent(i * 2);
 
-    if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
+    if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
+      o << "IC_VEX_L_W_OPSIZE";
+    else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
       o << "IC_VEX_L_OPSIZE";
     else if ((index & ATTR_VEXL) && (index & ATTR_XD))
       o << "IC_VEX_L_XD";
@@ -524,6 +545,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
       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) && (index & ATTR_OPSIZE))
+      o << "IC_64BIT_XS_OPSIZE";
     else if ((index & ATTR_64BIT) && (index & ATTR_XS))
       o << "IC_64BIT_XS";
     else if ((index & ATTR_64BIT) && (index & ATTR_XD))
@@ -534,6 +557,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_XS) && (index & ATTR_OPSIZE))
+      o << "IC_XS_OPSIZE";
     else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
       o << "IC_XD_OPSIZE";
     else if (index & ATTR_XS)
@@ -587,11 +612,16 @@ void DisassemblerTables::emit(raw_ostream &o) const {
 
   emitContextTable(o, i2);
   o << "\n";
-  
+
+  o << "static const InstrUID modRMTable[] = {\n";
+  i1++;
   emitEmptyTable(o1, i1);
+  i1--;
   emitContextDecisions(o1, o2, i1, i2);
-  
+
   o << o1.str();
+  o << "  0x0\n";
+  o << "};\n";
   o << "\n";
   o << o2.str();
   o << "\n";