aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2012-09-13 05:45:42 +0000
committerCraig Topper <craig.topper@gmail.com>2012-09-13 05:45:42 +0000
commit76b29b518dad5e719077a1066e242fa91f777a7c (patch)
tree4d4219f3a5859b42b605958219d94dfd631f3e5f
parent7639f98c5fc903339bf50e574aee999d54340cdf (diff)
downloadexternal_llvm-76b29b518dad5e719077a1066e242fa91f777a7c.zip
external_llvm-76b29b518dad5e719077a1066e242fa91f777a7c.tar.gz
external_llvm-76b29b518dad5e719077a1066e242fa91f777a7c.tar.bz2
Add a new compression type to ModRM table that detects when the memory modRM byte represent 8 instructions and the reg modRM byte represents up to 64 instructions. Reduces modRM table from 43k entreis to 25k entries. Based on a patch from Manman Ren.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163774 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoder.c4
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h5
-rw-r--r--utils/TableGen/X86DisassemblerTables.cpp17
3 files changed, 24 insertions, 2 deletions
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
index af444d1..b24f517 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
@@ -138,6 +138,10 @@ static InstrUID decode(OpcodeType type,
if (modFromModRM(modRM) == 0x3)
return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)+8];
return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
+ case MODRM_SPLITMISC:
+ if (modFromModRM(modRM) == 0x3)
+ return modRMTable[dec->instructionIDs+(modRM & 0x3f)+8];
+ return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
case MODRM_FULL:
return modRMTable[dec->instructionIDs+modRM];
}
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
index b0a0e1e..23dfe4b 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
@@ -160,6 +160,10 @@ 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_SPLITMISC- If the ModR/M byte is between 0x00 and 0xbf, ModR/M byte
+ * divided by 8 is used to select instruction; otherwise, each
+ * value of the ModR/M byte could correspond 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
@@ -169,6 +173,7 @@ typedef uint16_t InstrUID;
#define MODRMTYPES \
ENUM_ENTRY(MODRM_ONEENTRY) \
ENUM_ENTRY(MODRM_SPLITRM) \
+ ENUM_ENTRY(MODRM_SPLITMISC) \
ENUM_ENTRY(MODRM_SPLITREG) \
ENUM_ENTRY(MODRM_FULL)
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp
index 8526621..468a1f8 100644
--- a/utils/TableGen/X86DisassemblerTables.cpp
+++ b/utils/TableGen/X86DisassemblerTables.cpp
@@ -209,6 +209,7 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) {
bool satisfiesOneEntry = true;
bool satisfiesSplitRM = true;
bool satisfiesSplitReg = true;
+ bool satisfiesSplitMisc = true;
for (unsigned index = 0; index < 256; ++index) {
if (decision.instructionIDs[index] != decision.instructionIDs[0])
@@ -228,7 +229,7 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) {
if (((index & 0xc0) != 0xc0) &&
(decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
- satisfiesSplitReg = false;
+ satisfiesSplitMisc = false;
}
if (satisfiesOneEntry)
@@ -237,9 +238,12 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) {
if (satisfiesSplitRM)
return MODRM_SPLITRM;
- if (satisfiesSplitReg)
+ if (satisfiesSplitReg && satisfiesSplitMisc)
return MODRM_SPLITREG;
+ if (satisfiesSplitMisc)
+ return MODRM_SPLITMISC;
+
return MODRM_FULL;
}
@@ -332,6 +336,12 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
for (unsigned index = 0xc0; index < 256; index += 8)
emitOneID(o1, i1, decision.instructionIDs[index], true);
break;
+ case MODRM_SPLITMISC:
+ for (unsigned index = 0; index < 64; index += 8)
+ emitOneID(o1, i1, decision.instructionIDs[index], true);
+ for (unsigned index = 0xc0; index < 256; ++index)
+ emitOneID(o1, i1, decision.instructionIDs[index], true);
+ break;
case MODRM_FULL:
for (unsigned index = 0; index < 256; ++index)
emitOneID(o1, i1, decision.instructionIDs[index], true);
@@ -361,6 +371,9 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
case MODRM_SPLITREG:
sEntryNumber += 16;
break;
+ case MODRM_SPLITMISC:
+ sEntryNumber += 8 + 64;
+ break;
case MODRM_FULL:
sEntryNumber += 256;
break;