/*===-- X86DisassemblerDecoder.c - Disassembler decoder ------------*- C -*-===*
 *
 *                     The LLVM Compiler Infrastructure
 *
 * This file is distributed under the University of Illinois Open Source
 * License. See LICENSE.TXT for details.
 *
 *===----------------------------------------------------------------------===*
 *
 * This file is part of the X86 Disassembler.
 * It contains the implementation of the instruction decoder.
 * Documentation for the disassembler can be found in X86Disassembler.h.
 *
 *===----------------------------------------------------------------------===*/

/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */

#ifdef CAPSTONE_HAS_X86

#include <stdarg.h>   /* for va_*()       */
#if defined(CAPSTONE_HAS_OSXKERNEL)
#include <libkern/libkern.h>
#else
#include <stdlib.h>   /* for exit()       */
#endif

#include "../../cs_priv.h"
#include "../../utils.h"

#include "X86DisassemblerDecoder.h"

/// Specifies whether a ModR/M byte is needed and (if so) which
/// instruction each possible value of the ModR/M byte corresponds to.  Once
/// this information is known, we have narrowed down to a single instruction.
struct ModRMDecision {
	uint8_t modrm_type;
	uint16_t instructionIDs;
};

/// Specifies which set of ModR/M->instruction tables to look at
/// given a particular opcode.
struct OpcodeDecision {
	struct ModRMDecision modRMDecisions[256];
};

/// Specifies which opcode->instruction tables to look at given
/// a particular context (set of attributes).  Since there are many possible
/// contexts, the decoder first uses CONTEXTS_SYM to determine which context
/// applies given a specific set of attributes.  Hence there are only IC_max
/// entries in this table, rather than 2^(ATTR_max).
struct ContextDecision {
	struct OpcodeDecision opcodeDecisions[IC_max];
};

#ifdef CAPSTONE_X86_REDUCE
#include "X86GenDisassemblerTables_reduce.inc"
#else
#include "X86GenDisassemblerTables.inc"
#endif

//#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_DESC
#ifdef CAPSTONE_X86_REDUCE
#include "X86GenInstrInfo_reduce.inc"
#else
#include "X86GenInstrInfo.inc"
#endif

/*
 * contextForAttrs - Client for the instruction context table.  Takes a set of
 *   attributes and returns the appropriate decode context.
 *
 * @param attrMask  - Attributes, from the enumeration attributeBits.
 * @return          - The InstructionContext to use when looking up an
 *                    an instruction with these attributes.
 */
static InstructionContext contextForAttrs(uint16_t attrMask)
{
	return CONTEXTS_SYM[attrMask];
}

/*
 * modRMRequired - Reads the appropriate instruction table to determine whether
 *   the ModR/M byte is required to decode a particular instruction.
 *
 * @param type        - The opcode type (i.e., how many bytes it has).
 * @param insnContext - The context for the instruction, as returned by
 *                      contextForAttrs.
 * @param opcode      - The last byte of the instruction's opcode, not counting
 *                      ModR/M extensions and escapes.
 * @return            - true if the ModR/M byte is required, false otherwise.
 */
static int modRMRequired(OpcodeType type,
		InstructionContext insnContext,
		uint16_t opcode)
{
	const struct OpcodeDecision *decision = NULL;
	const uint8_t *indextable = NULL;
	uint8_t index;

	switch (type) {
		default:
		case ONEBYTE:
			decision = ONEBYTE_SYM;
			indextable = index_x86DisassemblerOneByteOpcodes;
			break;
		case TWOBYTE:
			decision = TWOBYTE_SYM;
			indextable = index_x86DisassemblerTwoByteOpcodes;
			break;
		case THREEBYTE_38:
			decision = THREEBYTE38_SYM;
			indextable = index_x86DisassemblerThreeByte38Opcodes;
			break;
		case THREEBYTE_3A:
			decision = THREEBYTE3A_SYM;
			indextable = index_x86DisassemblerThreeByte3AOpcodes;
			break;
#ifndef CAPSTONE_X86_REDUCE
		case XOP8_MAP:
			decision = XOP8_MAP_SYM;
			indextable = index_x86DisassemblerXOP8Opcodes;
			break;
		case XOP9_MAP:
			decision = XOP9_MAP_SYM;
			indextable = index_x86DisassemblerXOP9Opcodes;
			break;
		case XOPA_MAP:
			decision = XOPA_MAP_SYM;
			indextable = index_x86DisassemblerXOPAOpcodes;
			break;
		case T3DNOW_MAP:
			// 3DNow instructions always have ModRM byte
			return true;
#endif
	}

	index = indextable[insnContext];
	if (index)
		return decision[index - 1].modRMDecisions[opcode].modrm_type != MODRM_ONEENTRY;
	else
		return false;
}

/*
 * decode - Reads the appropriate instruction table to obtain the unique ID of
 *   an instruction.
 *
 * @param type        - See modRMRequired().
 * @param insnContext - See modRMRequired().
 * @param opcode      - See modRMRequired().
 * @param modRM       - The ModR/M byte if required, or any value if not.
 * @return            - The UID of the instruction, or 0 on failure.
 */
static InstrUID decode(OpcodeType type,
		InstructionContext insnContext,
		uint8_t opcode,
		uint8_t modRM)
{
	const struct ModRMDecision *dec = NULL;
	const uint8_t *indextable = NULL;
	uint8_t index;

	switch (type) {
		default:
		case ONEBYTE:
			indextable = index_x86DisassemblerOneByteOpcodes;
			index = indextable[insnContext];
			if (index)
				dec = &ONEBYTE_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
		case TWOBYTE:
			indextable = index_x86DisassemblerTwoByteOpcodes;
			index = indextable[insnContext];
			if (index)
				dec = &TWOBYTE_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
		case THREEBYTE_38:
			indextable = index_x86DisassemblerThreeByte38Opcodes;
			index = indextable[insnContext];
			if (index)
				dec = &THREEBYTE38_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
		case THREEBYTE_3A:
			indextable = index_x86DisassemblerThreeByte3AOpcodes;
			index = indextable[insnContext];
			if (index)
				dec = &THREEBYTE3A_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
#ifndef CAPSTONE_X86_REDUCE
		case XOP8_MAP:
			indextable = index_x86DisassemblerXOP8Opcodes;
			index = indextable[insnContext];
			if (index)
				dec = &XOP8_MAP_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
		case XOP9_MAP:
			indextable = index_x86DisassemblerXOP9Opcodes;
			index = indextable[insnContext];
			if (index)
				dec = &XOP9_MAP_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
		case XOPA_MAP:
			indextable = index_x86DisassemblerXOPAOpcodes;
			index = indextable[insnContext];
			if (index)
				dec = &XOPA_MAP_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
		case T3DNOW_MAP:
			indextable = index_x86DisassemblerT3DNOWOpcodes;
			index = indextable[insnContext];
			if (index)
				dec = &T3DNOW_MAP_SYM[index - 1].modRMDecisions[opcode];
			else
				dec = &emptyTable.modRMDecisions[opcode];
			break;
#endif
	}

	switch (dec->modrm_type) {
		default:
			//debug("Corrupt table!  Unknown modrm_type");
			return 0;
		case MODRM_ONEENTRY:
			return modRMTable[dec->instructionIDs];
		case MODRM_SPLITRM:
			if (modFromModRM(modRM) == 0x3)
				return modRMTable[dec->instructionIDs+1];
			return modRMTable[dec->instructionIDs];
		case MODRM_SPLITREG:
			if (modFromModRM(modRM) == 0x3)
				return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)+8];
			return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
		case MODRM_SPLITMISC:
			if (modFromModRM(modRM) == 0x3)
				return modRMTable[dec->instructionIDs+(modRM & 0x3f)+8];
			return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
		case MODRM_FULL:
			return modRMTable[dec->instructionIDs+modRM];
	}
}

/*
 * specifierForUID - Given a UID, returns the name and operand specification for
 *   that instruction.
 *
 * @param uid - The unique ID for the instruction.  This should be returned by
 *              decode(); specifierForUID will not check bounds.
 * @return    - A pointer to the specification for that instruction.
 */
static const struct InstructionSpecifier *specifierForUID(InstrUID uid)
{
	return &INSTRUCTIONS_SYM[uid];
}

/*
 * consumeByte - Uses the reader function provided by the user to consume one
 *   byte from the instruction's memory and advance the cursor.
 *
 * @param insn  - The instruction with the reader function to use.  The cursor
 *                for this instruction is advanced.
 * @param byte  - A pointer to a pre-allocated memory buffer to be populated
 *                with the data read.
 * @return      - 0 if the read was successful; nonzero otherwise.
 */
static int consumeByte(struct InternalInstruction *insn, uint8_t *byte)
{
	int ret = insn->reader(insn->readerArg, byte, insn->readerCursor);

	if (!ret)
		++(insn->readerCursor);

	return ret;
}

/*
 * lookAtByte - Like consumeByte, but does not advance the cursor.
 *
 * @param insn  - See consumeByte().
 * @param byte  - See consumeByte().
 * @return      - See consumeByte().
 */
static int lookAtByte(struct InternalInstruction *insn, uint8_t *byte)
{
	return insn->reader(insn->readerArg, byte, insn->readerCursor);
}

