diff options
author | Craig Topper <craig.topper@gmail.com> | 2011-10-04 06:30:42 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2011-10-04 06:30:42 +0000 |
commit | 6744a17dcfb941d9fdd869b9f06e20660e18ff88 (patch) | |
tree | fe947adef5aa0b66a85b739c60b8f83220d61913 /lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | |
parent | f143b79b78d1d244809fa59320f2af2edf4e1a86 (diff) |
Add support in the disassembler for ignoring the L-bit on certain VEX instructions. Mark instructions that have this behavior. Fixes PR10676.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141065 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/Disassembler/X86DisassemblerDecoder.c')
-rw-r--r-- | lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index a1eb57c78f..2508c06821 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -767,8 +767,6 @@ static int getID(struct InternalInstruction* insn) { break; } - if (insn->mode == MODE_64BIT && wFromVEX3of3(insn->vexPrefix[2])) - attrMask |= ATTR_REXW; if (lFromVEX3of3(insn->vexPrefix[2])) attrMask |= ATTR_VEXL; } @@ -793,23 +791,55 @@ static int getID(struct InternalInstruction* insn) { } } else { - if (insn->rexPrefix & 0x08) - attrMask |= ATTR_REXW; - if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) attrMask |= ATTR_OPSIZE; else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) attrMask |= ATTR_XS; else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) attrMask |= ATTR_XD; - } + if (insn->rexPrefix & 0x08) + attrMask |= ATTR_REXW; + if (getIDWithAttrMask(&instructionID, insn, attrMask)) return -1; /* The following clauses compensate for limitations of the tables. */ + if ((attrMask & ATTR_VEXL) && (attrMask & ATTR_REXW)) { + /* + * Some VEX instructions ignore the L-bit, but use the W-bit. Normally L-bit + * has precedence since there are no L-bit with W-bit entries in the tables. + * So if the L-bit isn't significant we should use the W-bit instead. + */ + + const struct InstructionSpecifier *spec; + uint16_t instructionIDWithWBit; + const struct InstructionSpecifier *specWithWBit; + + spec = specifierForUID(instructionID); + + if (getIDWithAttrMask(&instructionIDWithWBit, + insn, + (attrMask & (~ATTR_VEXL)) | ATTR_REXW)) { + insn->instructionID = instructionID; + insn->spec = spec; + return 0; + } + + specWithWBit = specifierForUID(instructionIDWithWBit); + + if (instructionID != instructionIDWithWBit) { + insn->instructionID = instructionIDWithWBit; + insn->spec = specWithWBit; + } else { + insn->instructionID = instructionID; + insn->spec = spec; + } + return 0; + } + if ((attrMask & ATTR_XD) && (attrMask & ATTR_REXW)) { /* * Although for SSE instructions it is usually necessary to treat REX.W+F2 |