More tweaks to get the size of the X86 disassembler tables down.

llvm-svn: 150167
This commit is contained in:
Craig Topper 2012-02-09 08:58:07 +00:00
parent 410d6af994
commit a0cd970b81
3 changed files with 35 additions and 7 deletions

View 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];
}

View 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,

View 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;