static void unconsumeByte(struct InternalInstruction *insn)
{
	insn->readerCursor--;
}

#define CONSUME_FUNC(name, type)                                  \
	static int name(struct InternalInstruction *insn, type *ptr) {  \
		type combined = 0;                                            \
		unsigned offset;                                              \
		for (offset = 0; offset < sizeof(type); ++offset) {           \
			uint8_t byte;                                               \
			int ret = insn->reader(insn->readerArg,                     \
					&byte,                               \
					insn->readerCursor + offset);        \
			if (ret)                                                    \
			return ret;                                               \
			combined = combined | (type)((uint64_t)byte << (offset * 8));     \
		}                                                             \
		*ptr = combined;                                              \
		insn->readerCursor += sizeof(type);                           \
		return 0;                                                     \
	}

/*
 * consume* - Use the reader function provided by the user to consume data
 *   values of various sizes from the instruction's memory and advance the
 *   cursor appropriately.  These readers perform endian conversion.
 *
 * @param insn    - See consumeByte().
 * @param ptr     - A pointer to a pre-allocated memory of appropriate size to
 *                  be populated with the data read.
 * @return        - See consumeByte().
 */
CONSUME_FUNC(consumeInt8, int8_t)
CONSUME_FUNC(consumeInt16, int16_t)
CONSUME_FUNC(consumeInt32, int32_t)
CONSUME_FUNC(consumeUInt16, uint16_t)
CONSUME_FUNC(consumeUInt32, uint32_t)
CONSUME_FUNC(consumeUInt64, uint64_t)

/*
 * setPrefixPresent - Marks that a particular prefix is present at a particular
 *   location.
 *
 * @param insn      - The instruction to be marked as having the prefix.
 * @param prefix    - The prefix that is present.
 * @param location  - The location where the prefix is located (in the address
 *                    space of the instruction's reader).
 */
static void setPrefixPresent(struct InternalInstruction *insn,
		uint8_t prefix, uint64_t location)
{
	switch (prefix) {
	case 0x26:
		insn->isPrefix26 = true;
		insn->prefix26 = location;
		break;
	case 0x2e:
		insn->isPrefix2e = true;
		insn->prefix2e = location;
		break;
	case 0x36:
		insn->isPrefix36 = true;
		insn->prefix36 = location;
		break;
	case 0x3e:
		insn->isPrefix3e = true;
		insn->prefix3e = location;
		break;
	case 0x64:
		insn->isPrefix64 = true;
		insn->prefix64 = location;
		break;
	case 0x65:
		insn->isPrefix65 = true;
		insn->prefix65 = location;
		break;
	case 0x66:
		insn->isPrefix66 = true;
		insn->prefix66 = location;
		break;
	case 0x67:
		insn->isPrefix67 = true;
		insn->prefix67 = location;
		break;
	case 0xf0:
		insn->isPrefixf0 = true;
		insn->prefixf0 = location;
		break;
	case 0xf2:
		insn->isPrefixf2 = true;
		insn->prefixf2 = location;
		break;
	case 0xf3:
		insn->isPrefixf3 = true;
		insn->prefixf3 = location;
		break;
	default:
		break;
	}
}

/*
 * isPrefixAtLocation - Queries an instruction to determine whether a prefix is
 *   present at a given location.
 *
 * @param insn      - The instruction to be queried.
 * @param prefix    - The prefix.
 * @param location  - The location to query.
 * @return          - Whether the prefix is at that location.
 */
static bool isPrefixAtLocation(struct InternalInstruction *insn, uint8_t prefix,
		uint64_t location)
{
	switch (prefix) {
	case 0x26:
		if (insn->isPrefix26 && insn->prefix26 == location)
			return true;
		break;
	case 0x2e:
		if (insn->isPrefix2e && insn->prefix2e == location)
			return true;
		break;
	case 0x36:
		if (insn->isPrefix36 && insn->prefix36 == location)
			return true;
		break;
	case 0x3e:
		if (insn->isPrefix3e && insn->prefix3e == location)
			return true;
		break;
	case 0x64:
		if (insn->isPrefix64 && insn->prefix64 == location)
			return true;
		break;
	case 0x65:
		if (insn->isPrefix65 && insn->prefix65 == location)
			return true;
		break;
	case 0x66:
		if (insn->isPrefix66 && insn->prefix66 == location)
			return true;
		break;
	case 0x67:
		if (insn->isPrefix67 && insn->prefix67 == location)
			return true;
		break;
	case 0xf0:
		if (insn->isPrefixf0 && insn->prefixf0 == location)
			return true;
		break;
	case 0xf2:
		if (insn->isPrefixf2 && insn->prefixf2 == location)
			return true;
		break;
	case 0xf3:
		if (insn->isPrefixf3 && insn->prefixf3 == location)
			return true;
		break;
	default:
		break;
	}
	return false;
}

/*
 * readPrefixes - Consumes all of an instruction's prefix bytes, and marks the
 *   instruction as having them.  Also sets the instruction's default operand,
 *   address, and other relevant data sizes to report operands correctly.
 *
 * @param insn  - The instruction whose prefixes are to be read.
 * @return      - 0 if the instruction could be read until the end of the prefix
 *                bytes, and no prefixes conflicted; nonzero otherwise.
 */
