/*
instructions.c

diStorm3 - Powerful disassembler for X86/AMD64
http://ragestorm.net/distorm/
distorm at gmail dot com
Copyright (C) 2003-2021 Gil Dabah
This library is licensed under the BSD license. See the file COPYING.
*/


#include "instructions.h"

#include "insts.h"
#include "prefix.h"
#include "x86defs.h"
#include "../include/mnemonics.h"


/* Helper macros to extract the type or index from an inst-node value. */
#define INST_NODE_INDEX(n) ((n) & 0x1fff)
#define INST_NODE_TYPE(n) ((n) >> 13)

/* Helper macro to read the actual flags that are associated with an inst-info. */
#define INST_INFO_FLAGS(ii) (FlagsTable[InstSharedInfoTable[(ii)->sharedIndex].flagsIndex])

/*
I use the trie data structure as I found it most fitting to a disassembler mechanism.
When you read a byte and have to decide if it's enough or you should read more bytes, 'till you get to the instruction information.
It's really fast because you POP the instruction info in top 3 iterates on the DB, because an instruction can be formed from two bytes + 3 bits reg from the ModR/M byte.
For a simple explanation, check this out:
http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Trie/
Further reading: http://en.wikipedia.org/wiki/Trie

The first GATE (array you read off a trie data structure), as I call them, is statically allocated by the compiler.
The second and third gates if used are being allocated dynamically by the instructions-insertion functionality.

How would such a thing look in memory, say we support 4 instructions with 3 bytes top (means 2 dynamically allocated gates).

->
|-------|                                0,
|0|     -------------------------------> |-------|
|1|RET  |      1,                        |0|AND  |
|2|     -----> |-------|                 |1|XOR  |
|3|INT3 |      |0|PUSH |                 |2|OR   |         0,3,
|-------|      |1|POP  |                 |3|     --------->|-------|
               |2|PUSHF|                 |-------|         |0|ROR  |
               |3|POPF |                                   |1|ROL  |
               |-------|                                   |2|SHR  |
                                                           |3|SHL  |
                                                           |-------|

Of course, this is NOT how Intel instructions set looks!!!
but I just wanted to give a small demonstration.
Now the instructions you get from such a trie DB goes like this:

0, 0 - AND
0, 1 - XOR
0, 2 - OR
0, 3, 0, ROR
0, 3, 1, ROL
0, 3, 2, SHR
0, 3, 3, SHL
1 - RET
2, 0 - PUSH
2, 1 - POP
2, 2 - PUSHF
2, 3 - POPF
3 - INT3

I guess it's clear by now.
So now, if you read 0, you know that you have to enter the second gate(list) with the second byte specifying the index.
But if you read 1, you know that you go to an instruction (in this case, a RET).
That's why there's an Instruction-Node structure, it tells you whether you got to an instruction or another list
so you should keep on reading byte).

In Intel, you could go through 4 gates at top, because there are instructions which are built from 2 bytes and another smaller list
for the REG part, or newest SSE4 instructions which use 4 bytes for opcode.
Therefore, Intel's first gate is 256 long, and other gates are 256 (/72) or 8 long, yes, it costs pretty much a lot of memory
for non-used defined instructions, but I think that it still rocks.
*/

/*
 * A helper function to look up the correct inst-info structure.
 * It does one fetch from the index-table, and then another to get the inst-info.
 * Note that it takes care about basic inst-info or inst-info-ex.
 * The caller should worry about boundary checks and whether it accesses a last-level table.
 */
static _InstInfo* inst_get_info(_InstNode in, int index)
{
	int instIndex = 0;

	in = InstructionsTree[INST_NODE_INDEX(in) + index];
	if (in == INT_NOTEXISTS) return NULL;

	instIndex = INST_NODE_INDEX(in);
	return INST_NODE_TYPE(in) == INT_INFO ? &InstInfos[instIndex] : (_InstInfo*)&InstInfosEx[instIndex];
}

