diff options
author | Craig Topper <craig.topper@gmail.com> | 2014-12-31 07:07:31 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2014-12-31 07:07:31 +0000 |
commit | 99bcab7b850fd57143e4103939a27ad78655b721 (patch) | |
tree | bb100a85df4804fa9fdbf3ce7c8c54baf2230cf8 /llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp | |
parent | 6e518776e3f0506ecb2dbb63c34ec561eb81f075 (diff) | |
download | bcm5719-llvm-99bcab7b850fd57143e4103939a27ad78655b721.tar.gz bcm5719-llvm-99bcab7b850fd57143e4103939a27ad78655b721.zip |
[X86] Fix disassembly of absolute moves to work correctly in 16 and 32-bit modes with all 4 combinations of OpSize and AdSize prefixes being present or not.
llvm-svn: 225036
Diffstat (limited to 'llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp')
-rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp index a5fcf1513f7..cc19ec229be 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp @@ -1019,6 +1019,32 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) { } } + /* + * Absolute moves need special handling. + * -For 16-bit mode because the meaning of the AdSize and OpSize prefixes are + * inverted w.r.t. + * -For 32-bit mode we need to ensure the ADSIZE prefix is observed in + * any position. + */ + if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) { + /* Make sure we observed the prefixes in any position. */ + if (insn->prefixPresent[0x67]) + attrMask |= ATTR_ADSIZE; + if (insn->prefixPresent[0x66]) + attrMask |= ATTR_OPSIZE; + + /* In 16-bit, invert the attributes. */ + if (insn->mode == MODE_16BIT) + attrMask ^= ATTR_ADSIZE | ATTR_OPSIZE; + + if (getIDWithAttrMask(&instructionID, insn, attrMask)) + return -1; + + insn->instructionID = instructionID; + insn->spec = specifierForUID(instructionID); + return 0; + } + if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) && !(attrMask & ATTR_OPSIZE)) { /* |