static int readPrefixes(struct InternalInstruction *insn)
{
	bool isPrefix = true;
	uint64_t prefixLocation;
	uint8_t byte = 0, nextByte;

	bool hasAdSize = false;
	bool hasOpSize = false;

	while (isPrefix) {
		if (insn->mode == MODE_64BIT) {
			// eliminate consecutive redundant REX bytes in front
			if (consumeByte(insn, &byte))
				return -1;

			if ((byte & 0xf0) == 0x40) {
				while(true) {
					if (lookAtByte(insn, &byte))	// out of input code
						return -1;
					if ((byte & 0xf0) == 0x40) {
						// another REX prefix, but we only remember the last one
						if (consumeByte(insn, &byte))
							return -1;
					} else
						break;
				}

				// recover the last REX byte if next byte is not a legacy prefix
				switch (byte) {
					case 0xf2:  /* REPNE/REPNZ */
					case 0xf3:  /* REP or REPE/REPZ */
					case 0xf0:  /* LOCK */
					case 0x2e:  /* CS segment override -OR- Branch not taken */
					case 0x36:  /* SS segment override -OR- Branch taken */
					case 0x3e:  /* DS segment override */
					case 0x26:  /* ES segment override */
					case 0x64:  /* FS segment override */
					case 0x65:  /* GS segment override */
					case 0x66:  /* Operand-size override */
					case 0x67:  /* Address-size override */
						break;
					default:    /* Not a prefix byte */
						unconsumeByte(insn);
						break;
				}
			} else {
				unconsumeByte(insn);
			}
		}

		prefixLocation = insn->readerCursor;

		/* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
		if (consumeByte(insn, &byte))
			return -1;

		if (insn->readerCursor - 1 == insn->startLocation
				&& (byte == 0xf2 || byte == 0xf3)) {

			if (lookAtByte(insn, &nextByte))
				return -1;

			/*
			 * If the byte is 0xf2 or 0xf3, and any of the following conditions are
			 * met:
			 * - it is followed by a LOCK (0xf0) prefix
			 * - it is followed by an xchg instruction
			 * then it should be disassembled as a xacquire/xrelease not repne/rep.
			 */
			if ((byte == 0xf2 || byte == 0xf3) &&
					((nextByte == 0xf0) |
					 ((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90)))
				insn->xAcquireRelease = true;
			/*
			 * Also if the byte is 0xf3, and the following condition is met:
			 * - it is followed by a "mov mem, reg" (opcode 0x88/0x89) or
			 *                       "mov mem, imm" (opcode 0xc6/0xc7) instructions.
			 * then it should be disassembled as an xrelease not rep.
			 */
			if (byte == 0xf3 &&
					(nextByte == 0x88 || nextByte == 0x89 ||
					 nextByte == 0xc6 || nextByte == 0xc7))
				insn->xAcquireRelease = true;

			if (insn->mode == MODE_64BIT && (nextByte & 0xf0) == 0x40) {
				if (consumeByte(insn, &nextByte))
					return -1;
				if (lookAtByte(insn, &nextByte))
					return -1;
				unconsumeByte(insn);
			}
		}

		switch (byte) {
			case 0xf2:  /* REPNE/REPNZ */
			case 0xf3:  /* REP or REPE/REPZ */
			case 0xf0:  /* LOCK */
				// only accept the last prefix
				insn->isPrefixf2 = false;
				insn->isPrefixf3 = false;
				insn->isPrefixf0 = false;
				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix0 = byte;
				break;
			case 0x2e:  /* CS segment override -OR- Branch not taken */
				insn->segmentOverride = SEG_OVERRIDE_CS;
				// only accept the last prefix
				insn->isPrefix2e = false;
				insn->isPrefix36 = false;
				insn->isPrefix3e = false;
				insn->isPrefix26 = false;
				insn->isPrefix64 = false;
				insn->isPrefix65 = false;

				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix1 = byte;
				break;
			case 0x36:  /* SS segment override -OR- Branch taken */
				insn->segmentOverride = SEG_OVERRIDE_SS;
				// only accept the last prefix
				insn->isPrefix2e = false;
				insn->isPrefix36 = false;
				insn->isPrefix3e = false;
				insn->isPrefix26 = false;
				insn->isPrefix64 = false;
				insn->isPrefix65 = false;

				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix1 = byte;
				break;
			case 0x3e:  /* DS segment override */
				insn->segmentOverride = SEG_OVERRIDE_DS;
				// only accept the last prefix
				insn->isPrefix2e = false;
				insn->isPrefix36 = false;
				insn->isPrefix3e = false;
				insn->isPrefix26 = false;
				insn->isPrefix64 = false;
				insn->isPrefix65 = false;

				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix1 = byte;
				break;
			case 0x26:  /* ES segment override */
				insn->segmentOverride = SEG_OVERRIDE_ES;
				// only accept the last prefix
				insn->isPrefix2e = false;
				insn->isPrefix36 = false;
				insn->isPrefix3e = false;
				insn->isPrefix26 = false;
				insn->isPrefix64 = false;
				insn->isPrefix65 = false;

				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix1 = byte;
				break;
			case 0x64:  /* FS segment override */
				insn->segmentOverride = SEG_OVERRIDE_FS;
				// only accept the last prefix
				insn->isPrefix2e = false;
				insn->isPrefix36 = false;
				insn->isPrefix3e = false;
				insn->isPrefix26 = false;
				insn->isPrefix64 = false;
				insn->isPrefix65 = false;

				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix1 = byte;
				break;
			case 0x65:  /* GS segment override */
				insn->segmentOverride = SEG_OVERRIDE_GS;
				// only accept the last prefix
				insn->isPrefix2e = false;
				insn->isPrefix36 = false;
				insn->isPrefix3e = false;
				insn->isPrefix26 = false;
				insn->isPrefix64 = false;
				insn->isPrefix65 = false;

				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix1 = byte;
				break;
			case 0x66:  /* Operand-size override */
				hasOpSize = true;
				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix2 = byte;
				break;
			case 0x67:  /* Address-size override */
				hasAdSize = true;
				setPrefixPresent(insn, byte, prefixLocation);
				insn->prefix3 = byte;
				break;
			default:    /* Not a prefix byte */
				isPrefix = false;
				break;
		}

		//if (isPrefix)
		//	dbgprintf(insn, "Found prefix 0x%hhx", byte);
	}

	insn->vectorExtensionType = TYPE_NO_VEX_XOP;


	if (byte == 0x62) {
		uint8_t byte1, byte2;

		if (consumeByte(insn, &byte1)) {
			//dbgprintf(insn, "Couldn't read second byte of EVEX prefix");
			return -1;
		}

		if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) &&
				((~byte1 & 0xc) == 0xc)) {
			if (lookAtByte(insn, &byte2)) {
				//dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
				return -1;
			}

			if ((byte2 & 0x4) == 0x4) {
				insn->vectorExtensionType = TYPE_EVEX;
			} else {
				unconsumeByte(insn); /* unconsume byte1 */
				unconsumeByte(insn); /* unconsume byte  */
				insn->necessaryPrefixLocation = insn->readerCursor - 2;
			}

			if (insn->vectorExtensionType == TYPE_EVEX) {
				insn->vectorExtensionPrefix[0] = byte;
				insn->vectorExtensionPrefix[1] = byte1;

				if (consumeByte(insn, &insn->vectorExtensionPrefix[2])) {
					//dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
					return -1;
				}

				if (consumeByte(insn, &insn->vectorExtensionPrefix[3])) {
					//dbgprintf(insn, "Couldn't read fourth byte of EVEX prefix");
					return -1;
				}

				/* We simulate the REX prefix for simplicity's sake */
				if (insn->mode == MODE_64BIT) {
					insn->rexPrefix = 0x40
						| (wFromEVEX3of4(insn->vectorExtensionPrefix[2]) << 3)
						| (rFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 2)
						| (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 1)
						| (bFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 0);
				}

				//dbgprintf(insn, "Found EVEX prefix 0x%hhx 0x%hhx 0x%hhx 0x%hhx",
				//		insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
				//		insn->vectorExtensionPrefix[2], insn->vectorExtensionPrefix[3]);
			}
		} else {
			// BOUND instruction
			unconsumeByte(insn); /* unconsume byte1 */
			unconsumeByte(insn); /* unconsume byte */
		}
	} else if (byte == 0xc4) {
		uint8_t byte1;

		if (lookAtByte(insn, &byte1)) {
			//dbgprintf(insn, "Couldn't read second byte of VEX");
			return -1;
		}

		if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
			insn->vectorExtensionType = TYPE_VEX_3B;
			insn->necessaryPrefixLocation = insn->readerCursor - 1;
		} else {
			unconsumeByte(insn);
			insn->necessaryPrefixLocation = insn->readerCursor - 1;
		}

		if (insn->vectorExtensionType == TYPE_VEX_3B) {
			insn->vectorExtensionPrefix[0] = byte;
			if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
				return -1;
			if (consumeByte(insn, &insn->vectorExtensionPrefix[2]))
				return -1;

			/* We simulate the REX prefix for simplicity's sake */
			if (insn->mode == MODE_64BIT) {
				insn->rexPrefix = 0x40
					| (wFromVEX3of3(insn->vectorExtensionPrefix[2]) << 3)
					| (rFromVEX2of3(insn->vectorExtensionPrefix[1]) << 2)
					| (xFromVEX2of3(insn->vectorExtensionPrefix[1]) << 1)
					| (bFromVEX2of3(insn->vectorExtensionPrefix[1]) << 0);

			}
		}
	} else if (byte == 0xc5) {
		uint8_t byte1;

		if (lookAtByte(insn, &byte1)) {
			//dbgprintf(insn, "Couldn't read second byte of VEX");
			return -1;
		}

		if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
			insn->vectorExtensionType = TYPE_VEX_2B;
		} else {
			unconsumeByte(insn);
		}

		if (insn->vectorExtensionType == TYPE_VEX_2B) {
			insn->vectorExtensionPrefix[0] = byte;
			if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
				return -1;

			if (insn->mode == MODE_64BIT) {
				insn->rexPrefix = 0x40
					| (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);
			}

			switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
				default:
					break;
				case VEX_PREFIX_66:
					hasOpSize = true;
					break;
			}
		}
	} else if (byte == 0x8f) {
		uint8_t byte1;

		if (lookAtByte(insn, &byte1)) {
			// dbgprintf(insn, "Couldn't read second byte of XOP");
			return -1;
		}

		if ((byte1 & 0x38) != 0x0) { /* 0 in these 3 bits is a POP instruction. */
			insn->vectorExtensionType = TYPE_XOP;
			insn->necessaryPrefixLocation = insn->readerCursor - 1;
		} else {
			unconsumeByte(insn);
			insn->necessaryPrefixLocation = insn->readerCursor - 1;
		}

		if (insn->vectorExtensionType == TYPE_XOP) {
			insn->vectorExtensionPrefix[0] = byte;
			if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
				return -1;
			if (consumeByte(insn, &insn->vectorExtensionPrefix[2]))
				return -1;

			/* We simulate the REX prefix for simplicity's sake */
			if (insn->mode == MODE_64BIT) {
				insn->rexPrefix = 0x40
					| (wFromXOP3of3(insn->vectorExtensionPrefix[2]) << 3)
					| (rFromXOP2of3(insn->vectorExtensionPrefix[1]) << 2)
					| (xFromXOP2of3(insn->vectorExtensionPrefix[1]) << 1)
					| (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);
			}

			switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
				default:
					break;
				case VEX_PREFIX_66:
					hasOpSize = true;
					break;
			}
		}
	} else {
		if (insn->mode == MODE_64BIT) {
			if ((byte & 0xf0) == 0x40) {
				uint8_t opcodeByte;

				while(true) {
					if (lookAtByte(insn, &opcodeByte))	// out of input code
						return -1;
					if ((opcodeByte & 0xf0) == 0x40) {
						// another REX prefix, but we only remember the last one
						if (consumeByte(insn, &byte))
							return -1;
					} else
						break;
				}

				insn->rexPrefix = byte;
				insn->necessaryPrefixLocation = insn->readerCursor - 2;
				// dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
			} else {
				unconsumeByte(insn);
				insn->necessaryPrefixLocation = insn->readerCursor - 1;
			}
		} else {
			unconsumeByte(insn);
			insn->necessaryPrefixLocation = insn->readerCursor - 1;
		}
	}

	if (insn->mode == MODE_16BIT) {
		insn->registerSize       = (hasOpSize ? 4 : 2);
		insn->addressSize        = (hasAdSize ? 4 : 2);
		insn->displacementSize   = (hasAdSize ? 4 : 2);
		insn->immediateSize      = (hasOpSize ? 4 : 2);
		insn->immSize = (hasOpSize ? 4 : 2);
	} else if (insn->mode == MODE_32BIT) {
		insn->registerSize       = (hasOpSize ? 2 : 4);
		insn->addressSize        = (hasAdSize ? 2 : 4);
		insn->displacementSize   = (hasAdSize ? 2 : 4);
		insn->immediateSize      = (hasOpSize ? 2 : 4);
		insn->immSize = (hasOpSize ? 2 : 4);
	} else if (insn->mode == MODE_64BIT) {
		if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
			insn->registerSize       = 8;
			insn->addressSize        = (hasAdSize ? 4 : 8);
			insn->displacementSize   = 4;
			insn->immediateSize      = 4;
			insn->immSize      = 4;
		} else if (insn->rexPrefix) {
			insn->registerSize       = (hasOpSize ? 2 : 4);
			insn->addressSize        = (hasAdSize ? 4 : 8);
			insn->displacementSize   = (hasOpSize ? 2 : 4);
			insn->immediateSize      = (hasOpSize ? 2 : 4);
			insn->immSize      = (hasOpSize ? 2 : 4);
		} else {
			insn->registerSize       = (hasOpSize ? 2 : 4);
			insn->addressSize        = (hasAdSize ? 4 : 8);
			insn->displacementSize   = (hasOpSize ? 2 : 4);
			insn->immediateSize      = (hasOpSize ? 2 : 4);
			insn->immSize      = (hasOpSize ? 4 : 8);
		}
	}

	return 0;
}