/*
 * This function is responsible to return the instruction information of the first found in code.
 * It returns the _InstInfo of the found instruction, otherwise NULL.
 * code should point to the ModR/M byte upon exit (if used), or after the instruction binary code itself.
 * This function is NOT decoding-type dependant, it is up to the caller to see whether the instruction is valid.
 * Get the instruction info, using a Trie data structure.
 *
 * Sometimes normal prefixes become mandatory prefixes, which means they are now part of the instruction opcode bytes.

 * This is a bit tricky now,
 * if the first byte is a REP (F3) prefix, we will have to give a chance to an SSE instruction.
 * If an instruction doesn't exist, we will make it as a prefix and re-locateinst.
 * A case such that a REP prefix is being changed into an instruction byte and also an SSE instruction will not be found can't happen,
 * simply because there are no collisions between string instruction and SSE instructions (they are escaped).

 * As for S/SSE2/3, check for F2 and 66 as well.

 * In 64 bits, we have to make sure that we will skip the REX prefix, if it exists.
 * There's a specific case, where a 66 is mandatory but it was dropped because REG.W was used,
 * but it doesn't behave as an operand size prefix but as a mandatory, so we will have to take it into account.

 * For example (64 bits decoding mode):
 * 66 98 CBW
 * 48 98 CDQE
 * 66 48 98: db 0x66; CDQE
 * Shows that operand size is dropped.

 * Now, it's a mandatory prefix and NOT an operand size one.
 * 66480f2dc0 db 0x48; CVTPD2PI XMM0, XMM0
 * Although this instruction doesn't require a REX.W, it just shows, that even if it did - it doesn't matter.
 * REX.W is dropped because it's not required, but the decode function disabled the operand size even so.
 */
static _InstInfo* inst_lookup_prefixed(_InstNode in, _PrefixState* ps)
{
	int checkOpSize = FALSE;
	int index = 0;
	_InstInfo* ii = NULL;

	/* Check prefixes of current decoded instruction (None, 0x66, 0xf3, 0xf2). */
	switch (ps->decodedPrefixes & (INST_PRE_OP_SIZE | INST_PRE_REPS))
	{
		case 0:
			/* Non-prefixed, index = 0. */
			index = 0;
		break;
		case INST_PRE_OP_SIZE:
			/* 0x66, index = 1. */
			index = 1;
			/* Mark that we used it as a mandatory prefix. */
			ps->isOpSizeMandatory = TRUE;
			ps->decodedPrefixes &= ~INST_PRE_OP_SIZE;
		break;
		case INST_PRE_REP:
			/* 0xf3, index = 2. */
			index = 2;
			ps->decodedPrefixes &= ~INST_PRE_REP;
		break;
		case INST_PRE_REPNZ:
			/* 0xf2, index = 3. */
			index = 3;
			ps->decodedPrefixes &= ~INST_PRE_REPNZ;
		break;
		default:
			/*
			 * Now we got a problem, since there are a few mandatory prefixes at once.
			 * There is only one case when it's ok, when the operand size prefix is for real (not mandatory).
			 * Otherwise we will have to return NULL, since the instruction is illegal.
			 * Therefore we will start with REPNZ and REP prefixes,
			 * try to get the instruction and only then check for the operand size prefix.
			 */

			 /* If both REPNZ and REP are together, it's illegal for sure. */
			if ((ps->decodedPrefixes & INST_PRE_REPS) == INST_PRE_REPS) return NULL;

			/* Now we know it's either REPNZ+OPSIZE or REP+OPSIZE, so examine the instruction. */
			if (ps->decodedPrefixes & INST_PRE_REPNZ) {
				index = 3;
				ps->decodedPrefixes &= ~INST_PRE_REPNZ;
			}
			else if (ps->decodedPrefixes & INST_PRE_REP) {
				index = 2;
				ps->decodedPrefixes &= ~INST_PRE_REP;
			}
			/* Mark to verify the operand-size prefix of the fetched instruction below. */
			checkOpSize = TRUE;
		break;
	}

	/* Fetch the inst-info from the index. */
	ii = inst_get_info(in, index);

	if (checkOpSize) {
		/* If the instruction doesn't support operand size prefix, then it's illegal. */
		if ((ii == NULL) || (~INST_INFO_FLAGS(ii) & INST_PRE_OP_SIZE)) return NULL;
	}

	/* If there was a prefix, but the instruction wasn't found. Try to fall back to use the normal instruction. */
	if (ii == NULL) ii = inst_get_info(in, 0);
	return ii;
}

