From 146c6d77f02bfc631ff21f01c14edbf52f1aa884 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 2 Oct 2011 16:56:09 +0000 Subject: Special case disassembler handling of REX.B prefix on NOP instruction to decode as XCHG R8D, EAX instead. Fixes PR10344. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140971 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../X86/Disassembler/X86DisassemblerDecoder.c | 41 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index ed2cb3f70a..8a88955561 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -58,8 +58,8 @@ static InstructionContext contextForAttrs(uint8_t attrMask) { * @return - TRUE if the ModR/M byte is required, FALSE otherwise. */ static int modRMRequired(OpcodeType type, - InstructionContext insnContext, - uint8_t opcode) { + InstructionContext insnContext, + uint8_t opcode) { const struct ContextDecision* decision = 0; switch (type) { @@ -885,6 +885,43 @@ static int getID(struct InternalInstruction* insn) { } return 0; } + + if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 && + insn->rexPrefix & 0x01) { + /* + * NOOP shouldn't decode as NOOP if REX.b is set. Instead + * it should decode as XCHG %r8, %eax. + */ + + const struct InstructionSpecifier *spec; + uint16_t instructionIDWithNewOpcode; + const struct InstructionSpecifier *specWithNewOpcode; + + spec = specifierForUID(instructionID); + + // Borrow opcode from one of the other XCHGar opcodes + insn->opcode = 0x91; + + if (getIDWithAttrMask(&instructionIDWithNewOpcode, + insn, + attrMask)) { + insn->opcode = 0x90; + + insn->instructionID = instructionID; + insn->spec = spec; + return 0; + } + + specWithNewOpcode = specifierForUID(instructionIDWithNewOpcode); + + // Change back + insn->opcode = 0x90; + + insn->instructionID = instructionIDWithNewOpcode; + insn->spec = specWithNewOpcode; + + return 0; + } insn->instructionID = instructionID; insn->spec = specifierForUID(insn->instructionID); -- cgit v1.2.3