static int readModRM(struct InternalInstruction *insn);

/*
 * readOpcode - Reads the opcode (excepting the ModR/M byte in the case of
 *   extended or escape opcodes).
 *
 * @param insn  - The instruction whose opcode is to be read.
 * @return      - 0 if the opcode could be read successfully; nonzero otherwise.
 */
static int readOpcode(struct InternalInstruction *insn)
{
	/* Determine the length of the primary opcode */
	uint8_t current;

	// printf(">>> readOpcode() = %x\n", insn->readerCursor);

	insn->opcodeType = ONEBYTE;

	if (insn->vectorExtensionType == TYPE_EVEX) {
		switch (mmFromEVEX2of4(insn->vectorExtensionPrefix[1])) {
			default:
				// dbgprintf(insn, "Unhandled mm field for instruction (0x%hhx)",
				// 		mmFromEVEX2of4(insn->vectorExtensionPrefix[1]));
				return -1;
			case VEX_LOB_0F:
				insn->opcodeType = TWOBYTE;
				return consumeByte(insn, &insn->opcode);
			case VEX_LOB_0F38:
				insn->opcodeType = THREEBYTE_38;
				return consumeByte(insn, &insn->opcode);
			case VEX_LOB_0F3A:
				insn->opcodeType = THREEBYTE_3A;
				return consumeByte(insn, &insn->opcode);
		}
	} else if (insn->vectorExtensionType == TYPE_VEX_3B) {
		switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
			default:
				// dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
				//		mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
				return -1;
			case VEX_LOB_0F:
				insn->twoByteEscape = 0x0f;
				insn->opcodeType = TWOBYTE;
				return consumeByte(insn, &insn->opcode);
			case VEX_LOB_0F38:
				insn->twoByteEscape = 0x0f;
				insn->threeByteEscape = 0x38;
				insn->opcodeType = THREEBYTE_38;
				return consumeByte(insn, &insn->opcode);
			case VEX_LOB_0F3A:
				insn->twoByteEscape = 0x0f;
				insn->threeByteEscape = 0x3a;
				insn->opcodeType = THREEBYTE_3A;
				return consumeByte(insn, &insn->opcode);
		}
	} else if (insn->vectorExtensionType == TYPE_VEX_2B) {
		insn->twoByteEscape = 0x0f;
		insn->opcodeType = TWOBYTE;
		return consumeByte(insn, &insn->opcode);
	} else if (insn->vectorExtensionType == TYPE_XOP) {
		switch (mmmmmFromXOP2of3(insn->vectorExtensionPrefix[1])) {
			default:
				// dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
				// 		mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
				return -1;
			case XOP_MAP_SELECT_8:
				// FIXME: twoByteEscape?
				insn->opcodeType = XOP8_MAP;
				return consumeByte(insn, &insn->opcode);
			case XOP_MAP_SELECT_9:
				// FIXME: twoByteEscape?
				insn->opcodeType = XOP9_MAP;
				return consumeByte(insn, &insn->opcode);
			case XOP_MAP_SELECT_A:
				// FIXME: twoByteEscape?
				insn->opcodeType = XOPA_MAP;
				return consumeByte(insn, &insn->opcode);
		}
	}

	if (consumeByte(insn, &current))
		return -1;

	// save this first byte for MOVcr, MOVdr, MOVrc, MOVrd
	insn->firstByte = current;

	if (current == 0x0f) {
		// dbgprintf(insn, "Found a two-byte escape prefix (0x%hhx)", current);

		insn->twoByteEscape = current;

		if (consumeByte(insn, &current))
			return -1;

		if (current == 0x38) {
			// dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);

			insn->threeByteEscape = current;

			if (consumeByte(insn, &current))
				return -1;

			insn->opcodeType = THREEBYTE_38;
		} else if (current == 0x3a) {
			// dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);

			insn->threeByteEscape = current;

			if (consumeByte(insn, &current))
				return -1;

			insn->opcodeType = THREEBYTE_3A;
		} else {
#ifndef CAPSTONE_X86_REDUCE
			switch(current) {
				default:
					// dbgprintf(insn, "Didn't find a three-byte escape prefix");
					insn->opcodeType = TWOBYTE;
					break;
				case 0x0e:	// HACK for femms. to be handled properly in next version 3.x
					insn->opcodeType = T3DNOW_MAP;
					// this encode does not have ModRM
					insn->consumedModRM = true;
					break;
				case 0x0f:
					// 3DNow instruction has weird format: ModRM/SIB/displacement + opcode
					if (readModRM(insn))
						return -1;
					// next is 3DNow opcode
					if (consumeByte(insn, &current))
						return -1;
					insn->opcodeType = T3DNOW_MAP;
					break;
			}
#endif
		}
	}

	/*
	 * At this point we have consumed the full opcode.
	 * Anything we consume from here on must be unconsumed.
	 */

	insn->opcode = current;

	return 0;
}

// Hacky for FEMMS
#define GET_INSTRINFO_ENUM
#ifndef CAPSTONE_X86_REDUCE
#include "X86GenInstrInfo.inc"
#else
#include "X86GenInstrInfo_reduce.inc"
#endif

/*
 * getIDWithAttrMask - Determines the ID of an instruction, consuming
 *   the ModR/M byte as appropriate for extended and escape opcodes,
 *   and using a supplied attribute mask.
 *
 * @param instructionID - A pointer whose target is filled in with the ID of the
 *                        instruction.
 * @param insn          - The instruction whose ID is to be determined.
 * @param attrMask      - The attribute mask to search.
 * @return              - 0 if the ModR/M could be read when needed or was not
 *                        needed; nonzero otherwise.
 */
static int getIDWithAttrMask(uint16_t *instructionID,
		struct InternalInstruction *insn,
		uint16_t attrMask)
{
	bool hasModRMExtension;

	InstructionContext instructionClass;

#ifndef CAPSTONE_X86_REDUCE
	// HACK for femms. to be handled properly in next version 3.x
	if (insn->opcode == 0x0e && insn->opcodeType == T3DNOW_MAP) {
		*instructionID = X86_FEMMS;
		return 0;
	}
#endif

	if (insn->opcodeType == T3DNOW_MAP)
		instructionClass = IC_OF;
	else
		instructionClass = contextForAttrs(attrMask);

	hasModRMExtension = modRMRequired(insn->opcodeType,
			instructionClass,
			insn->opcode) != 0;

	if (hasModRMExtension) {
		if (readModRM(insn))
			return -1;

		*instructionID = decode(insn->opcodeType,
				instructionClass,
				insn->opcode,
				insn->modRM);
	} else {
		*instructionID = decode(insn->opcodeType,
				instructionClass,
				insn->opcode,
				0);
	}

	return 0;
}

/*
 * is16BitEquivalent - Determines whether two instruction names refer to
 * equivalent instructions but one is 16-bit whereas the other is not.
 *
 * @param orig  - The instruction ID that is not 16-bit
 * @param equiv - The instruction ID that is 16-bit
 */
static bool is16BitEquivalent(unsigned orig, unsigned equiv)
{
	size_t i;
	uint16_t idx;

	if ((idx = x86_16_bit_eq_lookup[orig]) != 0) {
		for (i = idx - 1; i < ARR_SIZE(x86_16_bit_eq_tbl) && x86_16_bit_eq_tbl[i].first == orig; i++) {
			if (x86_16_bit_eq_tbl[i].second == equiv)
				return true;
		}
	}

	return false;
}

/*
 * 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.
 *
 * @param insn  - The instruction whose ID is to be determined.
 * @return      - 0 if the ModR/M could be read when needed or was not needed;
 *                nonzero otherwise.
 */
