diff options
author | David Woodhouse <dwmw2@infradead.org> | 2014-01-20 12:02:35 +0000 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2014-01-20 12:02:35 +0000 |
commit | 5cf4c6750dd835059ceb133d974acdf73e3b042e (patch) | |
tree | 96f0e9b40fc6af6a6e472856b855c891c360f91c /llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | |
parent | 7dd218245cedbbc380225964356a0688bf18c2dd (diff) | |
download | bcm5719-llvm-5cf4c6750dd835059ceb133d974acdf73e3b042e.tar.gz bcm5719-llvm-5cf4c6750dd835059ceb133d974acdf73e3b042e.zip |
[x86] Fix 16-bit handling of OpSize bit
When disassembling in 16-bit mode the meaning of the OpSize bit is
inverted. Instructions found in the IC_OPSIZE context will actually
*not* have the 0x66 prefix, and instructions in the IC context will
have the 0x66 prefix. Make use of the existing special-case handling
for the 0x66 prefix being in the wrong place, to cope with this.
llvm-svn: 199650
Diffstat (limited to 'llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c')
-rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index fc19650c7bc..66badd95c32 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -971,7 +971,7 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) { } } else { - if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) + if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) attrMask |= ATTR_OPSIZE; else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation)) attrMask |= ATTR_ADSIZE; @@ -989,7 +989,8 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) { /* The following clauses compensate for limitations of the tables. */ - if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) { + if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) && + !(attrMask & ATTR_OPSIZE)) { /* * The instruction tables make no distinction between instructions that * allow OpSize anywhere (i.e., 16-bit operations) and that need it in a @@ -1021,7 +1022,8 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) { specWithOpSizeName = x86DisassemblerGetInstrName(instructionIDWithOpsize, miiArg); - if (is16BitEquivalent(specName, specWithOpSizeName)) { + if (is16BitEquivalent(specName, specWithOpSizeName) && + (insn->mode == MODE_16BIT) ^ insn->prefixPresent[0x66]) { insn->instructionID = instructionIDWithOpsize; insn->spec = specifierForUID(instructionIDWithOpsize); } else { |