X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FX86DisassemblerTables.cpp;h=40a0c1b260b726b1ecffd5a4d286be777b2eeeeb;hb=4ffd89fa4d2788611187d1a534d2ed46adf1702c;hp=e7b608306c8d4522c774a8206a8481fd7058509b;hpb=7c788888872233748da10a8177a9a1eb176c1bc8;p=oota-llvm.git diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index e7b608306c8..40a0c1b260b 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -14,17 +14,17 @@ // //===----------------------------------------------------------------------===// -#include "X86DisassemblerShared.h" #include "X86DisassemblerTables.h" - -#include "llvm/TableGen/TableGenBackend.h" +#include "X86DisassemblerShared.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/TableGen/TableGenBackend.h" +#include using namespace llvm; using namespace X86Disassembler; - + /// inheritsFrom - Indicates whether all instructions in one class also belong /// to another class. /// @@ -32,27 +32,37 @@ using namespace X86Disassembler; /// @param parent - The class that may be the superset /// @return - True if child is a subset of parent, false otherwise. static inline bool inheritsFrom(InstructionContext child, - InstructionContext parent) { + InstructionContext parent, + bool VEX_LIG = false) { if (child == parent) return true; - + switch (parent) { case IC: return(inheritsFrom(child, IC_64BIT) || inheritsFrom(child, IC_OPSIZE) || + inheritsFrom(child, IC_ADSIZE) || inheritsFrom(child, IC_XD) || inheritsFrom(child, IC_XS)); case IC_64BIT: return(inheritsFrom(child, IC_64BIT_REXW) || inheritsFrom(child, IC_64BIT_OPSIZE) || + inheritsFrom(child, IC_64BIT_ADSIZE) || inheritsFrom(child, IC_64BIT_XD) || inheritsFrom(child, IC_64BIT_XS)); case IC_OPSIZE: return inheritsFrom(child, IC_64BIT_OPSIZE); + case IC_ADSIZE: + case IC_64BIT_ADSIZE: + return false; case IC_XD: return inheritsFrom(child, IC_64BIT_XD); case IC_XS: 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) || @@ -63,39 +73,40 @@ static inline bool inheritsFrom(InstructionContext child, return(inheritsFrom(child, IC_64BIT_REXW_XD)); case IC_64BIT_XS: return(inheritsFrom(child, IC_64BIT_REXW_XS)); - case IC_64BIT_REXW_XD: + case IC_64BIT_XD_OPSIZE: + case IC_64BIT_XS_OPSIZE: return false; + case IC_64BIT_REXW_XD: case IC_64BIT_REXW_XS: - return false; case IC_64BIT_REXW_OPSIZE: return false; case IC_VEX: - return inheritsFrom(child, IC_VEX_W); + return inheritsFrom(child, IC_VEX_W) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L)); case IC_VEX_XS: - return inheritsFrom(child, IC_VEX_W_XS); + return inheritsFrom(child, IC_VEX_W_XS) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); case IC_VEX_XD: - return inheritsFrom(child, IC_VEX_W_XD); + return inheritsFrom(child, IC_VEX_W_XD) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); case IC_VEX_OPSIZE: - return inheritsFrom(child, IC_VEX_W_OPSIZE); + return inheritsFrom(child, IC_VEX_W_OPSIZE) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); case IC_VEX_W: - return false; case IC_VEX_W_XS: - return false; case IC_VEX_W_XD: - return false; case IC_VEX_W_OPSIZE: return false; case IC_VEX_L: - return false; case IC_VEX_L_XS: - return false; 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; } } @@ -106,17 +117,17 @@ static inline bool inheritsFrom(InstructionContext child, /// @param upper - The class that may be preferable /// @param lower - The class that may be less preferable /// @return - True if upper is to be preferred, false otherwise. -static inline bool outranks(InstructionContext upper, +static inline bool outranks(InstructionContext upper, InstructionContext lower) { assert(upper < IC_max); assert(lower < IC_max); - + #define ENUM_ENTRY(n, r, d) r, static int ranks[IC_max] = { INSTRUCTION_CONTEXTS }; #undef ENUM_ENTRY - + return (ranks[upper] > ranks[lower]); } @@ -134,8 +145,6 @@ static inline const char* stringForContext(InstructionContext insnContext) { INSTRUCTION_CONTEXTS #undef ENUM_ENTRY } - - return 0; } /// stringForOperandType - Like stringForContext, but for OperandTypes. @@ -161,24 +170,22 @@ static inline const char* stringForOperandEncoding(OperandEncoding encoding) { } } -void DisassemblerTables::emitOneID(raw_ostream &o, - uint32_t &i, - InstrUID id, +void DisassemblerTables::emitOneID(raw_ostream &o, unsigned &i, InstrUID id, bool addComma) const { if (id) o.indent(i * 2) << format("0x%hx", id); else o.indent(i * 2) << 0; - + if (addComma) o << ", "; else o << " "; - + o << "/* "; o << InstructionSpecifiers[id].name; o << "*/"; - + o << "\n"; } @@ -188,10 +195,8 @@ void DisassemblerTables::emitOneID(raw_ostream &o, /// /// @param o - The output stream on which to emit the table. /// @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"; +static void emitEmptyTable(raw_ostream &o, unsigned &i) { + o.indent(i * 2) << "0x0, /* EmptyTable */\n"; } /// getDecisionType - Determines whether a ModRM decision with 255 entries can @@ -199,32 +204,45 @@ static void emitEmptyTable(raw_ostream &o, uint32_t &i) /// /// @param decision - The decision to be compacted. /// @return - The compactest available representation for the decision. -static ModRMDecisionType getDecisionType(ModRMDecision &decision) -{ +static ModRMDecisionType getDecisionType(ModRMDecision &decision) { bool satisfiesOneEntry = true; bool satisfiesSplitRM = true; - - uint16_t index; - - for (index = 0; index < 256; ++index) { + bool satisfiesSplitReg = true; + bool satisfiesSplitMisc = true; + + for (unsigned 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])) + satisfiesSplitMisc = false; } - + if (satisfiesOneEntry) return MODRM_ONEENTRY; - + if (satisfiesSplitRM) return MODRM_SPLITRM; - + + if (satisfiesSplitReg && satisfiesSplitMisc) + return MODRM_SPLITREG; + + if (satisfiesSplitMisc) + return MODRM_SPLITMISC; + return MODRM_FULL; } @@ -232,27 +250,25 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) /// to a particular decision type. /// /// @param dt - The decision type. -/// @return - A pointer to the statically-allocated string (e.g., +/// @return - A pointer to the statically-allocated string (e.g., /// "MODRM_ONEENTRY" for MODRM_ONEENTRY). -static const char* stringForDecisionType(ModRMDecisionType dt) -{ +static const char* stringForDecisionType(ModRMDecisionType dt) { #define ENUM_ENTRY(n) case n: return #n; switch (dt) { default: - llvm_unreachable("Unknown decision type"); + llvm_unreachable("Unknown decision type"); MODRMTYPES - }; + }; #undef ENUM_ENTRY } - + /// stringForModifierType - Returns a statically-allocated string corresponding /// to an opcode modifier type. /// /// @param mt - The modifier type. /// @return - A pointer to the statically-allocated string (e.g., /// "MODIFIER_NONE" for MODIFIER_NONE). -static const char* stringForModifierType(ModifierType mt) -{ +static const char* stringForModifierType(ModifierType mt) { #define ENUM_ENTRY(n) case n: return #n; switch(mt) { default: @@ -261,114 +277,123 @@ static const char* stringForModifierType(ModifierType mt) }; #undef ENUM_ENTRY } - + DisassemblerTables::DisassemblerTables() { unsigned i; - + for (i = 0; i < array_lengthof(Tables); i++) { Tables[i] = new ContextDecision; memset(Tables[i], 0, sizeof(ContextDecision)); } - + HasConflicts = false; } - + DisassemblerTables::~DisassemblerTables() { unsigned i; - + for (i = 0; i < array_lengthof(Tables); i++) delete Tables[i]; } - -void DisassemblerTables::emitModRMDecision(raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2, - ModRMDecision &decision) - const { - static uint64_t sTableNumber = 0; - uint64_t thisTableNumber = sTableNumber; + +void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, + ModRMDecision &decision) const { + static uint32_t sTableNumber = 0; + static uint32_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; - + + o1 << "/* Table" << sTableNumber << " */\n"; + i1++; + switch (dt) { default: llvm_unreachable("Unknown decision type"); case MODRM_ONEENTRY: - o1 << "[1]"; + emitOneID(o1, i1, decision.instructionIDs[0], true); break; case MODRM_SPLITRM: - o1 << "[2]"; + emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 + emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11 + break; + case MODRM_SPLITREG: + for (unsigned index = 0; index < 64; index += 8) + emitOneID(o1, i1, decision.instructionIDs[index], true); + 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: - o1 << "[256]"; - break; + for (unsigned index = 0; index < 256; ++index) + emitOneID(o1, i1, decision.instructionIDs[index], true); + break; } - o1 << " = {" << "\n"; - i1++; - + i1--; + + o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; + i2++; + + o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; + o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n"; + + i2--; + o2.indent(i2) << "}"; + switch (dt) { default: llvm_unreachable("Unknown decision type"); case MODRM_ONEENTRY: - emitOneID(o1, i1, decision.instructionIDs[0], false); + sEntryNumber += 1; break; case MODRM_SPLITRM: - emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 - emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11 + sEntryNumber += 2; + break; + case MODRM_SPLITREG: + sEntryNumber += 16; + break; + case MODRM_SPLITMISC: + sEntryNumber += 8 + 64; break; case MODRM_FULL: - for (index = 0; index < 256; ++index) - emitOneID(o1, i1, decision.instructionIDs[index], index < 255); + sEntryNumber += 256; 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"; - - i2--; - o2.indent(i2) << "}"; - + + // We assume that the index can fit into uint16_t. + assert(sEntryNumber < 65536U && + "Index into ModRMDecision is too large for uint16_t!"); + ++sTableNumber; } -void DisassemblerTables::emitOpcodeDecision( - raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2, - OpcodeDecision &decision) const { - uint16_t index; - +void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, + OpcodeDecision &decision) const { o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; i2++; o2.indent(i2) << "{" << "\n"; i2++; - for (index = 0; index < 256; ++index) { + for (unsigned index = 0; index < 256; ++index) { o2.indent(i2); o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; @@ -387,21 +412,16 @@ void DisassemblerTables::emitOpcodeDecision( o2.indent(i2) << "}" << "\n"; } -void DisassemblerTables::emitContextDecision( - raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2, - ContextDecision &decision, - const char* name) const { +void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, + ContextDecision &decision, + const char* name) const { o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; i2++; o2.indent(i2) << "{ /* opcodeDecisions */" << "\n"; i2++; - unsigned index; - - for (index = 0; index < IC_max; ++index) { + for (unsigned index = 0; index < IC_max; ++index) { o2.indent(i2) << "/* "; o2 << stringForContext((InstructionContext)index); o2 << " */"; @@ -419,58 +439,81 @@ void DisassemblerTables::emitContextDecision( o2.indent(i2) << "};" << "\n"; } -void DisassemblerTables::emitInstructionInfo(raw_ostream &o, uint32_t &i) - const { +void DisassemblerTables::emitInstructionInfo(raw_ostream &o, + unsigned &i) const { + unsigned NumInstructions = InstructionSpecifiers.size(); + + o << "static const struct OperandSpecifier x86OperandSets[][" + << X86_MAX_OPERANDS << "] = {\n"; + + typedef std::vector > OperandListTy; + std::map OperandSets; + + unsigned OperandSetNum = 0; + for (unsigned Index = 0; Index < NumInstructions; ++Index) { + OperandListTy OperandList; + + for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; + ++OperandIndex) { + const char *Encoding = + stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index] + .operands[OperandIndex].encoding); + const char *Type = + stringForOperandType((OperandType)InstructionSpecifiers[Index] + .operands[OperandIndex].type); + OperandList.push_back(std::make_pair(Encoding, Type)); + } + unsigned &N = OperandSets[OperandList]; + if (N != 0) continue; + + N = ++OperandSetNum; + + o << " { /* " << (OperandSetNum - 1) << " */\n"; + for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { + o << " { " << OperandList[i].first << ", " + << OperandList[i].second << " },\n"; + } + o << " },\n"; + } + o << "};" << "\n\n"; + o.indent(i * 2) << "static const struct InstructionSpecifier "; o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; - - i++; - uint16_t numInstructions = InstructionSpecifiers.size(); - uint16_t index, operandIndex; + i++; - for (index = 0; index < numInstructions; ++index) { + for (unsigned index = 0; index < NumInstructions; ++index) { o.indent(i * 2) << "{ /* " << index << " */" << "\n"; i++; - - o.indent(i * 2) << - stringForModifierType(InstructionSpecifiers[index].modifierType); - o << "," << "\n"; - - o.indent(i * 2) << "0x"; - o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase); - o << "," << "\n"; - o.indent(i * 2) << "{" << "\n"; - i++; + o.indent(i * 2) << stringForModifierType( + (ModifierType)InstructionSpecifiers[index].modifierType); + o << ",\n"; - for (operandIndex = 0; operandIndex < X86_MAX_OPERANDS; ++operandIndex) { - o.indent(i * 2) << "{ "; - o << stringForOperandEncoding(InstructionSpecifiers[index] - .operands[operandIndex] - .encoding); - o << ", "; - o << stringForOperandType(InstructionSpecifiers[index] - .operands[operandIndex] - .type); - o << " }"; - - if (operandIndex < X86_MAX_OPERANDS - 1) - o << ","; - - o << "\n"; + o.indent(i * 2) << "0x"; + o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase); + o << ",\n"; + + OperandListTy OperandList; + for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; + ++OperandIndex) { + const char *Encoding = + stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index] + .operands[OperandIndex].encoding); + const char *Type = + stringForOperandType((OperandType)InstructionSpecifiers[index] + .operands[OperandIndex].type); + OperandList.push_back(std::make_pair(Encoding, Type)); } + o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; - i--; - o.indent(i * 2) << "}," << "\n"; - - o.indent(i * 2) << "\"" << InstructionSpecifiers[index].name << "\""; + o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */"; o << "\n"; i--; o.indent(i * 2) << "}"; - if (index + 1 < numInstructions) + if (index + 1 < NumInstructions) o << ","; o << "\n"; @@ -480,17 +523,17 @@ void DisassemblerTables::emitInstructionInfo(raw_ostream &o, uint32_t &i) o.indent(i * 2) << "};" << "\n"; } -void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { - uint16_t index; - - o.indent(i * 2) << "static const InstructionContext " CONTEXTS_STR +void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { + o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR "[256] = {\n"; i++; - for (index = 0; index < 256; ++index) { + for (unsigned 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"; @@ -518,25 +561,37 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { o << "IC_64BIT_REXW_XS"; else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) o << "IC_64BIT_REXW_XD"; - else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && + else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 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)) o << "IC_64BIT_XD"; else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) o << "IC_64BIT_OPSIZE"; + else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) + o << "IC_64BIT_ADSIZE"; else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 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) o << "IC_XS"; else if (index & ATTR_XD) o << "IC_XD"; else if (index & ATTR_OPSIZE) o << "IC_OPSIZE"; + else if (index & ATTR_ADSIZE) + o << "IC_ADSIZE"; else o << "IC"; @@ -554,11 +609,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { o.indent(i * 2) << "};" << "\n"; } -void DisassemblerTables::emitContextDecisions(raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2) - const { +void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2) const { emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR); emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR); emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR); @@ -568,25 +620,30 @@ void DisassemblerTables::emitContextDecisions(raw_ostream &o1, } void DisassemblerTables::emit(raw_ostream &o) const { - uint32_t i1 = 0; - uint32_t i2 = 0; - + unsigned i1 = 0; + unsigned i2 = 0; + std::string s1; std::string s2; - + raw_string_ostream o1(s1); raw_string_ostream o2(s2); - + emitInstructionInfo(o, i2); o << "\n"; 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"; @@ -597,9 +654,7 @@ void DisassemblerTables::setTableFields(ModRMDecision &decision, const ModRMFilter &filter, InstrUID uid, uint8_t opcode) { - unsigned index; - - for (index = 0; index < 256; ++index) { + for (unsigned index = 0; index < 256; ++index) { if (filter.accepts(index)) { if (decision.instructionIDs[index] == uid) continue; @@ -609,18 +664,19 @@ void DisassemblerTables::setTableFields(ModRMDecision &decision, InstructionSpecifiers[uid]; InstructionSpecifier &previousInfo = InstructionSpecifiers[decision.instructionIDs[index]]; - + if(newInfo.filtered) continue; // filtered instructions get lowest priority - + if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || newInfo.name == "XCHG32ar" || + newInfo.name == "XCHG32ar64" || newInfo.name == "XCHG64ar")) continue; // special case for XCHG*ar and NOOP if (outranks(previousInfo.insnContext, newInfo.insnContext)) continue; - + if (previousInfo.insnContext == newInfo.insnContext && !previousInfo.filtered) { errs() << "Error: Primary decode conflict: "; @@ -643,18 +699,17 @@ void DisassemblerTables::setTableFields(OpcodeType type, uint8_t opcode, const ModRMFilter &filter, InstrUID uid, - bool is32bit) { - unsigned index; - + bool is32bit, + bool ignoresVEX_L) { ContextDecision &decision = *Tables[type]; - for (index = 0; index < IC_max; ++index) { + for (unsigned index = 0; index < IC_max; ++index) { if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT)) continue; - if (inheritsFrom((InstructionContext)index, - InstructionSpecifiers[uid].insnContext)) - setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], + if (inheritsFrom((InstructionContext)index, + InstructionSpecifiers[uid].insnContext, ignoresVEX_L)) + setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], filter, uid, opcode);