static int getID(struct InternalInstruction *insn)
{
	uint16_t attrMask;
	uint16_t instructionID;
	const struct InstructionSpecifier *spec;

	// printf(">>> getID()\n");
	attrMask = ATTR_NONE;

	if (insn->mode == MODE_64BIT)
		attrMask |= ATTR_64BIT;

	if (insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
		attrMask |= (insn->vectorExtensionType == TYPE_EVEX) ? ATTR_EVEX : ATTR_VEX;

		if (insn->vectorExtensionType == TYPE_EVEX) {
			switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
				case VEX_PREFIX_66:
					attrMask |= ATTR_OPSIZE;
					break;
				case VEX_PREFIX_F3:
					attrMask |= ATTR_XS;
					break;
				case VEX_PREFIX_F2:
					attrMask |= ATTR_XD;
					break;
			}

			if (zFromEVEX4of4(insn->vectorExtensionPrefix[3]))
				attrMask |= ATTR_EVEXKZ;
			if (bFromEVEX4of4(insn->vectorExtensionPrefix[3]))
				attrMask |= ATTR_EVEXB;
			if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]))
				attrMask |= ATTR_EVEXK;
			if (lFromEVEX4of4(insn->vectorExtensionPrefix[3]))
				attrMask |= ATTR_EVEXL;
			if (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
				attrMask |= ATTR_EVEXL2;
		} else if (insn->vectorExtensionType == TYPE_VEX_3B) {
			switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
				case VEX_PREFIX_66:
					attrMask |= ATTR_OPSIZE;
					break;
				case VEX_PREFIX_F3:
					attrMask |= ATTR_XS;
					break;
				case VEX_PREFIX_F2:
					attrMask |= ATTR_XD;
					break;
			}

			if (lFromVEX3of3(insn->vectorExtensionPrefix[2]))
				attrMask |= ATTR_VEXL;
		} else if (insn->vectorExtensionType == TYPE_VEX_2B) {
			switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
				case VEX_PREFIX_66:
					attrMask |= ATTR_OPSIZE;
					break;
				case VEX_PREFIX_F3:
					attrMask |= ATTR_XS;
					break;
				case VEX_PREFIX_F2:
					attrMask |= ATTR_XD;
					break;
			}

			if (lFromVEX2of2(insn->vectorExtensionPrefix[1]))
				attrMask |= ATTR_VEXL;
		} else if (insn->vectorExtensionType == TYPE_XOP) {
			switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
				case VEX_PREFIX_66:
					attrMask |= ATTR_OPSIZE;
					break;
				case VEX_PREFIX_F3:
					attrMask |= ATTR_XS;
					break;
				case VEX_PREFIX_F2:
					attrMask |= ATTR_XD;
					break;
			}

			if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
				attrMask |= ATTR_VEXL;
		} else {
			return -1;
		}
	} else {
		if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) {
			attrMask |= ATTR_OPSIZE;
		} else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation)) {
			attrMask |= ATTR_ADSIZE;
		} 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;

	/*
	 * JCXZ/JECXZ need special handling for 16-bit mode because the meaning
	 * of the AdSize prefix is inverted w.r.t. 32-bit mode.
	 */
	if (insn->mode == MODE_16BIT && insn->opcode == 0xE3) {
		spec = specifierForUID(instructionID);

		/*
		 * Check for Ii8PCRel instructions. We could alternatively do a
		 * string-compare on the names, but this is probably cheaper.
		 */
		if (x86OperandSets[spec->operands][0].type == TYPE_REL8) {
			attrMask ^= ATTR_ADSIZE;
			if (getIDWithAttrMask(&instructionID, insn, attrMask))
				return -1;
		}
	}

	/* The following clauses compensate for limitations of the tables. */
	if ((insn->mode == MODE_16BIT || insn->isPrefix66) &&
			!(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
		 * particular spot (i.e., many MMX operations).  In general we're
		 * conservative, but in the specific case where OpSize is present but not
		 * in the right place we check if there's a 16-bit operation.
		 */

		const struct InstructionSpecifier *spec;
		uint16_t instructionIDWithOpsize;

		spec = specifierForUID(instructionID);

		if (getIDWithAttrMask(&instructionIDWithOpsize,
					insn, attrMask | ATTR_OPSIZE)) {
			/*
			 * ModRM required with OpSize but not present; give up and return version
			 * without OpSize set
			 */

			insn->instructionID = instructionID;
			insn->spec = spec;
			return 0;
		}

		if (is16BitEquivalent(instructionID, instructionIDWithOpsize) &&
				(insn->mode == MODE_16BIT) ^ insn->isPrefix66) {
			insn->instructionID = instructionIDWithOpsize;
			insn->spec = specifierForUID(instructionIDWithOpsize);
		} else {
			insn->instructionID = instructionID;
			insn->spec = spec;
		}
		return 0;
	}

	if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 &&
			insn->rexPrefix & 0x01) {
		/*
		 * NOOP shouldn't decode as NOOP if REX.b is set. Instead
		 * it should decode as XCHG %r8, %eax.
		 */

		const struct InstructionSpecifier *spec;
		uint16_t instructionIDWithNewOpcode;
		const struct InstructionSpecifier *specWithNewOpcode;

		spec = specifierForUID(instructionID);

		/* Borrow opcode from one of the other XCHGar opcodes */
		insn->opcode = 0x91;

		if (getIDWithAttrMask(&instructionIDWithNewOpcode,
					insn,
					attrMask)) {
			insn->opcode = 0x90;

			insn->instructionID = instructionID;
			insn->spec = spec;
			return 0;
		}

		specWithNewOpcode = specifierForUID(instructionIDWithNewOpcode);

		/* Change back */
		insn->opcode = 0x90;

		insn->instructionID = instructionIDWithNewOpcode;
		insn->spec = specWithNewOpcode;

		return 0;
	}

	insn->instructionID = instructionID;
	insn->spec = specifierForUID(insn->instructionID);

	return 0;
}

/*
 * readSIB - Consumes the SIB byte to determine addressing information for an
 *   instruction.
 *
 * @param insn  - The instruction whose SIB byte is to be read.
 * @return      - 0 if the SIB byte was successfully read; nonzero otherwise.
 */
static int readSIB(struct InternalInstruction *insn)
{
	SIBIndex sibIndexBase = SIB_INDEX_NONE;
	SIBBase sibBaseBase = SIB_BASE_NONE;
	uint8_t index, base;

	// dbgprintf(insn, "readSIB()");

	if (insn->consumedSIB)
		return 0;

	insn->consumedSIB = true;

	switch (insn->addressSize) {
		case 2:
			// dbgprintf(insn, "SIB-based addressing doesn't work in 16-bit mode");
			return -1;
		case 4:
			sibIndexBase = SIB_INDEX_EAX;
			sibBaseBase = SIB_BASE_EAX;
			break;
		case 8:
			sibIndexBase = SIB_INDEX_RAX;
			sibBaseBase = SIB_BASE_RAX;
			break;
	}

	if (consumeByte(insn, &insn->sib))
		return -1;

	index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3);
	if (insn->vectorExtensionType == TYPE_EVEX)
		index |= v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4;

	switch (index) {
		case 0x4:
			insn->sibIndex = SIB_INDEX_NONE;
			break;
		default:
			insn->sibIndex = (SIBIndex)(sibIndexBase + index);
			if (insn->sibIndex == SIB_INDEX_sib ||
					insn->sibIndex == SIB_INDEX_sib64)
				insn->sibIndex = SIB_INDEX_NONE;
			break;
	}

	switch (scaleFromSIB(insn->sib)) {
		case 0:
			insn->sibScale = 1;
			break;
		case 1:
			insn->sibScale = 2;
			break;
		case 2:
			insn->sibScale = 4;
			break;
		case 3:
			insn->sibScale = 8;
			break;
	}

	base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);

	switch (base) {
		case 0x5:
		case 0xd:
			switch (modFromModRM(insn->modRM)) {
				case 0x0:
					insn->eaDisplacement = EA_DISP_32;
					insn->sibBase = SIB_BASE_NONE;
					break;
				case 0x1:
					insn->eaDisplacement = EA_DISP_8;
					insn->sibBase = (SIBBase)(sibBaseBase + base);
					break;
				case 0x2:
					insn->eaDisplacement = EA_DISP_32;
					insn->sibBase = (SIBBase)(sibBaseBase + base);
					break;
				case 0x3:
					//debug("Cannot have Mod = 0b11 and a SIB byte");
					return -1;
			}
			break;
		default:
			insn->sibBase = (SIBBase)(sibBaseBase + base);
			break;
	}

	return 0;
}

/*
 * readDisplacement - Consumes the displacement of an instruction.
 *
 * @param insn  - The instruction whose displacement is to be read.
 * @return      - 0 if the displacement byte was successfully read; nonzero
 *                otherwise.
 */
static int readDisplacement(struct InternalInstruction *insn)
{
	int8_t d8;
	int16_t d16;
	int32_t d32;

	// dbgprintf(insn, "readDisplacement()");

	if (insn->consumedDisplacement)
		return 0;

	insn->consumedDisplacement = true;
	insn->displacementOffset = (uint8_t)(insn->readerCursor - insn->startLocation);

	switch (insn->eaDisplacement) {
		case EA_DISP_NONE:
			insn->consumedDisplacement = false;
			break;
		case EA_DISP_8:
			if (consumeInt8(insn, &d8))
				return -1;
			insn->displacement = d8;
			break;
		case EA_DISP_16:
			if (consumeInt16(insn, &d16))
				return -1;
			insn->displacement = d16;
			break;
		case EA_DISP_32:
			if (consumeInt32(insn, &d32))
				return -1;
			insn->displacement = d32;
			break;
	}

	insn->consumedDisplacement = true;
	return 0;
}

/*
 * readModRM - Consumes all addressing information (ModR/M byte, SIB byte, and
 *   displacement) for an instruction and interprets it.
 *
 * @param insn  - The instruction whose addressing information is to be read.
 * @return      - 0 if the information was successfully read; nonzero otherwise.
 */