/* A helper function to look up special VEX instructions.
 * See if it's a MOD based instruction and fix index if required.
 * Only after a first lookup (that was done by caller), we can tell if we need to fix the index.
 * Because these are coupled instructions
 * (which means that the base instruction hints about the other instruction).
 * Note that caller should check if it's a MOD dependent instruction before getting in here.
 */
static _InstInfo* inst_vex_mod_lookup(_CodeInfo* ci, _InstNode in, _InstInfo* ii, unsigned int index)
{
	/* Advance to read the MOD from ModRM byte. */
	ci->code += 1;
	ci->codeLen -= 1;
	if (ci->codeLen < 0) return NULL;
	if (*ci->code < INST_DIVIDED_MODRM) {
		/* MOD is not 11, therefore change the index to 8 - 12 range in the prefixed table. */
		index += 4;
		/* Make a second lookup for this special instruction. */
		return inst_get_info(in, index);
	}
	/* Return the original one, in case we didn't find a suited instruction. */
	return ii;
}

static _InstInfo* inst_vex_lookup(_CodeInfo* ci, _PrefixState* ps)
{
	_InstNode in = 0;
	unsigned int pp = 0, start = 0;
	unsigned int index = 4; /* VEX instructions start at index 4 in the Prefixed table. */
	uint8_t vex = *ps->vexPos, vex2 = 0, v = 0;
	int instType = 0, instIndex = 0;

	/* The VEX instruction will #ud if any of 66, f0, f2, f3, REX prefixes precede. */
	_iflags illegal = (INST_PRE_OP_SIZE | INST_PRE_LOCK | INST_PRE_REP | INST_PRE_REPNZ | INST_PRE_REX);
	if ((ps->decodedPrefixes & illegal) != 0) return NULL;

	/* Read the some fields from the VEX prefix we need to extract the instruction. */
	if (ps->prefixExtType == PET_VEX2BYTES) {
		ps->vexV = v = (~vex >> 3) & 0xf;
		pp = vex & 3;
		/* Implied leading 0x0f byte by default for 2 bytes VEX prefix. */
		start = 1;
	}
	else { /* PET_VEX3BYTES */
		start = vex & 0x1f;
		vex2 = *(ps->vexPos + 1);
		ps->vexV = v = (~vex2 >> 3) & 0xf;
		pp = vex2 & 3;
	}

	/* start can be either 1 (0x0f), 2 (0x0f, 0x038) or 3 (0x0f, 0x3a), otherwise it's illegal. */
	switch (start)
	{
		case 1: in = Table_0F; break;
		case 2: in = Table_0F_38; break;
		case 3: in = Table_0F_3A; break;
		default: return NULL;
	}

	/* pp is actually the implied mandatory prefix, apply it to the index. */
	index += pp; /* (None, 0x66, 0xf3, 0xf2) */

	/* Read a byte from the stream. */
	ci->codeLen -= 1;
	if (ci->codeLen < 0) return NULL;

	in = InstructionsTree[INST_NODE_INDEX(in) + *ci->code];
	if (in == INT_NOTEXISTS) return NULL;

	instType = INST_NODE_TYPE(in);
	instIndex = INST_NODE_INDEX(in);

	/*
	 * If we started with 0f38 or 0f3a so it's a prefixed table,
	 * therefore it's surely a VEXed instruction (because of a high index).
	 * However, starting with 0f, could also lead immediately to a prefixed table for some bytes.
	 * it might return NULL, if the index is invalid.
	 */
	if (instType == INT_LIST_PREFIXED) {
		_InstInfo* ii = inst_get_info(in, index);
		/* See if the instruction is dependent on MOD. */
		if ((ii != NULL) && (((_InstInfoEx*)ii)->flagsEx & INST_MODRR_BASED)) {
			ii = inst_vex_mod_lookup(ci, in, ii, index);
		}
		return ii;
	}

	/*
	 * If we reached here, obviously we started with 0f. VEXed instructions must be nodes of a prefixed table.
	 * But since we found an instruction (or divided one), just return NULL.
	 * They cannot lead to a VEXed instruction.
	 */
	if ((instType == INT_INFO) || (instType == INT_INFOEX) || (instType == INT_LIST_DIVIDED)) return NULL;

	/* Now we are left with handling either GROUP or FULL tables, therefore we will read another byte from the stream. */
	ci->code += 1;
	ci->codeLen -= 1;
	if (ci->codeLen < 0) return NULL;

	if (instType == INT_LIST_GROUP) {
		in = InstructionsTree[instIndex + ((*ci->code >> 3) & 7)];
		/* Continue below to check prefixed table. */
	}
	else if (instType == INT_LIST_FULL) {
		in = InstructionsTree[instIndex + *ci->code];
		/* Continue below to check prefixed table. */
	}

	/* Now that we got to the last table in the trie, check for a prefixed table. */
	if (INST_NODE_TYPE(in) == INT_LIST_PREFIXED) {
		_InstInfo* ii = inst_get_info(in, index);
		/* See if the instruction is dependent on MOD. */
		if ((ii != NULL) && (((_InstInfoEx*)ii)->flagsEx & INST_MODRR_BASED)) {
			ii = inst_vex_mod_lookup(ci, in, ii, index);
		}
		return ii;
	}

	/* No VEXed instruction was found. */
	return NULL;
}

