forked from OSchip/llvm-project
[X86][Disassembler] Fix LOCK prefix disassembler support
Summary: If LOCK prefix is not the first prefix in an instruction, LLVM disassembler silently drops the prefix. The fix is to select a proper instruction with a builtin LOCK prefix if one exists. Reviewers: craig.topper Reviewed By: craig.topper Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D49001 llvm-svn: 336400
This commit is contained in:
parent
9e412ec8f2
commit
89e4abe7b7
|
@ -247,6 +247,8 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(
|
|||
// It should not be 'pause' f3 90
|
||||
InternalInstr.opcode != 0x90)
|
||||
Flags |= X86::IP_HAS_REPEAT;
|
||||
if (InternalInstr.hasLockPrefix)
|
||||
Flags |= X86::IP_HAS_LOCK;
|
||||
}
|
||||
Instr.setFlags(Flags);
|
||||
}
|
||||
|
|
|
@ -298,6 +298,9 @@ static bool isREX(struct InternalInstruction *insn, uint8_t prefix) {
|
|||
static void setPrefixPresent(struct InternalInstruction *insn, uint8_t prefix) {
|
||||
uint8_t nextByte;
|
||||
switch (prefix) {
|
||||
case 0xf0:
|
||||
insn->hasLockPrefix = true;
|
||||
break;
|
||||
case 0xf2:
|
||||
case 0xf3:
|
||||
if (lookAtByte(insn, &nextByte))
|
||||
|
|
|
@ -563,6 +563,8 @@ struct InternalInstruction {
|
|||
bool hasAdSize;
|
||||
// Operand-size override
|
||||
bool hasOpSize;
|
||||
// Lock prefix
|
||||
bool hasLockPrefix;
|
||||
// The repeat prefix if any
|
||||
uint8_t repeatPrefix;
|
||||
|
||||
|
|
|
@ -101,6 +101,10 @@
|
|||
# CHECK: movq %mm0, %mm1
|
||||
0x46 0x0f 0x7f 0xc1
|
||||
|
||||
# Test that lock prefix is not dropped if it's not the first prefix
|
||||
# CHECK: lock cmpxchgw %di, (%rcx)
|
||||
0x66 0xf0 0x0f 0xb1 0x39
|
||||
|
||||
# Test that a prefix on it's own works. It's debatable as to if this is
|
||||
# something that is considered valid, but however as LLVM's own disassembler
|
||||
# has decided to disassemble prefixes as being separate opcodes, it therefore
|
||||
|
|
Loading…
Reference in New Issue