static int readModRM(struct InternalInstruction *insn)
{
	uint8_t mod, rm, reg;

	// dbgprintf(insn, "readModRM()");

	// already got ModRM byte?
	if (insn->consumedModRM)
		return 0;

	if (consumeByte(insn, &insn->modRM))
		return -1;

	// mark that we already got ModRM
	insn->consumedModRM = true;

	// save original ModRM for later reference
	insn->orgModRM = insn->modRM;

	// handle MOVcr, MOVdr, MOVrc, MOVrd by pretending they have MRM.mod = 3
	if ((insn->firstByte == 0x0f && insn->opcodeType == TWOBYTE) &&
			(insn->opcode >= 0x20 && insn->opcode <= 0x23 ))
		insn->modRM |= 0xC0;

	mod     = modFromModRM(insn->modRM);
	rm      = rmFromModRM(insn->modRM);
	reg     = regFromModRM(insn->modRM);

	/*
	 * This goes by insn->registerSize to pick the correct register, which messes
	 * up if we're using (say) XMM or 8-bit register operands.  That gets fixed in
	 * fixupReg().
	 */
	switch (insn->registerSize) {
		case 2:
			insn->regBase = MODRM_REG_AX;
			insn->eaRegBase = EA_REG_AX;
			break;
		case 4:
			insn->regBase = MODRM_REG_EAX;
			insn->eaRegBase = EA_REG_EAX;
			break;
		case 8:
			insn->regBase = MODRM_REG_RAX;
			insn->eaRegBase = EA_REG_RAX;
			break;
	}

	reg |= rFromREX(insn->rexPrefix) << 3;
	rm  |= bFromREX(insn->rexPrefix) << 3;
	if (insn->vectorExtensionType == TYPE_EVEX) {
		reg |= r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
		rm  |=  xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
	}

	insn->reg = (Reg)(insn->regBase + reg);

	switch (insn->addressSize) {
		case 2:
			insn->eaBaseBase = EA_BASE_BX_SI;

			switch (mod) {
				case 0x0:
					if (rm == 0x6) {
						insn->eaBase = EA_BASE_NONE;
						insn->eaDisplacement = EA_DISP_16;
						if (readDisplacement(insn))
							return -1;
					} else {
						insn->eaBase = (EABase)(insn->eaBaseBase + rm);
						insn->eaDisplacement = EA_DISP_NONE;
					}
					break;
				case 0x1:
					insn->eaBase = (EABase)(insn->eaBaseBase + rm);
					insn->eaDisplacement = EA_DISP_8;
					insn->displacementSize = 1;
					if (readDisplacement(insn))
						return -1;
					break;
				case 0x2:
					insn->eaBase = (EABase)(insn->eaBaseBase + rm);
					insn->eaDisplacement = EA_DISP_16;
					if (readDisplacement(insn))
						return -1;
					break;
				case 0x3:
					insn->eaBase = (EABase)(insn->eaRegBase + rm);
					insn->eaDisplacement = EA_DISP_NONE;
					if (readDisplacement(insn))
						return -1;
					break;
			}
			break;
		case 4:
		case 8:
			insn->eaBaseBase = (insn->addressSize == 4 ? EA_BASE_EAX : EA_BASE_RAX);

			switch (mod) {
				case 0x0:
					insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */
					switch (rm) {
						case 0x14:
						case 0x4:
						case 0xc:   /* in case REXW.b is set */
							insn->eaBase = (insn->addressSize == 4 ?
									EA_BASE_sib : EA_BASE_sib64);
							if (readSIB(insn) || readDisplacement(insn))
								return -1;
							break;
						case 0x5:
						case 0xd:
							insn->eaBase = EA_BASE_NONE;
							insn->eaDisplacement = EA_DISP_32;
							if (readDisplacement(insn))
								return -1;
							break;
						default:
							insn->eaBase = (EABase)(insn->eaBaseBase + rm);
							break;
					}

					break;
				case 0x1:
					insn->displacementSize = 1;
					/* FALLTHROUGH */
				case 0x2:
					insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
					switch (rm) {
						case 0x14:
						case 0x4:
						case 0xc:   /* in case REXW.b is set */
							insn->eaBase = EA_BASE_sib;
							if (readSIB(insn) || readDisplacement(insn))
								return -1;
							break;
						default:
							insn->eaBase = (EABase)(insn->eaBaseBase + rm);
							if (readDisplacement(insn))
								return -1;
							break;
					}
					break;
				case 0x3:
					insn->eaDisplacement = EA_DISP_NONE;
					insn->eaBase = (EABase)(insn->eaRegBase + rm);
					break;
			}
			break;
	} /* switch (insn->addressSize) */

	return 0;
}

#define GENERIC_FIXUP_FUNC(name, base, prefix)            \
	static uint8_t name(struct InternalInstruction *insn,   \
			OperandType type,                   \
			uint8_t index,                      \
			uint8_t *valid) {                   \
		*valid = 1;                                           \
		switch (type) {                                       \
			case TYPE_R8:       \
			    insn->operandSize = 1; \
				break; \
			case TYPE_R16:      \
			    insn->operandSize = 2; \
				break; \
			case TYPE_R32:      \
			    insn->operandSize = 4; \
				break; \
			case TYPE_R64:      \
			    insn->operandSize = 8; \
				break; \
			case TYPE_XMM512:   \
			    insn->operandSize = 64; \
				break; \
			case TYPE_XMM256:   \
			    insn->operandSize = 32; \
				break; \
			case TYPE_XMM128:   \
			    insn->operandSize = 16; \
				break; \
			case TYPE_XMM64:    \
			    insn->operandSize = 8; \
				break; \
			case TYPE_XMM32:    \
			    insn->operandSize = 4; \
				break; \
			case TYPE_XMM:      \
			    insn->operandSize = 2; \
				break; \
			case TYPE_MM64:     \
			    insn->operandSize = 8; \
				break; \
			case TYPE_MM32:     \
			    insn->operandSize = 4; \
				break; \
			case TYPE_MM:       \
			    insn->operandSize = 2; \
				break; \
			case TYPE_CONTROLREG: \
			    insn->operandSize = 4; \
				break; \
			default: break; \
		} \
		switch (type) {                                           \
			default:                                              \
				*valid = 0;                                       \
				return 0;                                         \
			case TYPE_Rv:                                         \
				return (uint8_t)(base + index);                   \
			case TYPE_R8:                                         \
				if (insn->rexPrefix &&                            \
					index >= 4 && index <= 7) { \
					return prefix##_SPL + (index - 4);        \
				} else {                                      \
					return prefix##_AL + index;               \
				}                                             \
			case TYPE_R16:                                        \
				return prefix##_AX + index;                       \
			case TYPE_R32:                                        \
				return prefix##_EAX + index;                      \
			case TYPE_R64:                                        \
				return prefix##_RAX + index;                      \
			case TYPE_XMM512:                                     \
				return prefix##_ZMM0 + index;                     \
			case TYPE_XMM256:                                     \
				return prefix##_YMM0 + index;                     \
			case TYPE_XMM128:                                     \
			case TYPE_XMM64:                                      \
			case TYPE_XMM32:                                      \
			case TYPE_XMM:                                        \
				return prefix##_XMM0 + index;                     \
			case TYPE_VK1:                                        \
			case TYPE_VK8:                                        \
			case TYPE_VK16:                                       \
				if (index > 7)                                    \
					*valid = 0;                                   \
				return prefix##_K0 + index;                       \
			case TYPE_MM64:                                       \
			case TYPE_MM32:                                       \
			case TYPE_MM:                                         \
				return prefix##_MM0 + (index & 7);                \
			case TYPE_SEGMENTREG:                                 \
				if (index > 5)                                    \
					*valid = 0;                                   \
				return prefix##_ES + index;                       \
			case TYPE_DEBUGREG:                                   \
				if (index > 7)                                    \
					*valid = 0;                                   \
				return prefix##_DR0 + index;                      \
			case TYPE_CONTROLREG:                                 \
				return prefix##_CR0 + index;                      \
		}                                                         \
	}

/*
 * fixup*Value - Consults an operand type to determine the meaning of the
 *   reg or R/M field.  If the operand is an XMM operand, for example, an
 *   operand would be XMM0 instead of AX, which readModRM() would otherwise
 *   misinterpret it as.
 *
 * @param insn  - The instruction containing the operand.
 * @param type  - The operand type.
 * @param index - The existing value of the field as reported by readModRM().
 * @param valid - The address of a uint8_t.  The target is set to 1 if the
 *                field is valid for the register class; 0 if not.
 * @return      - The proper value.
 */
GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase,    MODRM_REG)
GENERIC_FIXUP_FUNC(fixupRMValue,  insn->eaRegBase,  EA_REG)

/*
 * fixupReg - Consults an operand specifier to determine which of the
 *   fixup*Value functions to use in correcting readModRM()'ss interpretation.
 *
 * @param insn  - See fixup*Value().
 * @param op    - The operand specifier.
 * @return      - 0 if fixup was successful; -1 if the register returned was
 *                invalid for its class.
 */
