1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

Special case disassembler handling of REX.B prefix on NOP instruction to decode as XCHG R8D, EAX instead. Fixes PR10344.

llvm-svn: 140971
This commit is contained in:
Craig Topper 2011-10-02 16:56:09 +00:00
parent 7cd1bfb89d
commit 5c8feca34f
2 changed files with 42 additions and 2 deletions

View File

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

View File

@ -308,3 +308,6 @@
# CHECK: invvpid (%rax), %rax
0x66 0x0f 0x38 0x81 0x00
# CHECK: xchgl %r8d, %eax
0x41 0x90