mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 17:31:50 +00:00
Reworked the Intel disassembler to support instructions
whose opcodes extend into the ModR/M field using the Form field of the instruction rather than by special casing each instruction. Commented out the special casing of VMCALL, which is the first instruction to use this special form. While I was in the neighborhood, added a few comments for people modifying the Intel disassembler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96043 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4a2e5edb94
commit
9492be8d10
@ -24,6 +24,13 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define MRM_MAPPING \
|
||||
MAP(C1, 33) \
|
||||
MAP(C8, 34) \
|
||||
MAP(C9, 35) \
|
||||
MAP(E8, 36) \
|
||||
MAP(F0, 37)
|
||||
|
||||
// A clone of X86 since we can't depend on something that is generated.
|
||||
namespace X86Local {
|
||||
enum {
|
||||
@ -38,7 +45,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 {
|
||||
@ -51,7 +63,24 @@ namespace X86Local {
|
||||
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) \
|
||||
@ -82,10 +111,6 @@ namespace X86Local {
|
||||
EXTENSION_TABLE(b9) \
|
||||
EXTENSION_TABLE(ba) \
|
||||
EXTENSION_TABLE(c7)
|
||||
|
||||
#define TWO_BYTE_FULL_EXTENSION_TABLES \
|
||||
EXTENSION_TABLE(01)
|
||||
|
||||
|
||||
using namespace X86Disassembler;
|
||||
|
||||
@ -550,23 +575,28 @@ 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; \
|
||||
}
|
||||
#define MAP(from, to) \
|
||||
case X86Local::MRM_##from: \
|
||||
filter = new ExactFilter(0x##from); \
|
||||
break;
|
||||
|
||||
#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, "VMCALL", 0xc1) - Handled by MRM_ form; safe to remove
|
||||
EXACTCASE(TWOBYTE, "VMLAUNCH", 0xc2)
|
||||
EXACTCASE(TWOBYTE, "VMRESUME", 0xc3)
|
||||
EXACTCASE(TWOBYTE, "VMXOFF", 0xc4)
|
||||
@ -620,6 +650,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
|
||||
case X86Local::MRM7m:
|
||||
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
|
||||
break;
|
||||
MRM_MAPPING
|
||||
} // switch (Form)
|
||||
break;
|
||||
default:
|
||||
@ -697,6 +728,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:
|
||||
@ -761,6 +793,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
|
||||
}
|
||||
|
||||
delete filter;
|
||||
|
||||
#undef MAP
|
||||
}
|
||||
|
||||
#define TYPE(str, type) if (s == str) return type;
|
||||
|
Loading…
Reference in New Issue
Block a user