diff options
Diffstat (limited to 'utils/TableGen/X86RecognizableInstr.cpp')
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 107 |
1 files changed, 58 insertions, 49 deletions
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index da2de6b320..ea78d4193e 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -24,6 +24,18 @@ using namespace llvm; +#define MRM_MAPPING \ + MAP(C1, 33) \ + MAP(C2, 34) \ + MAP(C3, 35) \ + MAP(C4, 36) \ + MAP(C8, 37) \ + MAP(C9, 38) \ + MAP(E8, 39) \ + MAP(F0, 40) \ + MAP(F8, 41) \ + MAP(F9, 42) + // A clone of X86 since we can't depend on something that is generated. namespace X86Local { enum { @@ -38,7 +50,12 @@ namespace X86Local { MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, - MRMInitReg = 32 + MRMInitReg = 32, + +#define MAP(from, to) MRM_##from = to, + MRM_MAPPING +#undef MAP + lastMRM }; enum { @@ -47,10 +64,28 @@ namespace X86Local { D8 = 3, D9 = 4, DA = 5, DB = 6, DC = 7, DD = 8, DE = 9, DF = 10, XD = 11, XS = 12, - T8 = 13, TA = 14 + T8 = 13, P_TA = 14, + P_0F_AE = 16, P_0F_01 = 17 }; } - + +// If rows are added to the opcode extension tables, then corresponding entries +// must be added here. +// +// If the row corresponds to a single byte (i.e., 8f), then add an entry for +// that byte to ONE_BYTE_EXTENSION_TABLES. +// +// If the row corresponds to two bytes where the first is 0f, add an entry for +// the second byte to TWO_BYTE_EXTENSION_TABLES. +// +// If the row corresponds to some other set of bytes, you will need to modify +// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes +// to the X86 TD files, except in two cases: if the first two bytes of such a +// new combination are 0f 38 or 0f 3a, you just have to add maps called +// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a +// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line +// in RecognizableInstr::emitDecodePath(). + #define ONE_BYTE_EXTENSION_TABLES \ EXTENSION_TABLE(80) \ EXTENSION_TABLE(81) \ @@ -81,10 +116,6 @@ namespace X86Local { EXTENSION_TABLE(b9) \ EXTENSION_TABLE(ba) \ EXTENSION_TABLE(c7) - -#define TWO_BYTE_FULL_EXTENSION_TABLES \ - EXTENSION_TABLE(01) - using namespace X86Disassembler; @@ -251,6 +282,10 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const { IsCodeGenOnly) return FILTER_STRONG; + if (Form == X86Local::MRMInitReg) + return FILTER_STRONG; + + // Filter out instructions with a LOCK prefix; // prefer forms that do not have the prefix if (HasLockPrefix) @@ -322,9 +357,6 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const { if (AsmString.find("subreg") != AsmString.npos) return FILTER_STRONG; - assert(Form != X86Local::MRMInitReg && - "FORMAT_MRMINITREG instruction not skipped"); - if (HasFROperands && Name.find("MOV") != Name.npos && ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || (Name.find("to") != Name.npos))) @@ -549,36 +581,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { // Special cases where the LLVM tables are not complete -#define EXACTCASE(class, name, lastbyte) \ - if (Name == name) { \ - tables.setTableFields(class, \ - insnContext(), \ - Opcode, \ - ExactFilter(lastbyte), \ - UID); \ - Spec->modifierBase = Opcode; \ - return; \ - } - - EXACTCASE(TWOBYTE, "MONITOR", 0xc8) - EXACTCASE(TWOBYTE, "MWAIT", 0xc9) - EXACTCASE(TWOBYTE, "SWPGS", 0xf8) - EXACTCASE(TWOBYTE, "INVEPT", 0x80) - EXACTCASE(TWOBYTE, "INVVPID", 0x81) - EXACTCASE(TWOBYTE, "VMCALL", 0xc1) - EXACTCASE(TWOBYTE, "VMLAUNCH", 0xc2) - EXACTCASE(TWOBYTE, "VMRESUME", 0xc3) - EXACTCASE(TWOBYTE, "VMXOFF", 0xc4) - - if (Name == "INVLPG") { - tables.setTableFields(TWOBYTE, - insnContext(), - Opcode, - ExtendedFilter(false, 7), - UID); - Spec->modifierBase = Opcode; - return; - } +#define MAP(from, to) \ + case X86Local::MRM_##from: \ + filter = new ExactFilter(0x##from); \ + break; OpcodeType opcodeType = (OpcodeType)-1; @@ -593,6 +599,12 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { opcodeType = TWOBYTE; switch (Opcode) { + default: + if (needsModRMForDecode(Form)) + filter = new ModFilter(isRegFormat(Form)); + else + filter = new DumbFilter(); + break; #define EXTENSION_TABLE(n) case 0x##n: TWO_BYTE_EXTENSION_TABLES #undef EXTENSION_TABLE @@ -619,16 +631,10 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::MRM7m: filter = new ExtendedFilter(false, Form - X86Local::MRM0m); break; + MRM_MAPPING } // switch (Form) break; - default: - if (needsModRMForDecode(Form)) - filter = new ModFilter(isRegFormat(Form)); - else - filter = new DumbFilter(); - - break; - } // switch (opcode) + } // switch (Opcode) opcodeToSet = Opcode; break; case X86Local::T8: @@ -639,7 +645,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { filter = new DumbFilter(); opcodeToSet = Opcode; break; - case X86Local::TA: + case X86Local::P_TA: opcodeType = THREEBYTE_3A; if (needsModRMForDecode(Form)) filter = new ModFilter(isRegFormat(Form)); @@ -696,6 +702,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::MRM7m: filter = new ExtendedFilter(false, Form - X86Local::MRM0m); break; + MRM_MAPPING } // switch (Form) break; case 0xd8: @@ -760,6 +767,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { } delete filter; + +#undef MAP } #define TYPE(str, type) if (s == str) return type; |