_InstInfo* inst_lookup(_CodeInfo* ci, _PrefixState* ps, int* isPrefixed)
{
	unsigned int tmpIndex0, tmpIndex1, tmpIndex2;
	int instType;
	_InstNode in;
	_InstInfo* ii = NULL;
	int isWaitIncluded = FALSE;

	/* Always safe to read first byte codeLen > 0. */
	tmpIndex0 = *ci->code;

	if (prefixes_is_valid((unsigned char)tmpIndex0, ci->dt)) {
		*isPrefixed = TRUE;
		prefixes_decode(ci, ps);
		if (ci->codeLen < 1) return NULL; /* No more bytes for opcode, halt. */
		tmpIndex0 = *ci->code; /* Reload. */

		/* If there are too many prefixes, it will be checked later in decode_inst. */

		/* See whether we have to handle a VEX prefixed instruction. */
		if (ps->decodedPrefixes & INST_PRE_VEX) {
			ii = inst_vex_lookup(ci, ps);
			if (ii != NULL) {
				/* Make sure that VEX.L exists when forced. */
				if ((((_InstInfoEx*)ii)->flagsEx & INST_FORCE_VEXL) && (~ps->vrex & PREFIX_EX_L)) return NULL;
				/* If the instruction doesn't use VEX.vvvv it must be zero. */
				if ((((_InstInfoEx*)ii)->flagsEx & INST_VEX_V_UNUSED) && ps->vexV) return NULL;
			}
			return ii;
		}
	}

	/* Account first byte, we know it's safe to read. */
	ci->codeLen -= 1;

	/* Check for special 0x9b, WAIT instruction, which can be part of some instructions(x87). */
	if (tmpIndex0 == INST_WAIT_INDEX) {
		/* Only OCST_1dBYTES get a chance to include this byte as part of the opcode. */
		isWaitIncluded = TRUE;

		/* Ignore all prefixes, since they are useless and operate on the WAIT instruction itself. */
		prefixes_ignore_all(ps);

		/* Move to next code byte as a new whole instruction. */
		ci->code += 1;
		ci->codeLen -= 1;
		if (ci->codeLen < 0) return NULL; /* Faster to return NULL, it will be detected as WAIT later anyway. */
		/* Since we got a WAIT prefix, we re-read the first byte. */
		tmpIndex0 = *ci->code;
	}

	/* Walk first byte in InstructionsTree root. */
	in = InstructionsTree[tmpIndex0];
	if ((uint32_t)in == INT_NOTEXISTS) return NULL;
	instType = INST_NODE_TYPE(in);

	/* Single byte instruction (OCST_1BYTE). */
	if ((instType < INT_INFOS) && (!isWaitIncluded)) {
		/* Some single byte instructions need extra treatment. */
		if (instType == INT_INFO_TREAT) {
			if (tmpIndex0 == INST_NOP_INDEX) { /* Nopnopnop */
				/* Check for Pause, since it's prefixed with 0xf3, which is not a real mandatory prefix. */
				if (ps->decodedPrefixes & INST_PRE_REP) {
					/* Flag this prefix as used. */
					ps->usedPrefixes |= INST_PRE_REP;
					return &II_PAUSE;
				}

				/*
				 * Treat NOP/XCHG specially.
				 * If we're not in 64bits restore XCHG to NOP, since in the DB it's XCHG.
				 * Else if we're in 64bits examine REX, if exists, and decide which instruction should go to output.
				 * 48 90 XCHG RAX, RAX is a true NOP (eat REX in this case because it's valid).
				 * 90 XCHG EAX, EAX is a true NOP (and not high dword of RAX = 0 although it should be a 32 bits operation).
				 * Note that if the REX.B is used, then the register is not RAX anymore but R8, which means it's not a NOP.
				 */
				if (ps->vrex & PREFIX_EX_W) ps->usedPrefixes |= INST_PRE_REX;
				if ((ci->dt != Decode64Bits) || (~ps->vrex & PREFIX_EX_B)) return &II_NOP;
			}
			else if (tmpIndex0 == INST_LEA_INDEX) {
				/* Ignore segment override prefixes for LEA instruction. */
				ps->decodedPrefixes &= ~INST_PRE_SEGOVRD_MASK;
				/* Update unused mask for ignoring segment prefix. */
				prefixes_ignore(ps, PFXIDX_SEG);
			}
			else if (tmpIndex0 == INST_ARPL_INDEX) {
					/*
					 * ARPL/MOVSXD share the same opcode, and both have different operands and mnemonics, of course.
					 * Practically, I couldn't come up with a comfortable way to merge the operands' types of ARPL/MOVSXD.
					 * And since the DB can't be patched dynamically, because the DB has to be multi-threaded compliant,
					 * I have no choice but to check for ARPL/MOVSXD right here - "right about now, the funk soul brother, check it out now, the funk soul brother...", fatboy slim
					 */
					if (ci->dt == Decode64Bits) {
						return &II_MOVSXD;
					} /* else ARPL will be returned because its defined in the DB already. */
			}
		}
		/*
		 * Return the 1 byte instruction we found.
		 * We can have three node types here: infoex, info_treat and info.
		 * The latter two are really the same basic structure.
		 */
		return instType == INT_INFOEX ? (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)] : &InstInfos[INST_NODE_INDEX(in)];
	}

	/* Read second byte, still doesn't mean all of its bits are used (I.E: ModRM). */
	ci->code += 1;
	ci->codeLen -= 1;
	if (ci->codeLen < 0) return NULL;
	tmpIndex1 = *ci->code;

	/* Try single byte instruction + reg bits (OCST_13BYTES). */
	if ((instType == INT_LIST_GROUP) && (!isWaitIncluded)) return inst_get_info(in, (tmpIndex1 >> 3) & 7);

	/* Try single byte instruction + reg byte OR one whole byte (OCST_1dBYTES). */
	if (instType == INT_LIST_DIVIDED) {

		/* Checking for inst by REG bits is higher priority if it's found not to be divided instruction. */
		{
			_InstNode in2 = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex1 >> 3) & 7)];
			/*
			 * Do NOT check for NULL here, since we do a bit of a guess work,
			 * hence we don't override 'in', cause we might still need it.
			 */
			instType = INST_NODE_TYPE(in2);

			if (instType == INT_INFO) ii = &InstInfos[INST_NODE_INDEX(in2)];
			else if (instType == INT_INFOEX) ii = (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in2)];
			if ((ii != NULL) && (INST_INFO_FLAGS(ii) & INST_NOT_DIVIDED)) return ii;
			/* ii is reset below. */
		}

		/* Continue normally because of wait prefix. */
		if (tmpIndex1 < INST_DIVIDED_MODRM) {
			/* An instruction which requires a ModR/M byte. Thus it's 1.3 bytes long instruction. */
			tmpIndex1 = (tmpIndex1 >> 3) & 7; /* Isolate the 3 REG/OPCODE bits. */
		}
		else { /* Normal 2 bytes instruction. */
		 /*
		  * Divided instructions can't be in the range of 0x8-0xc0.
		  * That's because 0-8 are used for 3 bits group.
		  * And 0xc0-0xff are used for not-divided instruction.
		  * So the in between range is omitted, thus saving some more place in the tables.
		  */
			tmpIndex1 -= INST_DIVIDED_MODRM - 8;
		}

		in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex1];
		if (in == INT_NOTEXISTS) return NULL;
		instType = INST_NODE_TYPE(in);

		if (instType < INT_INFOS) {
			/* If the instruction doesn't support the wait (marked as opsize) as part of the opcode, it's illegal. */
			ii = instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
			if ((~INST_INFO_FLAGS(ii) & INST_PRE_OP_SIZE) && (isWaitIncluded)) return NULL;
			return ii;
		}
		/*
		 * If we got here the instruction can support the wait prefix, so see if it was part of the stream.
		 * Examine prefixed table, specially used for 0x9b, since it's optional.
		 * No Wait: index = 0.
		 * Wait Exists, index = 1.
		 */
		return inst_get_info(in, isWaitIncluded);
	}

	/* Don't allow to continue if WAIT is part of the opcode, because there are no instructions that include it. */
	if (isWaitIncluded) return NULL;

	/* Try 2 bytes long instruction (doesn't include ModRM byte). */
	if (instType == INT_LIST_FULL) {
		in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex1];
		if (in == INT_NOTEXISTS) return NULL;
		instType = INST_NODE_TYPE(in);

		/* This is where we check if we just read two escape bytes in a row, which means it is a 3DNow! instruction. */
		if ((tmpIndex0 == _3DNOW_ESCAPE_BYTE) && (tmpIndex1 == _3DNOW_ESCAPE_BYTE)) return &II_3DNOW;

		/* 2 bytes instruction (OCST_2BYTES). */
		if (instType < INT_INFOS)
			return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];

		/*
		 * 2 bytes + mandatory prefix.
		 * Mandatory prefixes can be anywhere in the prefixes.
		 * There cannot be more than one mandatory prefix, unless it's a normal operand size prefix.
		 */
		if (instType == INT_LIST_PREFIXED) return inst_lookup_prefixed(in, ps);
	}

	/* Read third byte, still doesn't mean all of its bits are used (I.E: ModRM). */
	ci->code += 1;
	ci->codeLen -= 1;
	if (ci->codeLen < 0) return NULL;
	tmpIndex2 = *ci->code;

	/* Try 2 bytes + reg instruction (OCST_23BYTES). */
	if (instType == INT_LIST_GROUP) {
		in = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex2 >> 3) & 7)];
		if (in == INT_NOTEXISTS) return NULL;
		instType = INST_NODE_TYPE(in);

		if (instType < INT_INFOS)
			return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];

		/* It has to be a prefixed table then. */
		ii = inst_lookup_prefixed(in, ps);
		/* RDRAND and VMPTRLD share same 2.3 bytes opcode, and alternate on the MOD bits. See insts.h for more info. */
		if ((ii != NULL) && (ii->opcodeId == I_VMPTRLD) && (tmpIndex1 >= INST_DIVIDED_MODRM)) return &II_RDRAND;
		return ii;
	}

	/* Try 2 bytes + divided range (OCST_2dBYTES). */
	if (instType == INT_LIST_DIVIDED) {
		_InstNode in2 = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex2 >> 3) & 7)];
		/*
		 * Do NOT check for NULL here, since we do a bit of a guess work,
		 * hence we don't override 'in', cause we might still need it.
		 */
		instType = INST_NODE_TYPE(in2);

		if (instType == INT_INFO) ii = &InstInfos[INST_NODE_INDEX(in2)];
		else if (instType == INT_INFOEX) ii = (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in2)];

		/*
		 * OCST_2dBYTES is complex, because there are a few instructions which are not divided in some special cases.
		 * If the instruction wasn't divided (but still it must be a 2.3 because we are in divided category)
		 * or it was an official 2.3 (because its index was less than 0xc0) -
		 * Then it means the instruction should be using the REG bits, otherwise give a chance to range 0xc0-0xff.
		 */
		 /* If we found an instruction only by its REG bits, AND it is not divided, then return it. */
		if ((ii != NULL) && (INST_INFO_FLAGS(ii) & INST_NOT_DIVIDED)) return ii;
		/* Otherwise, if the range is above 0xc0, try the special divided range (range 0x8-0xc0 is omitted). */
		if (tmpIndex2 >= INST_DIVIDED_MODRM) return inst_get_info(in, tmpIndex2 - INST_DIVIDED_MODRM + 8);

		/* It might be that we got here without touching ii in the above if statements, then it becomes an invalid instruction prolly. */
		return ii;
	}

	/* Try 3 full bytes (OCST_3BYTES - no ModRM byte). */
	if (instType == INT_LIST_FULL) {
		/* OCST_3BYTES. */
		in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex2];
		if (in == INT_NOTEXISTS) return NULL;
		instType = INST_NODE_TYPE(in);

		if (instType < INT_INFOS)
			return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];

		if (instType == INT_LIST_PREFIXED) return inst_lookup_prefixed(in, ps);
	}

	/* Kahtchinggg, damn. */
	return NULL;
}

