aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/Disassembler
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:51:49 -0800
committerStephen Hines <srhines@google.com>2014-12-02 16:08:10 -0800
commit37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch)
tree8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /lib/Target/X86/Disassembler
parentd2327b22152ced7bc46dc629fc908959e8a52d03 (diff)
downloadexternal_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'lib/Target/X86/Disassembler')
-rw-r--r--lib/Target/X86/Disassembler/LLVMBuild.txt2
-rw-r--r--lib/Target/X86/Disassembler/X86Disassembler.cpp80
-rw-r--r--lib/Target/X86/Disassembler/X86Disassembler.h16
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp121
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoder.h4
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h27
6 files changed, 148 insertions, 102 deletions
diff --git a/lib/Target/X86/Disassembler/LLVMBuild.txt b/lib/Target/X86/Disassembler/LLVMBuild.txt
index cac7adf..e003fc9 100644
--- a/lib/Target/X86/Disassembler/LLVMBuild.txt
+++ b/lib/Target/X86/Disassembler/LLVMBuild.txt
@@ -19,5 +19,5 @@
type = Library
name = X86Disassembler
parent = X86
-required_libraries = MC Support X86Info
+required_libraries = MCDisassembler Support X86Info
add_to_library_groups = X86
diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp
index c366725..5e8c2d6 100644
--- a/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -23,7 +23,6 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
@@ -97,16 +96,26 @@ X86GenericDisassembler::X86GenericDisassembler(
}
}
-/// regionReader - a callback function that wraps the readByte method from
-/// MemoryObject.
+struct Region {
+ ArrayRef<uint8_t> Bytes;
+ uint64_t Base;
+ Region(ArrayRef<uint8_t> Bytes, uint64_t Base) : Bytes(Bytes), Base(Base) {}
+};
+
+/// A callback function that wraps the readByte method from Region.
///
-/// @param arg - The generic callback parameter. In this case, this should
-/// be a pointer to a MemoryObject.
-/// @param byte - A pointer to the byte to be read.
-/// @param address - The address to be read.
-static int regionReader(const void* arg, uint8_t* byte, uint64_t address) {
- const MemoryObject* region = static_cast<const MemoryObject*>(arg);
- return region->readByte(address, byte);
+/// @param Arg - The generic callback parameter. In this case, this should
+/// be a pointer to a Region.
+/// @param Byte - A pointer to the byte to be read.
+/// @param Address - The address to be read.
+static int regionReader(const void *Arg, uint8_t *Byte, uint64_t Address) {
+ auto *R = static_cast<const Region *>(Arg);
+ ArrayRef<uint8_t> Bytes = R->Bytes;
+ unsigned Index = Address - R->Base;
+ if (Bytes.size() <= Index)
+ return -1;
+ *Byte = Bytes[Index];
+ return 0;
}
/// logger - a callback function that wraps the operator<< method from
@@ -127,38 +136,29 @@ static void logger(void* arg, const char* log) {
// Public interface for the disassembler
//
-MCDisassembler::DecodeStatus
-X86GenericDisassembler::getInstruction(MCInst &instr,
- uint64_t &size,
- const MemoryObject &region,
- uint64_t address,
- raw_ostream &vStream,
- raw_ostream &cStream) const {
- CommentStream = &cStream;
+MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(
+ MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &VStream, raw_ostream &CStream) const {
+ CommentStream = &CStream;
- InternalInstruction internalInstr;
+ InternalInstruction InternalInstr;
- dlog_t loggerFn = logger;
- if (&vStream == &nulls())
- loggerFn = nullptr; // Disable logging completely if it's going to nulls().
-
- int ret = decodeInstruction(&internalInstr,
- regionReader,
- (const void*)&region,
- loggerFn,
- (void*)&vStream,
- (const void*)MII.get(),
- address,
- fMode);
-
- if (ret) {
- size = internalInstr.readerCursor - address;
+ dlog_t LoggerFn = logger;
+ if (&VStream == &nulls())
+ LoggerFn = nullptr; // Disable logging completely if it's going to nulls().
+
+ Region R(Bytes, Address);
+
+ int Ret = decodeInstruction(&InternalInstr, regionReader, (const void *)&R,
+ LoggerFn, (void *)&VStream,
+ (const void *)MII.get(), Address, fMode);
+
+ if (Ret) {
+ Size = InternalInstr.readerCursor - Address;
return Fail;
- }
- else {
- size = internalInstr.length;
- return (!translateInstruction(instr, internalInstr, this)) ?
- Success : Fail;
+ } else {
+ Size = InternalInstr.length;
+ return (!translateInstruction(Instr, InternalInstr, this)) ? Success : Fail;
}
}
@@ -717,7 +717,7 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand,
return false;
case ENCODING_WRITEMASK:
return translateMaskRegister(mcInst, insn.writemask);
- case ENCODING_RM:
+ CASE_ENCODING_RM:
return translateRM(mcInst, operand, insn, Dis);
case ENCODING_CB:
case ENCODING_CW:
diff --git a/lib/Target/X86/Disassembler/X86Disassembler.h b/lib/Target/X86/Disassembler/X86Disassembler.h
index 4dc7c29..d7f426b 100644
--- a/lib/Target/X86/Disassembler/X86Disassembler.h
+++ b/lib/Target/X86/Disassembler/X86Disassembler.h
@@ -71,8 +71,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef X86DISASSEMBLER_H
-#define X86DISASSEMBLER_H
+#ifndef LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLER_H
+#define LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLER_H
#include "X86DisassemblerDecoderCommon.h"
#include "llvm/MC/MCDisassembler.h"
@@ -87,21 +87,17 @@ class raw_ostream;
namespace X86Disassembler {
-/// X86GenericDisassembler - Generic disassembler for all X86 platforms.
-/// All each platform class should have to do is subclass the constructor, and
-/// provide a different disassemblerMode value.
+/// Generic disassembler for all X86 platforms. All each platform class should
+/// have to do is subclass the constructor, and provide a different
+/// disassemblerMode value.
class X86GenericDisassembler : public MCDisassembler {
std::unique_ptr<const MCInstrInfo> MII;
public:
- /// Constructor - Initializes the disassembler.
- ///
X86GenericDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
std::unique_ptr<const MCInstrInfo> MII);
public:
-
- /// getInstruction - See MCDisassembler.
DecodeStatus getInstruction(MCInst &instr, uint64_t &size,
- const MemoryObject &region, uint64_t address,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &vStream,
raw_ostream &cStream) const override;
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
index 55587d4..98b3440 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
@@ -1,4 +1,4 @@
-//===-- X86DisassemblerDecoder.c - Disassembler decoder -------------------===//
+//===-- X86DisassemblerDecoder.cpp - Disassembler decoder -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,10 +13,10 @@
//
//===----------------------------------------------------------------------===//
-#include <stdarg.h> /* for va_*() */
-#include <stdio.h> /* for vsnprintf() */
-#include <stdlib.h> /* for exit() */
-#include <string.h> /* for memset() */
+#include <cstdarg> /* for va_*() */
+#include <cstdio> /* for vsnprintf() */
+#include <cstdlib> /* for exit() */
+#include <cstring> /* for memset() */
#include "X86DisassemblerDecoder.h"
@@ -472,8 +472,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) &&
((~byte1 & 0xc) == 0xc) && ((byte2 & 0x4) == 0x4)) {
insn->vectorExtensionType = TYPE_EVEX;
- }
- else {
+ } else {
unconsumeByte(insn); /* unconsume byte1 */
unconsumeByte(insn); /* unconsume byte */
insn->necessaryPrefixLocation = insn->readerCursor - 2;
@@ -504,8 +503,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
insn->vectorExtensionPrefix[2], insn->vectorExtensionPrefix[3]);
}
- }
- else if (byte == 0xc4) {
+ } else if (byte == 0xc4) {
uint8_t byte1;
if (lookAtByte(insn, &byte1)) {
@@ -516,8 +514,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
insn->vectorExtensionType = TYPE_VEX_3B;
insn->necessaryPrefixLocation = insn->readerCursor - 1;
- }
- else {
+ } else {
unconsumeByte(insn);
insn->necessaryPrefixLocation = insn->readerCursor - 1;
}
@@ -541,8 +538,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
insn->vectorExtensionPrefix[2]);
}
- }
- else if (byte == 0xc5) {
+ } else if (byte == 0xc5) {
uint8_t byte1;
if (lookAtByte(insn, &byte1)) {
@@ -552,8 +548,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
insn->vectorExtensionType = TYPE_VEX_2B;
- }
- else {
+ } else {
unconsumeByte(insn);
}
@@ -566,8 +561,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
| (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);
}
- switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1]))
- {
+ switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
default:
break;
case VEX_PREFIX_66:
@@ -579,8 +573,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
insn->vectorExtensionPrefix[0],
insn->vectorExtensionPrefix[1]);
}
- }
- else if (byte == 0x8f) {
+ } else if (byte == 0x8f) {
uint8_t byte1;
if (lookAtByte(insn, &byte1)) {
@@ -591,8 +584,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
if ((byte1 & 0x38) != 0x0) { /* 0 in these 3 bits is a POP instruction. */
insn->vectorExtensionType = TYPE_XOP;
insn->necessaryPrefixLocation = insn->readerCursor - 1;
- }
- else {
+ } else {
unconsumeByte(insn);
insn->necessaryPrefixLocation = insn->readerCursor - 1;
}
@@ -612,8 +604,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
| (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);
}
- switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2]))
- {
+ switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
default:
break;
case VEX_PREFIX_66:
@@ -625,8 +616,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
insn->vectorExtensionPrefix[2]);
}
- }
- else {
+ } else {
if (insn->mode == MODE_64BIT) {
if ((byte & 0xf0) == 0x40) {
uint8_t opcodeByte;
@@ -698,8 +688,7 @@ static int readOpcode(struct InternalInstruction* insn) {
insn->opcodeType = ONEBYTE;
- if (insn->vectorExtensionType == TYPE_EVEX)
- {
+ if (insn->vectorExtensionType == TYPE_EVEX) {
switch (mmFromEVEX2of4(insn->vectorExtensionPrefix[1])) {
default:
dbgprintf(insn, "Unhandled mm field for instruction (0x%hhx)",
@@ -715,8 +704,7 @@ static int readOpcode(struct InternalInstruction* insn) {
insn->opcodeType = THREEBYTE_3A;
return consumeByte(insn, &insn->opcode);
}
- }
- else if (insn->vectorExtensionType == TYPE_VEX_3B) {
+ } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
default:
dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
@@ -732,12 +720,10 @@ static int readOpcode(struct InternalInstruction* insn) {
insn->opcodeType = THREEBYTE_3A;
return consumeByte(insn, &insn->opcode);
}
- }
- else if (insn->vectorExtensionType == TYPE_VEX_2B) {
+ } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
insn->opcodeType = TWOBYTE;
return consumeByte(insn, &insn->opcode);
- }
- else if (insn->vectorExtensionType == TYPE_XOP) {
+ } else if (insn->vectorExtensionType == TYPE_XOP) {
switch (mmmmmFromXOP2of3(insn->vectorExtensionPrefix[1])) {
default:
dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
@@ -866,6 +852,22 @@ static bool is16BitEquivalent(const char* orig, const char* equiv) {
}
/*
+ * is64Bit - Determines whether this instruction is a 64-bit instruction.
+ *
+ * @param name - The instruction that is not 16-bit
+ */
+static bool is64Bit(const char* name) {
+ off_t i;
+
+ for (i = 0;; ++i) {
+ if (name[i] == '\0')
+ return false;
+ if (name[i] == '6' && name[i+1] == '4')
+ return true;
+ }
+}
+
+/*
* getID - Determines the ID of an instruction, consuming the ModR/M byte as
* appropriate for extended and escape opcodes. Determines the attributes and
* context for the instruction before doing so.
@@ -911,8 +913,7 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
attrMask |= ATTR_EVEXL;
if (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
attrMask |= ATTR_EVEXL2;
- }
- else if (insn->vectorExtensionType == TYPE_VEX_3B) {
+ } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
case VEX_PREFIX_66:
attrMask |= ATTR_OPSIZE;
@@ -927,8 +928,7 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
if (lFromVEX3of3(insn->vectorExtensionPrefix[2]))
attrMask |= ATTR_VEXL;
- }
- else if (insn->vectorExtensionType == TYPE_VEX_2B) {
+ } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
case VEX_PREFIX_66:
attrMask |= ATTR_OPSIZE;
@@ -943,8 +943,7 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
if (lFromVEX2of2(insn->vectorExtensionPrefix[1]))
attrMask |= ATTR_VEXL;
- }
- else if (insn->vectorExtensionType == TYPE_XOP) {
+ } else if (insn->vectorExtensionType == TYPE_XOP) {
switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
case VEX_PREFIX_66:
attrMask |= ATTR_OPSIZE;
@@ -959,12 +958,10 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
attrMask |= ATTR_VEXL;
- }
- else {
+ } else {
return -1;
}
- }
- else {
+ } else {
if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation))
attrMask |= ATTR_OPSIZE;
else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation))
@@ -1002,6 +999,37 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
/* The following clauses compensate for limitations of the tables. */
+ if (insn->mode != MODE_64BIT &&
+ insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
+ /*
+ * The tables can't distinquish between cases where the W-bit is used to
+ * select register size and cases where its a required part of the opcode.
+ */
+ if ((insn->vectorExtensionType == TYPE_EVEX &&
+ wFromEVEX3of4(insn->vectorExtensionPrefix[2])) ||
+ (insn->vectorExtensionType == TYPE_VEX_3B &&
+ wFromVEX3of3(insn->vectorExtensionPrefix[2])) ||
+ (insn->vectorExtensionType == TYPE_XOP &&
+ wFromXOP3of3(insn->vectorExtensionPrefix[2]))) {
+
+ uint16_t instructionIDWithREXW;
+ if (getIDWithAttrMask(&instructionIDWithREXW,
+ insn, attrMask | ATTR_REXW)) {
+ insn->instructionID = instructionID;
+ insn->spec = specifierForUID(instructionID);
+ return 0;
+ }
+
+ const char *SpecName = GetInstrName(instructionIDWithREXW, miiArg);
+ // If not a 64-bit instruction. Switch the opcode.
+ if (!is64Bit(SpecName)) {
+ insn->instructionID = instructionIDWithREXW;
+ insn->spec = specifierForUID(instructionIDWithREXW);
+ return 0;
+ }
+ }
+ }
+
if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) &&
!(attrMask & ATTR_OPSIZE)) {
/*
@@ -1488,7 +1516,7 @@ static int fixupReg(struct InternalInstruction *insn,
if (!valid)
return -1;
break;
- case ENCODING_RM:
+ CASE_ENCODING_RM:
if (insn->eaBase >= insn->eaRegBase) {
insn->eaBase = (EABase)fixupRMValue(insn,
(OperandType)op->type,
@@ -1681,11 +1709,14 @@ static int readOperands(struct InternalInstruction* insn) {
case ENCODING_DI:
break;
case ENCODING_REG:
- case ENCODING_RM:
+ CASE_ENCODING_RM:
if (readModRM(insn))
return -1;
if (fixupReg(insn, &Op))
return -1;
+ // Apply the AVX512 compressed displacement scaling factor.
+ if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
+ insn->displacement *= 1 << (Op.encoding - ENCODING_RM);
break;
case ENCODING_CB:
case ENCODING_CW:
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
index 8c45402..457b382 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef X86DISASSEMBLERDECODER_H
-#define X86DISASSEMBLERDECODER_H
+#ifndef LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLERDECODER_H
+#define LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLERDECODER_H
#include "X86DisassemblerDecoderCommon.h"
#include "llvm/ADT/ArrayRef.h"
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
index f59e0b6..bec4f0e 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef X86DISASSEMBLERDECODERCOMMON_H
-#define X86DISASSEMBLERDECODERCOMMON_H
+#ifndef LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLERDECODERCOMMON_H
+#define LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLERDECODERCOMMON_H
#include "llvm/Support/DataTypes.h"
@@ -265,7 +265,7 @@ enum attributeBits {
ENUM_ENTRY(IC_EVEX_L2_W_KZ, 3, "requires EVEX_KZ, L2 and W") \
ENUM_ENTRY(IC_EVEX_L2_W_XS_KZ, 4, "requires EVEX_KZ, L2, W and XS prefix") \
ENUM_ENTRY(IC_EVEX_L2_W_XD_KZ, 4, "requires EVEX_KZ, L2, W and XD prefix") \
- ENUM_ENTRY(IC_EVEX_L2_W_OPSIZE_KZ, 4, "requires EVEX_KZ, L2, W and OpSize")
+ ENUM_ENTRY(IC_EVEX_L2_W_OPSIZE_KZ, 4, "requires EVEX_KZ, L2, W and OpSize")
#define ENUM_ENTRY(n, r, d) n,
enum InstructionContext {
@@ -325,11 +325,26 @@ enum ModRMDecisionType {
};
#undef ENUM_ENTRY
+#define CASE_ENCODING_RM \
+ case ENCODING_RM: \
+ case ENCODING_RM_CD2: \
+ case ENCODING_RM_CD4: \
+ case ENCODING_RM_CD8: \
+ case ENCODING_RM_CD16: \
+ case ENCODING_RM_CD32: \
+ case ENCODING_RM_CD64
+
// Physical encodings of instruction operands.
#define ENCODINGS \
ENUM_ENTRY(ENCODING_NONE, "") \
ENUM_ENTRY(ENCODING_REG, "Register operand in ModR/M byte.") \
ENUM_ENTRY(ENCODING_RM, "R/M operand in ModR/M byte.") \
+ ENUM_ENTRY(ENCODING_RM_CD2, "R/M operand with CDisp scaling of 2") \
+ ENUM_ENTRY(ENCODING_RM_CD4, "R/M operand with CDisp scaling of 4") \
+ ENUM_ENTRY(ENCODING_RM_CD8, "R/M operand with CDisp scaling of 8") \
+ ENUM_ENTRY(ENCODING_RM_CD16,"R/M operand with CDisp scaling of 16") \
+ ENUM_ENTRY(ENCODING_RM_CD32,"R/M operand with CDisp scaling of 32") \
+ ENUM_ENTRY(ENCODING_RM_CD64,"R/M operand with CDisp scaling of 64") \
ENUM_ENTRY(ENCODING_VVVV, "Register operand in VEX.vvvv byte.") \
ENUM_ENTRY(ENCODING_WRITEMASK, "Register operand in EVEX.aaa byte.") \
ENUM_ENTRY(ENCODING_CB, "1-byte code offset (possible new CS value)") \
@@ -438,8 +453,12 @@ enum OperandEncoding {
ENUM_ENTRY(TYPE_XMM256, "32-byte") \
ENUM_ENTRY(TYPE_XMM512, "64-byte") \
ENUM_ENTRY(TYPE_VK1, "1-bit") \
+ ENUM_ENTRY(TYPE_VK2, "2-bit") \
+ ENUM_ENTRY(TYPE_VK4, "4-bit") \
ENUM_ENTRY(TYPE_VK8, "8-bit") \
ENUM_ENTRY(TYPE_VK16, "16-bit") \
+ ENUM_ENTRY(TYPE_VK32, "32-bit") \
+ ENUM_ENTRY(TYPE_VK64, "64-bit") \
ENUM_ENTRY(TYPE_XMM0, "Implicit use of XMM0") \
ENUM_ENTRY(TYPE_SEGMENTREG, "Segment register operand") \
ENUM_ENTRY(TYPE_DEBUGREG, "Debug register operand") \
@@ -481,7 +500,7 @@ enum ModifierType {
};
#undef ENUM_ENTRY
-static const unsigned X86_MAX_OPERANDS = 5;
+static const unsigned X86_MAX_OPERANDS = 6;
/// Decoding mode for the Intel disassembler. 16-bit, 32-bit, and 64-bit mode
/// are supported, and represent real mode, IA-32e, and IA-32e in 64-bit mode,