static int fixupReg(struct InternalInstruction *insn,
		const struct OperandSpecifier *op)
{
	uint8_t valid;

	// dbgprintf(insn, "fixupReg()");

	switch ((OperandEncoding)op->encoding) {
		default:
			//debug("Expected a REG or R/M encoding in fixupReg");
			return -1;
		case ENCODING_VVVV:
			insn->vvvv = (Reg)fixupRegValue(insn,
					(OperandType)op->type,
					insn->vvvv,
					&valid);
			if (!valid)
				return -1;
			break;
		case ENCODING_REG:
			insn->reg = (Reg)fixupRegValue(insn,
					(OperandType)op->type,
					(uint8_t)(insn->reg - insn->regBase),
					&valid);
			if (!valid)
				return -1;
			break;
		CASE_ENCODING_RM:
			if (insn->eaBase >= insn->eaRegBase) {
				insn->eaBase = (EABase)fixupRMValue(insn,
						(OperandType)op->type,
						(uint8_t)(insn->eaBase - insn->eaRegBase),
						&valid);
				if (!valid)
					return -1;
			}
			break;
	}

	return 0;
}

/*
 * readOpcodeRegister - Reads an operand from the opcode field of an
 *   instruction and interprets it appropriately given the operand width.
 *   Handles AddRegFrm instructions.
 *
 * @param insn  - the instruction whose opcode field is to be read.
 * @param size  - The width (in bytes) of the register being specified.
 *                1 means AL and friends, 2 means AX, 4 means EAX, and 8 means
 *                RAX.
 * @return      - 0 on success; nonzero otherwise.
 */
static int readOpcodeRegister(struct InternalInstruction *insn, uint8_t size)
{
	// dbgprintf(insn, "readOpcodeRegister()");

	if (size == 0)
		size = insn->registerSize;

	insn->operandSize = size;

	switch (size) {
		case 1:
			insn->opcodeRegister = (Reg)(MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3)
						| (insn->opcode & 7)));
			if (insn->rexPrefix &&
					insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
					insn->opcodeRegister < MODRM_REG_AL + 0x8) {
				insn->opcodeRegister = (Reg)(MODRM_REG_SPL
						+ (insn->opcodeRegister - MODRM_REG_AL - 4));
			}

			break;
		case 2:
			insn->opcodeRegister = (Reg)(MODRM_REG_AX
					+ ((bFromREX(insn->rexPrefix) << 3)
						| (insn->opcode & 7)));
			break;
		case 4:
			insn->opcodeRegister = (Reg)(MODRM_REG_EAX
					+ ((bFromREX(insn->rexPrefix) << 3)
						| (insn->opcode & 7)));
			break;
		case 8:
			insn->opcodeRegister = (Reg)(MODRM_REG_RAX
					+ ((bFromREX(insn->rexPrefix) << 3)
						| (insn->opcode & 7)));
			break;
	}

	return 0;
}

/*
 * readImmediate - Consumes an immediate operand from an instruction, given the
 *   desired operand size.
 *
 * @param insn  - The instruction whose operand is to be read.
 * @param size  - The width (in bytes) of the operand.
 * @return      - 0 if the immediate was successfully consumed; nonzero
 *                otherwise.
 */
static int readImmediate(struct InternalInstruction *insn, uint8_t size)
{
	uint8_t imm8;
	uint16_t imm16;
	uint32_t imm32;
	uint64_t imm64;

	// dbgprintf(insn, "readImmediate()");

	if (insn->numImmediatesConsumed == 2) {
		//debug("Already consumed two immediates");
		return -1;
	}

	if (size == 0)
		size = insn->immediateSize;
	else
		insn->immediateSize = size;
	insn->immediateOffset = (uint8_t)(insn->readerCursor - insn->startLocation);

	switch (size) {
		case 1:
			if (consumeByte(insn, &imm8))
				return -1;
			insn->immediates[insn->numImmediatesConsumed] = imm8;
			break;
		case 2:
			if (consumeUInt16(insn, &imm16))
				return -1;
			insn->immediates[insn->numImmediatesConsumed] = imm16;
			break;
		case 4:
			if (consumeUInt32(insn, &imm32))
				return -1;
			insn->immediates[insn->numImmediatesConsumed] = imm32;
			break;
		case 8:
			if (consumeUInt64(insn, &imm64))
				return -1;
			insn->immediates[insn->numImmediatesConsumed] = imm64;
			break;
	}

	insn->numImmediatesConsumed++;

	return 0;
}

/*
 * readVVVV - Consumes vvvv from an instruction if it has a VEX prefix.
 *
 * @param insn  - The instruction whose operand is to be read.
 * @return      - 0 if the vvvv was successfully consumed; nonzero
 *                otherwise.
 */
static int readVVVV(struct InternalInstruction *insn)
{
	int vvvv;
	// dbgprintf(insn, "readVVVV()");

	if (insn->vectorExtensionType == TYPE_EVEX)
		vvvv = (v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4 |
				vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]));
	else if (insn->vectorExtensionType == TYPE_VEX_3B)
		vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]);
	else if (insn->vectorExtensionType == TYPE_VEX_2B)
		vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]);
	else if (insn->vectorExtensionType == TYPE_XOP)
		vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]);
	else
		return -1;

	if (insn->mode != MODE_64BIT)
		vvvv &= 0x7;

	insn->vvvv = vvvv;

	return 0;
}

/*
 * readMaskRegister - Reads an mask register from the opcode field of an
 *   instruction.
 *
 * @param insn    - The instruction whose opcode field is to be read.
 * @return        - 0 on success; nonzero otherwise.
 */
static int readMaskRegister(struct InternalInstruction *insn)
{
	// dbgprintf(insn, "readMaskRegister()");

	if (insn->vectorExtensionType != TYPE_EVEX)
		return -1;

	insn->writemask = aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]);

	return 0;
}
	 
/*
 * readOperands - Consults the specifier for an instruction and consumes all
 *   operands for that instruction, interpreting them as it goes.
 *
 * @param insn  - The instruction whose operands are to be read and interpreted.
 * @return      - 0 if all operands could be read; nonzero otherwise.
 */
