[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:
Maksim Panchenko 2018-07-05 23:32:42 +00:00
parent 9e412ec8f2
commit 89e4abe7b7
4 changed files with 11 additions and 0 deletions

View File

@ -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);
}

View File

@ -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))

View File

@ -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;

View File

@ -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