/*
* 3DNow! instruction handling:

* This is used when we encounter a 3DNow! instruction.
* We can't really locate a 3DNow! instruction before we see two escaped bytes,
* 0x0f, 0x0f. Then we have to extract operands which are, dest=mmx register, src=mmx register or quadword indirection.
* When we are finished with the extraction of operands we can resume to locate the instruction by reading another byte
* which tells us which 3DNow instruction we really tracked down...
* So in order to tell the extract operands function which operands the 3DNow! instruction require, we need to set up some
* generic instruction info for 3DNow! instructions.

* In the inst_lookup itself, when we read an OCST_3BYTES which the two first bytes are 0x0f and 0x0f.
* we will return this special generic II for the specific operands we are interested in (MM, MM64).
* Then after extracting the operand, we'll call a completion routine for locating the instruction
* which will be called only for 3DNow! instructions, distinguished by a flag, and it will read the last byte of the 3 bytes.
*
* The id of this opcode should not be used, the following function should change it anyway.
*/
_InstInfo* inst_lookup_3dnow(_CodeInfo* ci)
{
	/* Start off from the two escape bytes gates... which is 3DNow! table.*/
	_InstNode in = Table_0F_0F;

	int index;

	/* Make sure we can read a byte off the stream. */
	if (ci->codeLen < 1) return NULL;

	index = *ci->code;

	ci->codeLen -= 1;
	ci->code += 1;
	return inst_get_info(in, index);
}
