[llvm] r328416 - [X86] Add a new disassembler opcode map for 3DNow. Stop treating 3DNow as an attribute.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 24 00:48:54 PDT 2018


Author: ctopper
Date: Sat Mar 24 00:48:54 2018
New Revision: 328416

URL: http://llvm.org/viewvc/llvm-project?rev=328416&view=rev
Log:
[X86] Add a new disassembler opcode map for 3DNow. Stop treating 3DNow as an attribute.

This reduces the size of llvm-mc by at least 150k since we no longer have to multiply the attribute across 7 tables.

Modified:
    llvm/trunk/include/llvm/Support/X86DisassemblerDecoderCommon.h
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
    llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp
    llvm/trunk/utils/TableGen/X86DisassemblerTables.h
    llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp

Modified: llvm/trunk/include/llvm/Support/X86DisassemblerDecoderCommon.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/X86DisassemblerDecoderCommon.h?rev=328416&r1=328415&r2=328416&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/X86DisassemblerDecoderCommon.h (original)
+++ llvm/trunk/include/llvm/Support/X86DisassemblerDecoderCommon.h Sat Mar 24 00:48:54 2018
@@ -31,6 +31,7 @@ namespace X86Disassembler {
 #define XOP8_MAP_SYM      x86DisassemblerXOP8Opcodes
 #define XOP9_MAP_SYM      x86DisassemblerXOP9Opcodes
 #define XOPA_MAP_SYM      x86DisassemblerXOPAOpcodes
+#define THREEDNOW_MAP_SYM x86Disassembler3DNowOpcodes
 
 #define INSTRUCTIONS_STR  "x86DisassemblerInstrSpecifiers"
 #define CONTEXTS_STR      "x86DisassemblerContexts"
@@ -41,6 +42,7 @@ namespace X86Disassembler {
 #define XOP8_MAP_STR      "x86DisassemblerXOP8Opcodes"
 #define XOP9_MAP_STR      "x86DisassemblerXOP9Opcodes"
 #define XOPA_MAP_STR      "x86DisassemblerXOPAOpcodes"
+#define THREEDNOW_MAP_STR "x86Disassembler3DNowOpcodes"
 
 // Attributes of an instruction that must be known before the opcode can be
 // processed correctly.  Most of these indicate the presence of particular
@@ -60,8 +62,7 @@ namespace X86Disassembler {
   ENUM_ENTRY(ATTR_EVEXL2, (0x1 << 10))  \
   ENUM_ENTRY(ATTR_EVEXK,  (0x1 << 11))  \
   ENUM_ENTRY(ATTR_EVEXKZ, (0x1 << 12))  \
-  ENUM_ENTRY(ATTR_EVEXB,  (0x1 << 13))  \
-  ENUM_ENTRY(ATTR_3DNOW,  (0x1 << 14))
+  ENUM_ENTRY(ATTR_EVEXB,  (0x1 << 13))
 
 #define ENUM_ENTRY(n, v) n = v,
 enum attributeBits {
@@ -271,8 +272,7 @@ enum attributeBits {
   ENUM_ENTRY(IC_EVEX_L2_W_KZ,        3,  "requires EVEX_KZ, L2 and W")               \
   ENUM_ENTRY(IC_EVEX_L2_W_XS_KZ,     4,  "requires EVEX_KZ, L2, W and XS prefix")    \
   ENUM_ENTRY(IC_EVEX_L2_W_XD_KZ,     4,  "requires EVEX_KZ, L2, W and XD prefix")    \
-  ENUM_ENTRY(IC_EVEX_L2_W_OPSIZE_KZ, 4,  "requires EVEX_KZ, L2, W and OpSize")       \
-  ENUM_ENTRY(IC_3DNOW,               8,  "requires AMD 3DNow prefix 0f0f")
+  ENUM_ENTRY(IC_EVEX_L2_W_OPSIZE_KZ, 4,  "requires EVEX_KZ, L2, W and OpSize")
 
 #define ENUM_ENTRY(n, r, d) n,
 enum InstructionContext {
@@ -290,7 +290,8 @@ enum OpcodeType {
   THREEBYTE_3A  = 3,
   XOP8_MAP      = 4,
   XOP9_MAP      = 5,
-  XOPA_MAP      = 6
+  XOPA_MAP      = 6,
+  THREEDNOW_MAP = 7
 };
 
 // The following structs are used for the hierarchical decode table.  After

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp?rev=328416&r1=328415&r2=328416&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp Sat Mar 24 00:48:54 2018
@@ -103,6 +103,9 @@ static int modRMRequired(OpcodeType type
   case XOPA_MAP:
     decision = &XOPA_MAP_SYM;
     break;
+  case THREEDNOW_MAP:
+    decision = &THREEDNOW_MAP_SYM;
+    break;
   }
 
   return decision->opcodeDecisions[insnContext].modRMDecisions[opcode].
@@ -147,6 +150,9 @@ static InstrUID decode(OpcodeType type,
   case XOPA_MAP:
     dec = &XOPA_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
     break;
+  case THREEDNOW_MAP:
+    dec = &THREEDNOW_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
+    break;
   }
 
   switch (dec->modrm_type) {
@@ -588,44 +594,11 @@ static int readPrefixes(struct InternalI
                 insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
                 insn->vectorExtensionPrefix[2]);
     }
-  } else if (byte == 0x0f) {
-    uint8_t byte1;
-
-    // Check for AMD 3DNow without a REX prefix
-    if (consumeByte(insn, &byte1)) {
-      unconsumeByte(insn);
-    } else {
-      if (byte1 != 0x0f) {
-        unconsumeByte(insn);
-        unconsumeByte(insn);
-      } else {
-        dbgprintf(insn, "Found AMD 3DNow prefix 0f0f");
-        insn->vectorExtensionType = TYPE_3DNOW;
-      }
-    }
   } else if (isREX(insn, byte)) {
     if (lookAtByte(insn, &nextByte))
       return -1;
     insn->rexPrefix = byte;
     dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
-
-    // Check for AMD 3DNow with a REX prefix
-    if (nextByte == 0x0f) {
-      consumeByte(insn, &nextByte);
-      uint8_t byte1;
-
-      if (consumeByte(insn, &byte1)) {
-        unconsumeByte(insn);
-      } else {
-        if (byte1 != 0x0f) {
-          unconsumeByte(insn);
-          unconsumeByte(insn);
-        } else {
-          dbgprintf(insn, "Found AMD 3DNow prefix 0f0f");
-          insn->vectorExtensionType = TYPE_3DNOW;
-        }
-      }
-    }
   } else
     unconsumeByte(insn);
 
@@ -725,12 +698,6 @@ static int readOpcode(struct InternalIns
       insn->opcodeType = XOPA_MAP;
       return consumeByte(insn, &insn->opcode);
     }
-  } else if (insn->vectorExtensionType == TYPE_3DNOW) {
-    // Consume operands before the opcode to comply with the 3DNow encoding
-    if (readModRM(insn))
-      return -1;
-    insn->opcodeType = TWOBYTE;
-    return consumeByte(insn, &insn->opcode);
   }
 
   if (consumeByte(insn, &current))
@@ -756,6 +723,17 @@ static int readOpcode(struct InternalIns
         return -1;
 
       insn->opcodeType = THREEBYTE_3A;
+    } else if (current == 0x0f) {
+      dbgprintf(insn, "Found a 3dnow escape prefix (0x%hhx)", current);
+
+      // Consume operands before the opcode to comply with the 3DNow encoding
+      if (readModRM(insn))
+        return -1;
+
+      if (consumeByte(insn, &current))
+        return -1;
+
+      insn->opcodeType = THREEDNOW_MAP;
     } else {
       dbgprintf(insn, "Didn't find a three-byte escape prefix");
 
@@ -951,8 +929,6 @@ static int getID(struct InternalInstruct
 
       if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
         attrMask |= ATTR_VEXL;
-    } else if (insn->vectorExtensionType == TYPE_3DNOW) {
-      attrMask |= ATTR_3DNOW;
     } else {
       return -1;
     }

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h?rev=328416&r1=328415&r2=328416&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h Sat Mar 24 00:48:54 2018
@@ -493,8 +493,7 @@ enum VectorExtensionType {
   TYPE_VEX_2B       = 0x1,
   TYPE_VEX_3B       = 0x2,
   TYPE_EVEX         = 0x3,
-  TYPE_XOP          = 0x4,
-  TYPE_3DNOW        = 0x5
+  TYPE_XOP          = 0x4
 };
 
 /// \brief Type for the byte reader that the consumer must provide to

Modified: llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp?rev=328416&r1=328415&r2=328416&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp (original)
+++ llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Sat Mar 24 00:48:54 2018
@@ -546,8 +546,6 @@ static inline bool inheritsFrom(Instruct
   case IC_EVEX_L2_W_XD_KZ_B:
   case IC_EVEX_L2_W_OPSIZE_KZ_B:
     return false;
-  case IC_3DNOW:
-    return false;
   default:
     errs() << "Unknown instruction class: " <<
       stringForContext((InstructionContext)parent) << "\n";
@@ -882,7 +880,7 @@ void DisassemblerTables::emitInstruction
 }
 
 void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
-  const unsigned int tableSize = 32768;
+  const unsigned int tableSize = 16384;
   o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
                      "[" << tableSize << "] = {\n";
   i++;
@@ -890,9 +888,7 @@ void DisassemblerTables::emitContextTabl
   for (unsigned index = 0; index < tableSize; ++index) {
     o.indent(i * 2);
 
-    if (index & ATTR_3DNOW)
-      o << "IC_3DNOW";
-    else if (index & ATTR_EVEX) {
+    if (index & ATTR_EVEX) {
       o << "IC_EVEX";
       if (index & ATTR_EVEXL2)
         o << "_L2";
@@ -1015,6 +1011,7 @@ void DisassemblerTables::emitContextDeci
   emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR);
   emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR);
   emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR);
+  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], THREEDNOW_MAP_STR);
 }
 
 void DisassemblerTables::emit(raw_ostream &o) const {

Modified: llvm/trunk/utils/TableGen/X86DisassemblerTables.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86DisassemblerTables.h?rev=328416&r1=328415&r2=328416&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86DisassemblerTables.h (original)
+++ llvm/trunk/utils/TableGen/X86DisassemblerTables.h Sat Mar 24 00:48:54 2018
@@ -41,7 +41,8 @@ private:
   /// [4] XOP8 map opcode
   /// [5] XOP9 map opcode
   /// [6] XOPA map opcode
-  std::unique_ptr<ContextDecision> Tables[7];
+  /// [7] 3dnow map opcode
+  std::unique_ptr<ContextDecision> Tables[8];
 
   // Table of ModRM encodings.
   typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;

Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=328416&r1=328415&r2=328416&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Sat Mar 24 00:48:54 2018
@@ -288,8 +288,6 @@ InstructionContext RecognizableInstr::in
       errs() << "Instruction does not use a prefix: " << Name << "\n";
       llvm_unreachable("Invalid prefix");
     }
-  } else if (OpMap == X86Local::ThreeDNow) {
-    insnContext = IC_3DNOW;
   } else if (Is64Bit || HasREX_WPrefix || AdSize == X86Local::AdSize64) {
     if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
       insnContext = IC_64BIT_REXW_OPSIZE;
@@ -685,14 +683,14 @@ void RecognizableInstr::emitDecodePath(D
   llvm::Optional<OpcodeType> opcodeType;
   switch (OpMap) {
   default: llvm_unreachable("Invalid map!");
-  case X86Local::OB:        opcodeType = ONEBYTE;      break;
-  case X86Local::TB:        opcodeType = TWOBYTE;      break;
-  case X86Local::T8:        opcodeType = THREEBYTE_38; break;
-  case X86Local::TA:        opcodeType = THREEBYTE_3A; break;
-  case X86Local::XOP8:      opcodeType = XOP8_MAP;     break;
-  case X86Local::XOP9:      opcodeType = XOP9_MAP;     break;
-  case X86Local::XOPA:      opcodeType = XOPA_MAP;     break;
-  case X86Local::ThreeDNow: opcodeType = TWOBYTE;      break;
+  case X86Local::OB:        opcodeType = ONEBYTE;       break;
+  case X86Local::TB:        opcodeType = TWOBYTE;       break;
+  case X86Local::T8:        opcodeType = THREEBYTE_38;  break;
+  case X86Local::TA:        opcodeType = THREEBYTE_3A;  break;
+  case X86Local::XOP8:      opcodeType = XOP8_MAP;      break;
+  case X86Local::XOP9:      opcodeType = XOP9_MAP;      break;
+  case X86Local::XOPA:      opcodeType = XOPA_MAP;      break;
+  case X86Local::ThreeDNow: opcodeType = THREEDNOW_MAP; break;
   }
 
   std::unique_ptr<ModRMFilter> filter;




More information about the llvm-commits mailing list