mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 09:45:00 +00:00
[X86] Ignore bits 2:0 of the modrm byte when disassembling lfence, mfence, and sfence.
These are documented as using modrm byte of 0xe8, 0xf0, and 0xf8 respectively. But hardware ignore bits 2:0. So 0xe9-0xef is treated the same as 0xe8. Similar for the other two. Fixing this required adding 8 new formats to the X86 instructions to convey this information. Could have gotten away with 3, but adding all 8 made for a more logical conversion from format to modrm encoding. I renumbered the format encodings to keep the register modrm formats grouped together.
This commit is contained in:
parent
a92d798d0e
commit
ef35532c13
@ -626,82 +626,86 @@ namespace X86II {
|
||||
/// MRMDestMem - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a destination, which in this case is memory.
|
||||
///
|
||||
MRMDestMem = 32,
|
||||
MRMDestMem = 24,
|
||||
|
||||
/// MRMSrcMem - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a source, which in this case is memory.
|
||||
///
|
||||
MRMSrcMem = 33,
|
||||
MRMSrcMem = 25,
|
||||
|
||||
/// MRMSrcMem4VOp3 - This form is used for instructions that encode
|
||||
/// operand 3 with VEX.VVVV and load from memory.
|
||||
///
|
||||
MRMSrcMem4VOp3 = 34,
|
||||
MRMSrcMem4VOp3 = 26,
|
||||
|
||||
/// MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM
|
||||
/// byte to specify the fourth source, which in this case is memory.
|
||||
///
|
||||
MRMSrcMemOp4 = 35,
|
||||
MRMSrcMemOp4 = 27,
|
||||
|
||||
/// MRMSrcMemCC - This form is used for instructions that use the Mod/RM
|
||||
/// byte to specify the operands and also encodes a condition code.
|
||||
///
|
||||
MRMSrcMemCC = 36,
|
||||
MRMSrcMemCC = 28,
|
||||
|
||||
/// MRMXm - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a memory source, but doesn't use the middle field. And has
|
||||
/// a condition code.
|
||||
///
|
||||
MRMXmCC = 38,
|
||||
MRMXmCC = 30,
|
||||
|
||||
/// MRMXm - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a memory source, but doesn't use the middle field.
|
||||
///
|
||||
MRMXm = 39,
|
||||
MRMXm = 31,
|
||||
|
||||
// Next, instructions that operate on a memory r/m operand...
|
||||
MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43, // Format /0 /1 /2 /3
|
||||
MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47, // Format /4 /5 /6 /7
|
||||
MRM0m = 32, MRM1m = 33, MRM2m = 34, MRM3m = 35, // Format /0 /1 /2 /3
|
||||
MRM4m = 36, MRM5m = 37, MRM6m = 38, MRM7m = 39, // Format /4 /5 /6 /7
|
||||
|
||||
/// MRMDestReg - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a destination, which in this case is a register.
|
||||
///
|
||||
MRMDestReg = 48,
|
||||
MRMDestReg = 40,
|
||||
|
||||
/// MRMSrcReg - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a source, which in this case is a register.
|
||||
///
|
||||
MRMSrcReg = 49,
|
||||
MRMSrcReg = 41,
|
||||
|
||||
/// MRMSrcReg4VOp3 - This form is used for instructions that encode
|
||||
/// operand 3 with VEX.VVVV and do not load from memory.
|
||||
///
|
||||
MRMSrcReg4VOp3 = 50,
|
||||
MRMSrcReg4VOp3 = 42,
|
||||
|
||||
/// MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM
|
||||
/// byte to specify the fourth source, which in this case is a register.
|
||||
///
|
||||
MRMSrcRegOp4 = 51,
|
||||
MRMSrcRegOp4 = 43,
|
||||
|
||||
/// MRMSrcRegCC - This form is used for instructions that use the Mod/RM
|
||||
/// byte to specify the operands and also encodes a condition code
|
||||
///
|
||||
MRMSrcRegCC = 52,
|
||||
MRMSrcRegCC = 44,
|
||||
|
||||
/// MRMXCCr - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a register source, but doesn't use the middle field. And has
|
||||
/// a condition code.
|
||||
///
|
||||
MRMXrCC = 54,
|
||||
MRMXrCC = 46,
|
||||
|
||||
/// MRMXr - This form is used for instructions that use the Mod/RM byte
|
||||
/// to specify a register source, but doesn't use the middle field.
|
||||
///
|
||||
MRMXr = 55,
|
||||
MRMXr = 47,
|
||||
|
||||
// Instructions that operate on a register r/m operand...
|
||||
MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59, // Format /0 /1 /2 /3
|
||||
MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63, // Format /4 /5 /6 /7
|
||||
MRM0r = 48, MRM1r = 49, MRM2r = 50, MRM3r = 51, // Format /0 /1 /2 /3
|
||||
MRM4r = 52, MRM5r = 53, MRM6r = 54, MRM7r = 55, // Format /4 /5 /6 /7
|
||||
|
||||
// Instructions that operate that have mod=11 and an opcode but ignore r/m.
|
||||
MRM0X = 56, MRM1X = 57, MRM2X = 58, MRM3X = 59, // Format /0 /1 /2 /3
|
||||
MRM4X = 60, MRM5X = 61, MRM6X = 62, MRM7X = 63, // Format /4 /5 /6 /7
|
||||
|
||||
/// MRM_XX - A mod/rm byte of exactly 0xXX.
|
||||
MRM_C0 = 64, MRM_C1 = 65, MRM_C2 = 66, MRM_C3 = 67,
|
||||
@ -1105,6 +1109,11 @@ namespace X86II {
|
||||
case X86II::MRM4r: case X86II::MRM5r:
|
||||
case X86II::MRM6r: case X86II::MRM7r:
|
||||
return -1;
|
||||
case X86II::MRM0X: case X86II::MRM1X:
|
||||
case X86II::MRM2X: case X86II::MRM3X:
|
||||
case X86II::MRM4X: case X86II::MRM5X:
|
||||
case X86II::MRM6X: case X86II::MRM7X:
|
||||
return -1;
|
||||
case X86II::MRMXmCC:
|
||||
case X86II::MRMXm:
|
||||
case X86II::MRM0m: case X86II::MRM1m:
|
||||
|
@ -1670,6 +1670,18 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
CurOp += X86::AddrNumOperands;
|
||||
break;
|
||||
|
||||
case X86II::MRM0X:
|
||||
case X86II::MRM1X:
|
||||
case X86II::MRM2X:
|
||||
case X86II::MRM3X:
|
||||
case X86II::MRM4X:
|
||||
case X86II::MRM5X:
|
||||
case X86II::MRM6X:
|
||||
case X86II::MRM7X:
|
||||
emitByte(BaseOpcode, OS);
|
||||
emitByte(0xC0 + ((Form - X86II::MRM0X) << 3), OS);
|
||||
break;
|
||||
|
||||
case X86II::MRM_C0:
|
||||
case X86II::MRM_C1:
|
||||
case X86II::MRM_C2:
|
||||
|
@ -28,26 +28,29 @@ def RawFrmImm8 : Format<7>;
|
||||
def RawFrmImm16 : Format<8>;
|
||||
def AddCCFrm : Format<9>;
|
||||
def PrefixByte : Format<10>;
|
||||
def MRMDestMem : Format<32>;
|
||||
def MRMSrcMem : Format<33>;
|
||||
def MRMSrcMem4VOp3 : Format<34>;
|
||||
def MRMSrcMemOp4 : Format<35>;
|
||||
def MRMSrcMemCC : Format<36>;
|
||||
def MRMXmCC: Format<38>;
|
||||
def MRMXm : Format<39>;
|
||||
def MRM0m : Format<40>; def MRM1m : Format<41>; def MRM2m : Format<42>;
|
||||
def MRM3m : Format<43>; def MRM4m : Format<44>; def MRM5m : Format<45>;
|
||||
def MRM6m : Format<46>; def MRM7m : Format<47>;
|
||||
def MRMDestReg : Format<48>;
|
||||
def MRMSrcReg : Format<49>;
|
||||
def MRMSrcReg4VOp3 : Format<50>;
|
||||
def MRMSrcRegOp4 : Format<51>;
|
||||
def MRMSrcRegCC : Format<52>;
|
||||
def MRMXrCC: Format<54>;
|
||||
def MRMXr : Format<55>;
|
||||
def MRM0r : Format<56>; def MRM1r : Format<57>; def MRM2r : Format<58>;
|
||||
def MRM3r : Format<59>; def MRM4r : Format<60>; def MRM5r : Format<61>;
|
||||
def MRM6r : Format<62>; def MRM7r : Format<63>;
|
||||
def MRMDestMem : Format<24>;
|
||||
def MRMSrcMem : Format<25>;
|
||||
def MRMSrcMem4VOp3 : Format<26>;
|
||||
def MRMSrcMemOp4 : Format<27>;
|
||||
def MRMSrcMemCC : Format<28>;
|
||||
def MRMXmCC: Format<30>;
|
||||
def MRMXm : Format<31>;
|
||||
def MRM0m : Format<32>; def MRM1m : Format<33>; def MRM2m : Format<34>;
|
||||
def MRM3m : Format<35>; def MRM4m : Format<36>; def MRM5m : Format<37>;
|
||||
def MRM6m : Format<38>; def MRM7m : Format<39>;
|
||||
def MRMDestReg : Format<40>;
|
||||
def MRMSrcReg : Format<41>;
|
||||
def MRMSrcReg4VOp3 : Format<42>;
|
||||
def MRMSrcRegOp4 : Format<43>;
|
||||
def MRMSrcRegCC : Format<44>;
|
||||
def MRMXrCC: Format<46>;
|
||||
def MRMXr : Format<47>;
|
||||
def MRM0r : Format<48>; def MRM1r : Format<49>; def MRM2r : Format<50>;
|
||||
def MRM3r : Format<51>; def MRM4r : Format<52>; def MRM5r : Format<53>;
|
||||
def MRM6r : Format<54>; def MRM7r : Format<55>;
|
||||
def MRM0X : Format<56>; def MRM1X : Format<57>; def MRM2X : Format<58>;
|
||||
def MRM3X : Format<59>; def MRM4X : Format<60>; def MRM5X : Format<61>;
|
||||
def MRM6X : Format<62>; def MRM7X : Format<63>;
|
||||
def MRM_C0 : Format<64>; def MRM_C1 : Format<65>; def MRM_C2 : Format<66>;
|
||||
def MRM_C3 : Format<67>; def MRM_C4 : Format<68>; def MRM_C5 : Format<69>;
|
||||
def MRM_C6 : Format<70>; def MRM_C7 : Format<71>; def MRM_C8 : Format<72>;
|
||||
|
@ -3192,11 +3192,11 @@ let SchedRW = [WriteFence] in {
|
||||
// Load, store, and memory fence
|
||||
// TODO: As with mfence, we may want to ease the availability of sfence/lfence
|
||||
// to include any 64-bit target.
|
||||
def SFENCE : I<0xAE, MRM_F8, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>,
|
||||
def SFENCE : I<0xAE, MRM7X, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>,
|
||||
PS, Requires<[HasSSE1]>;
|
||||
def LFENCE : I<0xAE, MRM_E8, (outs), (ins), "lfence", [(int_x86_sse2_lfence)]>,
|
||||
def LFENCE : I<0xAE, MRM5X, (outs), (ins), "lfence", [(int_x86_sse2_lfence)]>,
|
||||
PS, Requires<[HasSSE2]>;
|
||||
def MFENCE : I<0xAE, MRM_F0, (outs), (ins), "mfence", [(int_x86_sse2_mfence)]>,
|
||||
def MFENCE : I<0xAE, MRM6X, (outs), (ins), "mfence", [(int_x86_sse2_mfence)]>,
|
||||
PS, Requires<[HasMFence]>;
|
||||
} // SchedRW
|
||||
|
||||
|
@ -57,11 +57,56 @@
|
||||
# CHECK: callw -1
|
||||
0x66 0xe8 0xff 0xff
|
||||
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
# CHECK: lfence
|
||||
0x0f 0xae 0xe8
|
||||
0x0f 0xae 0xe9
|
||||
0x0f 0xae 0xea
|
||||
0x0f 0xae 0xeb
|
||||
0x0f 0xae 0xec
|
||||
0x0f 0xae 0xed
|
||||
0x0f 0xae 0xee
|
||||
0x0f 0xae 0xef
|
||||
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
# CHECK: mfence
|
||||
0x0f 0xae 0xf0
|
||||
0x0f 0xae 0xf1
|
||||
0x0f 0xae 0xf2
|
||||
0x0f 0xae 0xf3
|
||||
0x0f 0xae 0xf4
|
||||
0x0f 0xae 0xf5
|
||||
0x0f 0xae 0xf6
|
||||
0x0f 0xae 0xf7
|
||||
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
# CHECK: sfence
|
||||
0x0f 0xae 0xf8
|
||||
0x0f 0xae 0xf9
|
||||
0x0f 0xae 0xfa
|
||||
0x0f 0xae 0xfb
|
||||
0x0f 0xae 0xfc
|
||||
0x0f 0xae 0xfd
|
||||
0x0f 0xae 0xfe
|
||||
0x0f 0xae 0xff
|
||||
|
||||
# CHECK: monitor
|
||||
0x0f 0x01 0xc8
|
||||
|
@ -49,6 +49,14 @@ static const char *isInvalidMemoryInstr(const Instruction &Instr) {
|
||||
case X86II::MRM5r:
|
||||
case X86II::MRM6r:
|
||||
case X86II::MRM7r:
|
||||
case X86II::MRM0X:
|
||||
case X86II::MRM1X:
|
||||
case X86II::MRM2X:
|
||||
case X86II::MRM3X:
|
||||
case X86II::MRM4X:
|
||||
case X86II::MRM5X:
|
||||
case X86II::MRM6X:
|
||||
case X86II::MRM7X:
|
||||
case X86II::MRM_C0:
|
||||
case X86II::MRM_C1:
|
||||
case X86II::MRM_C2:
|
||||
|
@ -708,6 +708,14 @@ void RecognizableInstr::emitInstructionSpecifier() {
|
||||
HANDLE_OPERAND(immediate)
|
||||
HANDLE_OPERAND(immediate)
|
||||
break;
|
||||
case X86Local::MRM0X:
|
||||
case X86Local::MRM1X:
|
||||
case X86Local::MRM2X:
|
||||
case X86Local::MRM3X:
|
||||
case X86Local::MRM4X:
|
||||
case X86Local::MRM5X:
|
||||
case X86Local::MRM6X:
|
||||
case X86Local::MRM7X:
|
||||
#define MAP(from, to) case X86Local::MRM_##from:
|
||||
X86_INSTR_MRM_MAPPING
|
||||
#undef MAP
|
||||
@ -778,6 +786,12 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
|
||||
case X86Local::MRM6r: case X86Local::MRM7r:
|
||||
filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0r);
|
||||
break;
|
||||
case X86Local::MRM0X: case X86Local::MRM1X:
|
||||
case X86Local::MRM2X: case X86Local::MRM3X:
|
||||
case X86Local::MRM4X: case X86Local::MRM5X:
|
||||
case X86Local::MRM6X: case X86Local::MRM7X:
|
||||
filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0X);
|
||||
break;
|
||||
case X86Local::MRM0m: case X86Local::MRM1m:
|
||||
case X86Local::MRM2m: case X86Local::MRM3m:
|
||||
case X86Local::MRM4m: case X86Local::MRM5m:
|
||||
|
@ -103,22 +103,24 @@ namespace X86Local {
|
||||
RawFrmImm16 = 8,
|
||||
AddCCFrm = 9,
|
||||
PrefixByte = 10,
|
||||
MRMDestMem = 32,
|
||||
MRMSrcMem = 33,
|
||||
MRMSrcMem4VOp3 = 34,
|
||||
MRMSrcMemOp4 = 35,
|
||||
MRMSrcMemCC = 36,
|
||||
MRMXmCC = 38, MRMXm = 39,
|
||||
MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43,
|
||||
MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47,
|
||||
MRMDestReg = 48,
|
||||
MRMSrcReg = 49,
|
||||
MRMSrcReg4VOp3 = 50,
|
||||
MRMSrcRegOp4 = 51,
|
||||
MRMSrcRegCC = 52,
|
||||
MRMXrCC = 54, MRMXr = 55,
|
||||
MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59,
|
||||
MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63,
|
||||
MRMDestMem = 24,
|
||||
MRMSrcMem = 25,
|
||||
MRMSrcMem4VOp3 = 26,
|
||||
MRMSrcMemOp4 = 27,
|
||||
MRMSrcMemCC = 28,
|
||||
MRMXmCC = 30, MRMXm = 31,
|
||||
MRM0m = 32, MRM1m = 33, MRM2m = 34, MRM3m = 35,
|
||||
MRM4m = 36, MRM5m = 37, MRM6m = 38, MRM7m = 39,
|
||||
MRMDestReg = 40,
|
||||
MRMSrcReg = 41,
|
||||
MRMSrcReg4VOp3 = 42,
|
||||
MRMSrcRegOp4 = 43,
|
||||
MRMSrcRegCC = 44,
|
||||
MRMXrCC = 46, MRMXr = 47,
|
||||
MRM0r = 48, MRM1r = 49, MRM2r = 50, MRM3r = 51,
|
||||
MRM4r = 52, MRM5r = 53, MRM6r = 54, MRM7r = 55,
|
||||
MRM0X = 56, MRM1X = 57, MRM2X = 58, MRM3X = 59,
|
||||
MRM4X = 60, MRM5X = 61, MRM6X = 62, MRM7X = 63,
|
||||
#define MAP(from, to) MRM_##from = to,
|
||||
X86_INSTR_MRM_MAPPING
|
||||
#undef MAP
|
||||
|
Loading…
Reference in New Issue
Block a user