summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2014-01-20 12:02:35 +0000
committerDavid Woodhouse <dwmw2@infradead.org>2014-01-20 12:02:35 +0000
commit5cf4c6750dd835059ceb133d974acdf73e3b042e (patch)
tree96f0e9b40fc6af6a6e472856b855c891c360f91c /llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
parent7dd218245cedbbc380225964356a0688bf18c2dd (diff)
downloadbcm5719-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.c8
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 {
OpenPOWER on IntegriCloud