static int readOperands(struct InternalInstruction *insn)
{
	int index;
	int hasVVVV, needVVVV;
	int sawRegImm = 0;

	// printf(">>> readOperands()\n");
	/* If non-zero vvvv specified, need to make sure one of the operands
	   uses it. */
	hasVVVV = !readVVVV(insn);
	needVVVV = hasVVVV && (insn->vvvv != 0);

	for (index = 0; index < X86_MAX_OPERANDS; ++index) {
		//printf(">>> encoding[%u] = %u\n", index, x86OperandSets[insn->spec->operands][index].encoding);
		switch (x86OperandSets[insn->spec->operands][index].encoding) {
			case ENCODING_NONE:
			case ENCODING_SI:
			case ENCODING_DI:
				break;
			case ENCODING_REG:
			CASE_ENCODING_RM:
				if (readModRM(insn))
					return -1;
				if (fixupReg(insn, &x86OperandSets[insn->spec->operands][index]))
					return -1;
				// Apply the AVX512 compressed displacement scaling factor.
				if (x86OperandSets[insn->spec->operands][index].encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
					insn->displacement *= 1 << (x86OperandSets[insn->spec->operands][index].encoding - ENCODING_RM);
				break;
			case ENCODING_CB:
			case ENCODING_CW:
			case ENCODING_CD:
			case ENCODING_CP:
			case ENCODING_CO:
			case ENCODING_CT:
				// dbgprintf(insn, "We currently don't hande code-offset encodings");
				return -1;
			case ENCODING_IB:
				if (sawRegImm) {
					/* Saw a register immediate so don't read again and instead split the
					   previous immediate.  FIXME: This is a hack. */
					insn->immediates[insn->numImmediatesConsumed] =
						insn->immediates[insn->numImmediatesConsumed - 1] & 0xf;
					++insn->numImmediatesConsumed;
					break;
				}
				if (readImmediate(insn, 1))
					return -1;
				if (x86OperandSets[insn->spec->operands][index].type == TYPE_XMM128 ||
						x86OperandSets[insn->spec->operands][index].type == TYPE_XMM256)
					sawRegImm = 1;
				break;
			case ENCODING_IW:
				if (readImmediate(insn, 2))
					return -1;
				break;
			case ENCODING_ID:
				if (readImmediate(insn, 4))
					return -1;
				break;
			case ENCODING_IO:
				if (readImmediate(insn, 8))
					return -1;
				break;
			case ENCODING_Iv:
				if (readImmediate(insn, insn->immediateSize))
					return -1;
				break;
			case ENCODING_Ia:
				if (readImmediate(insn, insn->addressSize))
					return -1;
				break;
			case ENCODING_RB:
				if (readOpcodeRegister(insn, 1))
					return -1;
				break;
			case ENCODING_RW:
				if (readOpcodeRegister(insn, 2))
					return -1;
				break;
			case ENCODING_RD:
				if (readOpcodeRegister(insn, 4))
					return -1;
				break;
			case ENCODING_RO:
				if (readOpcodeRegister(insn, 8))
					return -1;
				break;
			case ENCODING_Rv:
				if (readOpcodeRegister(insn, 0))
					return -1;
				break;
			case ENCODING_FP:
				break;
			case ENCODING_VVVV:
				needVVVV = 0; /* Mark that we have found a VVVV operand. */
				if (!hasVVVV)
					return -1;
				if (fixupReg(insn, &x86OperandSets[insn->spec->operands][index]))
					return -1;
				break;
			case ENCODING_WRITEMASK:
				if (readMaskRegister(insn))
					return -1;
				break;
			case ENCODING_DUP:
				break;
			default:
				// dbgprintf(insn, "Encountered an operand with an unknown encoding.");
				return -1;
		}
	}

	/* If we didn't find ENCODING_VVVV operand, but non-zero vvvv present, fail */
	if (needVVVV) return -1;

	return 0;
}

// return True if instruction is illegal to use with prefixes
// This also check & fix the prefixPresent[] when a prefix is irrelevant.
static bool checkPrefix(struct InternalInstruction *insn)
{
	// LOCK prefix
	if (insn->isPrefixf0) {
		switch(insn->instructionID) {
			default:
				// invalid LOCK
				return true;

			// DEC
			case X86_DEC16m:
			case X86_DEC32m:
			case X86_DEC64_16m:
			case X86_DEC64_32m:
			case X86_DEC64m:
			case X86_DEC8m:

			// ADC
			case X86_ADC16mi:
			case X86_ADC16mi8:
			case X86_ADC16mr:
			case X86_ADC32mi:
			case X86_ADC32mi8:
			case X86_ADC32mr:
			case X86_ADC64mi32:
			case X86_ADC64mi8:
			case X86_ADC64mr:
			case X86_ADC8mi:
			case X86_ADC8mr:

			// ADD
			case X86_ADD16mi:
			case X86_ADD16mi8:
			case X86_ADD16mr:
			case X86_ADD32mi:
			case X86_ADD32mi8:
			case X86_ADD32mr:
			case X86_ADD64mi32:
			case X86_ADD64mi8:
			case X86_ADD64mr:
			case X86_ADD8mi:
			case X86_ADD8mr:

			// AND
			case X86_AND16mi:
			case X86_AND16mi8:
			case X86_AND16mr:
			case X86_AND32mi:
			case X86_AND32mi8:
			case X86_AND32mr:
			case X86_AND64mi32:
			case X86_AND64mi8:
			case X86_AND64mr:
			case X86_AND8mi:
			case X86_AND8mr:

			// BTC
			case X86_BTC16mi8:
			case X86_BTC16mr:
			case X86_BTC32mi8:
			case X86_BTC32mr:
			case X86_BTC64mi8:
			case X86_BTC64mr:

			// BTR
			case X86_BTR16mi8:
			case X86_BTR16mr:
			case X86_BTR32mi8:
			case X86_BTR32mr:
			case X86_BTR64mi8:
			case X86_BTR64mr:

			// BTS
			case X86_BTS16mi8:
			case X86_BTS16mr:
			case X86_BTS32mi8:
			case X86_BTS32mr:
			case X86_BTS64mi8:
			case X86_BTS64mr:

			// CMPXCHG
			case X86_CMPXCHG16B:
			case X86_CMPXCHG16rm:
			case X86_CMPXCHG32rm:
			case X86_CMPXCHG64rm:
			case X86_CMPXCHG8rm:
			case X86_CMPXCHG8B:

			// INC
			case X86_INC16m:
			case X86_INC32m:
			case X86_INC64_16m:
			case X86_INC64_32m:
			case X86_INC64m:
			case X86_INC8m:

			// NEG
			case X86_NEG16m:
			case X86_NEG32m:
			case X86_NEG64m:
			case X86_NEG8m:

			// NOT
			case X86_NOT16m:
			case X86_NOT32m:
			case X86_NOT64m:
			case X86_NOT8m:

			// OR
			case X86_OR16mi:
			case X86_OR16mi8:
			case X86_OR16mr:
			case X86_OR32mi:
			case X86_OR32mi8:
			case X86_OR32mr:
			case X86_OR32mrLocked:
			case X86_OR64mi32:
			case X86_OR64mi8:
			case X86_OR64mr:
			case X86_OR8mi:
			case X86_OR8mr:

			// SBB
			case X86_SBB16mi:
			case X86_SBB16mi8:
			case X86_SBB16mr:
			case X86_SBB32mi:
			case X86_SBB32mi8:
			case X86_SBB32mr:
			case X86_SBB64mi32:
			case X86_SBB64mi8:
			case X86_SBB64mr:
			case X86_SBB8mi:
			case X86_SBB8mr:

			// SUB
			case X86_SUB16mi:
			case X86_SUB16mi8:
			case X86_SUB16mr:
			case X86_SUB32mi:
			case X86_SUB32mi8:
			case X86_SUB32mr:
			case X86_SUB64mi32:
			case X86_SUB64mi8:
			case X86_SUB64mr:
			case X86_SUB8mi:
			case X86_SUB8mr:

			// XADD
			case X86_XADD16rm:
			case X86_XADD32rm:
			case X86_XADD64rm:
			case X86_XADD8rm:

			// XCHG
			case X86_XCHG16rm:
			case X86_XCHG32rm:
			case X86_XCHG64rm:
			case X86_XCHG8rm:

			// XOR
			case X86_XOR16mi:
			case X86_XOR16mi8:
			case X86_XOR16mr:
			case X86_XOR32mi:
			case X86_XOR32mi8:
			case X86_XOR32mr:
			case X86_XOR64mi32:
			case X86_XOR64mi8:
			case X86_XOR64mr:
			case X86_XOR8mi:
			case X86_XOR8mr:

				// this instruction can be used with LOCK prefix
				return false;
		}
	}

	// REPNE prefix
	if (insn->isPrefixf2) {
		// 0xf2 can be a part of instruction encoding, but not really a prefix.
		// In such a case, clear it.
		if (insn->twoByteEscape == 0x0f) {
			insn->prefix0 = 0;
		}
	}

	// no invalid prefixes
	return false;
}

/*
 * decodeInstruction - Reads and interprets a full instruction provided by the
 *   user.
 *
 * @param insn      - A pointer to the instruction to be populated.  Must be
 *                    pre-allocated.
 * @param reader    - The function to be used to read the instruction's bytes.
 * @param readerArg - A generic argument to be passed to the reader to store
 *                    any internal state.
 * @param startLoc  - The address (in the reader's address space) of the first
 *                    byte in the instruction.
 * @param mode      - The mode (real mode, IA-32e, or IA-32e in 64-bit mode) to
 *                    decode the instruction in.
 * @return          - 0 if instruction is valid; nonzero if not.
 */
int decodeInstruction(struct InternalInstruction *insn,
		byteReader_t reader,
		const void *readerArg,
		uint64_t startLoc,
		DisassemblerMode mode)
{
	insn->reader = reader;
	insn->readerArg = readerArg;
	insn->startLocation = startLoc;
	insn->readerCursor = startLoc;
	insn->mode = mode;

	if (readPrefixes(insn)       ||
			readOpcode(insn)         ||
			getID(insn)      ||
			insn->instructionID == 0 ||
			checkPrefix(insn) ||
			readOperands(insn))
		return -1;

	insn->length = (size_t)(insn->readerCursor - insn->startLocation);

	// instruction length must be <= 15 to be valid
	if (insn->length > 15)
		return -1;

	if (insn->operandSize == 0)
		insn->operandSize = insn->registerSize;

	insn->operands = &x86OperandSets[insn->spec->operands][0];

	// dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %zu",
	// 		startLoc, insn->readerCursor, insn->length);

	//if (insn->length > 15)
	//	dbgprintf(insn, "Instruction exceeds 15-byte limit");

#if 0
	printf("\n>>> x86OperandSets = %lu\n", sizeof(x86OperandSets));
	printf(">>> x86DisassemblerInstrSpecifiers = %lu\n", sizeof(x86DisassemblerInstrSpecifiers));
	printf(">>> x86DisassemblerContexts = %lu\n", sizeof(x86DisassemblerContexts));
	printf(">>> modRMTable = %lu\n", sizeof(modRMTable));
	printf(">>> x86DisassemblerOneByteOpcodes = %lu\n", sizeof(x86DisassemblerOneByteOpcodes));
	printf(">>> x86DisassemblerTwoByteOpcodes = %lu\n", sizeof(x86DisassemblerTwoByteOpcodes));
	printf(">>> x86DisassemblerThreeByte38Opcodes = %lu\n", sizeof(x86DisassemblerThreeByte38Opcodes));
	printf(">>> x86DisassemblerThreeByte3AOpcodes = %lu\n", sizeof(x86DisassemblerThreeByte3AOpcodes));
	printf(">>> x86DisassemblerThreeByteA6Opcodes = %lu\n", sizeof(x86DisassemblerThreeByteA6Opcodes));
	printf(">>> x86DisassemblerThreeByteA7Opcodes= %lu\n", sizeof(x86DisassemblerThreeByteA7Opcodes));
	printf(">>> x86DisassemblerXOP8Opcodes = %lu\n", sizeof(x86DisassemblerXOP8Opcodes));
	printf(">>> x86DisassemblerXOP9Opcodes = %lu\n", sizeof(x86DisassemblerXOP9Opcodes));
	printf(">>> x86DisassemblerXOPAOpcodes = %lu\n\n", sizeof(x86DisassemblerXOPAOpcodes));
#endif

	return 0;
}

#endif
